Advertisement
Guest User

Untitled

a guest
May 29th, 2011
3,768
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.70 KB | None | 0 0
  1. uniform sampler2D   R5_texture0;    // Depth in linear format
  2. uniform sampler2D   R5_texture1;    // Normal
  3. uniform sampler2D   R5_texture2;    // Random
  4.  
  5. uniform vec2 R5_pixelSize;          // 0-1 factor size of the pixel
  6. uniform vec4 R5_clipRange;          // Near/far clipping range
  7. uniform mat4 R5_projectionMatrix;   // Current projection matrix
  8. uniform mat4 R5_inverseProjMatrix;  // Inverse projection matrix
  9.  
  10. //============================================================================================================
  11. // Retrieves depth at the specified texture coordinates
  12. //============================================================================================================
  13.  
  14. float GetDistance (in vec2 texCoord)
  15. {
  16.     //return texture2D(R5_texture0, texCoord).r * R5_clipRange.w;
  17.     const vec4 bitSh = vec4(1.0 / 16777216.0, 1.0 / 65535.0, 1.0 / 256.0, 1.0);
  18.     return dot(texture2D(R5_texture0, texCoord), bitSh) * R5_clipRange.w;
  19. }
  20.  
  21. //============================================================================================================
  22. // Calculates the view space position from the specified texture coordinates and depth
  23. //============================================================================================================
  24.  
  25. vec3 GetViewPos (in vec2 texCoord)
  26. {
  27.     float depth = (R5_clipRange.y - R5_clipRange.z / (GetDistance(texCoord) + R5_clipRange.x)) / R5_clipRange.w;
  28.     vec4 pos = vec4(texCoord.x, texCoord.y, depth, 1.0);
  29.     pos.xyz = pos.xyz * 2.0 - 1.0;
  30.     pos = R5_inverseProjMatrix * pos;
  31.     return pos.xyz / pos.w;
  32. }
  33.  
  34. //============================================================================================================
  35. // Fragment Shader
  36. //============================================================================================================
  37.  
  38. void main()
  39. {
  40.     // Modifiable settings
  41.     const float ssaoFocus = 1.5;
  42.     const float ssaoPower = 8.0;
  43.     const int   ssaoLoops = 32; // R5_AUTO_ADJUST
  44.  
  45.     // Texture coordinate
  46.     vec2 texCoord = gl_TexCoord[0].xy;
  47.  
  48.     // View space normal
  49.     vec3 normal = normalize(texture2D(R5_texture1, texCoord).xyz * 2.0 - 1.0);
  50.  
  51.     // View space position of the pixel
  52.     vec3 pos = GetViewPos(texCoord);
  53.  
  54.     // Random value sampled from the texture in repeated screen coordinates (32 x 32)
  55.     vec2 modifier = texture2D(R5_texture2, texCoord / R5_pixelSize / 32.0).xy + (pos.xy + pos.z);
  56.  
  57.     float dist, visibility = 0.0;
  58.     vec4 random, screenPos, viewPos = vec4(1.0);
  59.  
  60.     for (int i = 0; i < ssaoLoops; i++)
  61.     {
  62.         // Retrieve a new random vector from the texture
  63.         random = texture2D(R5_texture2, modifier);
  64.  
  65.         // Not much point in normalizing -- no visual difference
  66.         random.xyz = random.xyz * 2.0 - 1.0;
  67.  
  68.         // Randomize the modifier for the next loop
  69.         modifier += random.xy;
  70.  
  71.         // Flip the random vector if it's below the plane
  72.         if (dot(random.xyz, normal) < 0.0) random.xyz = -random.xyz;
  73.  
  74.         // Randomly offset view-space position
  75.         viewPos.xyz = random.xyz * (ssaoFocus * random.w) + pos;
  76.  
  77.         // Calculate the randomly offset position's screen space coordinates -- second most expensive operation
  78.         screenPos = R5_projectionMatrix * viewPos;
  79.  
  80.         // Get the depth at the screen space coordinates -- this is the most expensive operation
  81.         dist = GetDistance(screenPos.xy / screenPos.w * 0.5 + 0.5);
  82.  
  83.         // Visibility is linearly scaled, depending on how far the distance is from the focus range
  84.         visibility += min(abs((viewPos.z + dist) / ssaoFocus + 1.0), 1.0);
  85.     }
  86.  
  87.     // Final occlusion factor
  88.     gl_FragColor = vec4(pow(visibility / float(ssaoLoops), ssaoPower));
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement