Advertisement
Guest User

CrysisAO

a guest
Aug 22nd, 2014
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.37 KB | None | 0 0
  1. // By Christian Jakobsen
  2. // Ported by Ethatron
  3.  
  4. // ---------------------------------------
  5. // TWEAKABLE VARIABLES.
  6.  
  7.  
  8. #undef  TEST_MODE
  9. // testMode. set to 1, you can see the raw ssao
  10.  
  11. float distance = 0.0025;
  12.  
  13. static const float nearZ = 1.0;
  14. static const float farZ = 1000.0;
  15.  
  16. // END OF TWEAKABLE VARIABLES.
  17. // ---------------------------------------
  18.  
  19. // shader codes begin here
  20. texture2D frameTex2D;
  21. sampler frameSampler = sampler_state
  22. {
  23.     texture = <frameTex2D>;
  24.     MinFilter = LINEAR;
  25.     MagFilter = LINEAR;
  26.     MipFilter = LINEAR;
  27.     AddressU  = Clamp;
  28.     AddressV  = Clamp;
  29.     SRGBTexture=FALSE;
  30. };
  31.  
  32. texture2D depthTex2D;
  33. sampler depthSampler = sampler_state
  34. {
  35.     texture = <depthTex2D>;
  36.     MinFilter = POINT;
  37.     MagFilter = POINT;
  38.     MipFilter = NONE;
  39.     AddressU  = Clamp;
  40.     AddressV  = Clamp;
  41.     SRGBTexture=FALSE;
  42. };
  43.  
  44. texture2D cust_NoiseTexture < string filename = "RandomNoiseB.dds"; >;
  45. sampler2D NoiseSampler = sampler_state {
  46.     texture = <cust_NoiseTexture>;
  47.  
  48.     AddressU = WRAP;
  49.     AddressV = WRAP;
  50.  
  51.     MINFILTER = LINEAR;
  52.     MAGFILTER = LINEAR;
  53.     MIPFILTER = LINEAR;
  54. };
  55.  
  56. struct VSIN
  57. {
  58.     float4 vertPos : POSITION0;
  59.     float2 UVCoord : TEXCOORD0;
  60. };
  61.  
  62. struct VSOUT
  63. {
  64.     float4 vertPos : POSITION;
  65.     float2 UVCoord : TEXCOORD0;
  66. };
  67.  
  68. VSOUT FrameVS(VSIN IN) {
  69.     VSOUT OUT = (VSOUT)0.0f;    // initialize to zero, avoid complaints.
  70.  
  71.     OUT.vertPos = IN.vertPos;
  72.     OUT.UVCoord = IN.UVCoord;
  73.  
  74.     return OUT;
  75. }
  76.  
  77. float rand_1_05(in float2 uv)
  78. {
  79.     float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
  80.     return abs(noise.x + noise.y) * 0.5;
  81. }
  82.  
  83. float readDepth(in float2 coord : TEXCOORD0)
  84. {
  85.     float posZ = tex2D(depthSampler, coord);
  86.     posZ = (2.0f * nearZ) / ((farZ + nearZ) - posZ * (farZ - nearZ));
  87.     //posZ = (nearZ * farZ) / (farZ - posZ * (farZ - nearZ));
  88.     return posZ;
  89. }
  90.  
  91. float4 ssao_Main(VSOUT IN) : COLOR0 {
  92.  
  93.     //Tile the texture coordinates
  94.     float2 rotationTC = IN.UVCoord * rand_1_05(IN.UVCoord) / 4.0f;
  95.    
  96.     //Sample a random vector and transform it into [-1, 1] range
  97.     float3 vRotation = 2.0f * tex2D(NoiseSampler, rotationTC).rgb - 1.0f;
  98.    
  99.     //Create rotation matrix
  100.     float3x3 matRotate;
  101.     float offsetScale = distance;
  102.  
  103.     float h = 1.0f / (1.0f + vRotation.z);
  104.     matRotate._m00 =  h * vRotation.y * vRotation.y + vRotation.z;
  105.     matRotate._m01 = -h * vRotation.y * vRotation.x;
  106.     matRotate._m02 = -vRotation.x;
  107.     matRotate._m10 = -h * vRotation.y * vRotation.x;
  108.     matRotate._m11 =  h * vRotation.x * vRotation.x + vRotation.z;
  109.     matRotate._m12 = -vRotation.y;
  110.     matRotate._m20 =  vRotation.x;
  111.     matRotate._m21 =  vRotation.y;
  112.     matRotate._m22 =  vRotation.z;
  113.  
  114.     //Specify number of samples
  115.     const int nSamplesNum = 24;
  116.    
  117.     //Sample the depth at the current pixel
  118.     float fSceneDepthP = readDepth(IN.UVCoord);
  119.    
  120.     //Set the offset scale step
  121.     float fOffsetScaleStep = 1.0f + 2.4f / nSamplesNum;
  122.    
  123.     //Initialize the accessibility factor to zero
  124.     float fAccessibility = 0;
  125.  
  126.     //Sample area around current pixel and accumulate the accessibility factor
  127.     [loop] 
  128.     for (int i = 0 ; i < (nSamplesNum / 8) ; i++)
  129.     for (int x = -1 ; x <= 1 ; x += 2)
  130.     for (int y = -1 ; y <= 1 ; y += 2)
  131.     for (int z = -1 ; z <= 1 ; z += 2) {
  132.         //Create offset vector
  133.         float3 vOffset = normalize(float3(x, y, z)) * (offsetScale *= fOffsetScaleStep);
  134.         //Rotate the offset vector
  135.         float3 vRotatedOffset = mul(vOffset, matRotate);
  136.         //Center pixel's coordinates in screen space
  137.         float3 vSamplePos = float3(IN.UVCoord, fSceneDepthP);
  138.  
  139.         //Offset sample point
  140.         vSamplePos += float3(vRotatedOffset.xy, vRotatedOffset.z * fSceneDepthP);
  141.  
  142.         //Read sample point depth
  143.         float fSceneDepthS = readDepth(vSamplePos.xy);
  144.         //Discard if depth equals max
  145.         if (fSceneDepthS >= 1.0f)
  146.             fAccessibility += 1.0f;
  147.         else {
  148.             //Compute accessibility factor
  149.             float fRangeIsInvalid = saturate(fSceneDepthP - fSceneDepthS);
  150.             fAccessibility += lerp(fSceneDepthS > vSamplePos.z, 0.5f, fRangeIsInvalid);
  151.         }
  152.     }
  153.  
  154.     //Compute average accessibility
  155.     fAccessibility = fAccessibility / nSamplesNum;
  156.  
  157.     //Amplify and return the ambient occlusion coefficient
  158.     float3 ao = saturate(fAccessibility * fAccessibility + fAccessibility);
  159.    
  160.     return float4(ao, 1.0);
  161.     //return tex2D(frameSampler, IN.UVCoord);
  162.     //return tex2D(depthSampler, IN.UVCoord);
  163. }
  164.  
  165. technique t0
  166. {
  167.     pass p0
  168.     {
  169.         VertexShader = compile vs_3_0 FrameVS();
  170.         PixelShader  = compile ps_3_0 ssao_Main();
  171.     }
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement