Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // By Christian Jakobsen
- // Ported by Ethatron
- // ---------------------------------------
- // TWEAKABLE VARIABLES.
- #undef TEST_MODE
- // testMode. set to 1, you can see the raw ssao
- float distance = 0.0025;
- static const float nearZ = 1.0;
- static const float farZ = 1000.0;
- // END OF TWEAKABLE VARIABLES.
- // ---------------------------------------
- // shader codes begin here
- texture2D frameTex2D;
- sampler frameSampler = sampler_state
- {
- texture = <frameTex2D>;
- MinFilter = LINEAR;
- MagFilter = LINEAR;
- MipFilter = LINEAR;
- AddressU = Clamp;
- AddressV = Clamp;
- SRGBTexture=FALSE;
- };
- texture2D depthTex2D;
- sampler depthSampler = sampler_state
- {
- texture = <depthTex2D>;
- MinFilter = POINT;
- MagFilter = POINT;
- MipFilter = NONE;
- AddressU = Clamp;
- AddressV = Clamp;
- SRGBTexture=FALSE;
- };
- texture2D cust_NoiseTexture < string filename = "RandomNoiseB.dds"; >;
- sampler2D NoiseSampler = sampler_state {
- texture = <cust_NoiseTexture>;
- AddressU = WRAP;
- AddressV = WRAP;
- MINFILTER = LINEAR;
- MAGFILTER = LINEAR;
- MIPFILTER = LINEAR;
- };
- struct VSIN
- {
- float4 vertPos : POSITION0;
- float2 UVCoord : TEXCOORD0;
- };
- struct VSOUT
- {
- float4 vertPos : POSITION;
- float2 UVCoord : TEXCOORD0;
- };
- VSOUT FrameVS(VSIN IN) {
- VSOUT OUT = (VSOUT)0.0f; // initialize to zero, avoid complaints.
- OUT.vertPos = IN.vertPos;
- OUT.UVCoord = IN.UVCoord;
- return OUT;
- }
- float rand_1_05(in float2 uv)
- {
- float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
- return abs(noise.x + noise.y) * 0.5;
- }
- float readDepth(in float2 coord : TEXCOORD0)
- {
- float posZ = tex2D(depthSampler, coord);
- posZ = (2.0f * nearZ) / ((farZ + nearZ) - posZ * (farZ - nearZ));
- //posZ = (nearZ * farZ) / (farZ - posZ * (farZ - nearZ));
- return posZ;
- }
- float4 ssao_Main(VSOUT IN) : COLOR0 {
- //Tile the texture coordinates
- float2 rotationTC = IN.UVCoord * rand_1_05(IN.UVCoord) / 4.0f;
- //Sample a random vector and transform it into [-1, 1] range
- float3 vRotation = 2.0f * tex2D(NoiseSampler, rotationTC).rgb - 1.0f;
- //Create rotation matrix
- float3x3 matRotate;
- float offsetScale = distance;
- float h = 1.0f / (1.0f + vRotation.z);
- matRotate._m00 = h * vRotation.y * vRotation.y + vRotation.z;
- matRotate._m01 = -h * vRotation.y * vRotation.x;
- matRotate._m02 = -vRotation.x;
- matRotate._m10 = -h * vRotation.y * vRotation.x;
- matRotate._m11 = h * vRotation.x * vRotation.x + vRotation.z;
- matRotate._m12 = -vRotation.y;
- matRotate._m20 = vRotation.x;
- matRotate._m21 = vRotation.y;
- matRotate._m22 = vRotation.z;
- //Specify number of samples
- const int nSamplesNum = 24;
- //Sample the depth at the current pixel
- float fSceneDepthP = readDepth(IN.UVCoord);
- //Set the offset scale step
- float fOffsetScaleStep = 1.0f + 2.4f / nSamplesNum;
- //Initialize the accessibility factor to zero
- float fAccessibility = 0;
- //Sample area around current pixel and accumulate the accessibility factor
- [loop]
- for (int i = 0 ; i < (nSamplesNum / 8) ; i++)
- for (int x = -1 ; x <= 1 ; x += 2)
- for (int y = -1 ; y <= 1 ; y += 2)
- for (int z = -1 ; z <= 1 ; z += 2) {
- //Create offset vector
- float3 vOffset = normalize(float3(x, y, z)) * (offsetScale *= fOffsetScaleStep);
- //Rotate the offset vector
- float3 vRotatedOffset = mul(vOffset, matRotate);
- //Center pixel's coordinates in screen space
- float3 vSamplePos = float3(IN.UVCoord, fSceneDepthP);
- //Offset sample point
- vSamplePos += float3(vRotatedOffset.xy, vRotatedOffset.z * fSceneDepthP);
- //Read sample point depth
- float fSceneDepthS = readDepth(vSamplePos.xy);
- //Discard if depth equals max
- if (fSceneDepthS >= 1.0f)
- fAccessibility += 1.0f;
- else {
- //Compute accessibility factor
- float fRangeIsInvalid = saturate(fSceneDepthP - fSceneDepthS);
- fAccessibility += lerp(fSceneDepthS > vSamplePos.z, 0.5f, fRangeIsInvalid);
- }
- }
- //Compute average accessibility
- fAccessibility = fAccessibility / nSamplesNum;
- //Amplify and return the ambient occlusion coefficient
- float3 ao = saturate(fAccessibility * fAccessibility + fAccessibility);
- return float4(ao, 1.0);
- //return tex2D(frameSampler, IN.UVCoord);
- //return tex2D(depthSampler, IN.UVCoord);
- }
- technique t0
- {
- pass p0
- {
- VertexShader = compile vs_3_0 FrameVS();
- PixelShader = compile ps_3_0 ssao_Main();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement