Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- uniform sampler2D R5_texture0; // Depth in linear format
- uniform sampler2D R5_texture1; // Normal
- uniform sampler2D R5_texture2; // Random
- uniform vec2 R5_pixelSize; // 0-1 factor size of the pixel
- uniform vec4 R5_clipRange; // Near/far clipping range
- uniform mat4 R5_projectionMatrix; // Current projection matrix
- uniform mat4 R5_inverseProjMatrix; // Inverse projection matrix
- //============================================================================================================
- // Retrieves depth at the specified texture coordinates
- //============================================================================================================
- float GetDistance (in vec2 texCoord)
- {
- //return texture2D(R5_texture0, texCoord).r * R5_clipRange.w;
- const vec4 bitSh = vec4(1.0 / 16777216.0, 1.0 / 65535.0, 1.0 / 256.0, 1.0);
- return dot(texture2D(R5_texture0, texCoord), bitSh) * R5_clipRange.w;
- }
- //============================================================================================================
- // Calculates the view space position from the specified texture coordinates and depth
- //============================================================================================================
- vec3 GetViewPos (in vec2 texCoord)
- {
- float depth = (R5_clipRange.y - R5_clipRange.z / (GetDistance(texCoord) + R5_clipRange.x)) / R5_clipRange.w;
- vec4 pos = vec4(texCoord.x, texCoord.y, depth, 1.0);
- pos.xyz = pos.xyz * 2.0 - 1.0;
- pos = R5_inverseProjMatrix * pos;
- return pos.xyz / pos.w;
- }
- //============================================================================================================
- // Fragment Shader
- //============================================================================================================
- void main()
- {
- // Modifiable settings
- const float ssaoFocus = 1.5;
- const float ssaoPower = 8.0;
- const int ssaoLoops = 32; // R5_AUTO_ADJUST
- // Texture coordinate
- vec2 texCoord = gl_TexCoord[0].xy;
- // View space normal
- vec3 normal = normalize(texture2D(R5_texture1, texCoord).xyz * 2.0 - 1.0);
- // View space position of the pixel
- vec3 pos = GetViewPos(texCoord);
- // Random value sampled from the texture in repeated screen coordinates (32 x 32)
- vec2 modifier = texture2D(R5_texture2, texCoord / R5_pixelSize / 32.0).xy + (pos.xy + pos.z);
- float dist, visibility = 0.0;
- vec4 random, screenPos, viewPos = vec4(1.0);
- for (int i = 0; i < ssaoLoops; i++)
- {
- // Retrieve a new random vector from the texture
- random = texture2D(R5_texture2, modifier);
- // Not much point in normalizing -- no visual difference
- random.xyz = random.xyz * 2.0 - 1.0;
- // Randomize the modifier for the next loop
- modifier += random.xy;
- // Flip the random vector if it's below the plane
- if (dot(random.xyz, normal) < 0.0) random.xyz = -random.xyz;
- // Randomly offset view-space position
- viewPos.xyz = random.xyz * (ssaoFocus * random.w) + pos;
- // Calculate the randomly offset position's screen space coordinates -- second most expensive operation
- screenPos = R5_projectionMatrix * viewPos;
- // Get the depth at the screen space coordinates -- this is the most expensive operation
- dist = GetDistance(screenPos.xy / screenPos.w * 0.5 + 0.5);
- // Visibility is linearly scaled, depending on how far the distance is from the focus range
- visibility += min(abs((viewPos.z + dist) / ssaoFocus + 1.0), 1.0);
- }
- // Final occlusion factor
- gl_FragColor = vec4(pow(visibility / float(ssaoLoops), ssaoPower));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement