Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 150 core
- #define CONST_PI 3.141592653589793238
- #define CONST_POWER 4.0
- #define CONST_RADIUS 2.0
- #define CONST_SAMPLING_DIRECTIONS 4
- #define CONST_NUM_SAMPLING_STEPS 3
- #define CONST_TANGENT_BIAS 0.33
- #define CONST_RANGE 3
- uniform sampler2D texture_depth;
- uniform sampler2D texture_normal;
- uniform sampler2D texture_noise;
- uniform vec2 uScreenDimension;
- uniform float uInverseAspectRatio;
- uniform mat4 uInverseProjection;
- uniform vec2 frustumCorner;
- uniform vec2 nearFar;
- in vec2 pass_TextureCoord;
- out vec4 out_Color;
- vec3 unproject( vec2 tc, float depth ) {
- return vec3( (tc * 2.0 - 1.0) * frustumCorner, -1) * depth;
- }
- float rand(vec2 co){
- return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
- }
- void main() {
- float depth = texture( texture_depth, pass_TextureCoord ).r;
- vec3 viewPos = unproject( pass_TextureCoord, depth );
- vec3 viewNorm = texture(texture_normal, pass_TextureCoord).xyz * 2.0 - 1.0;
- float total = 0.0;
- float sample_direction_increment = (CONST_PI * 2) / float(CONST_SAMPLING_DIRECTIONS);
- // Calculate noise
- vec2 noiseScale = uScreenDimension/4.0;
- vec2 randVector = normalize( texture( texture_noise, pass_TextureCoord * noiseScale).xy * 2.0 - 1.0);
- float offsetScale = 1 / (depth * nearFar.y);
- for (int i = 0; i < CONST_SAMPLING_DIRECTIONS; i++) {
- float randomValue = rand(pass_TextureCoord); // Unused. Noise texture has better results
- float sampling_angle = float(i) * sample_direction_increment;// + randomValue; // azimuth angle theta in the paper
- vec2 sampleDir = vec2(cos(sampling_angle), sin(sampling_angle));
- // Apply noise
- sampleDir = reflect(sampleDir, randVector); // If random rotation is used, comment out this line
- // March along sampleDir (vector)
- float tangentAngle = acos(dot(vec3(sampleDir, 0.0), viewNorm)) - (0.5 * CONST_PI) + CONST_TANGENT_BIAS;
- float horizonAngle = tangentAngle;
- float SAMPLING_STEP = (CONST_RADIUS + ((randVector.x - randVector.y) * 0.5)) / float(CONST_NUM_SAMPLING_STEPS);
- SAMPLING_STEP *= 0.1;
- // Scale by distance from camera
- SAMPLING_STEP *= offsetScale;
- // Force min-max
- SAMPLING_STEP = min(0.05, max( 0.001, SAMPLING_STEP ) );
- // Start occlusion check
- float occlusion = 0.0;
- for (int j = 0; j < CONST_NUM_SAMPLING_STEPS; j++) {
- // march along the sampling direction and see what the horizon is
- vec2 sampleOffset = float(j+1) * SAMPLING_STEP * sampleDir;
- sampleOffset.x *= uInverseAspectRatio;
- vec2 offTex = pass_TextureCoord + sampleOffset;
- // reconstruct view-space position for this sample
- vec3 off_viewPos = unproject( offTex.st, texture( texture_depth, offTex.st ).r );//reconstructPosition( texture( texture_depth, offTex.st ).r, offTex );
- // get difference vector
- vec3 diff = off_viewPos.xyz - viewPos.xyz;
- // find length
- float diffLength = length(diff);
- // If there is an occlusion
- float normalCheck = 1.0 - clamp( dot( tangentAngle, horizonAngle ), 0.0, 1.0 );
- float rangeCheck = smoothstep(0.0, 1.0, ( float(CONST_RADIUS * CONST_RANGE) * (1/uScreenDimension.x) ) / abs(diff.z));
- // find horizon angle
- float x = diff.z / length(diff.xy);
- float elevationAngle = x * inversesqrt(x*x + 1); // ORIGINAL, SLOWER --> atan(diff.z / length(diff.xy));
- horizonAngle = max(horizonAngle, elevationAngle);
- // Handle attenuation
- float normDiff = diffLength / float(CONST_RADIUS);
- float attenuation = 1 - normDiff*normDiff;
- // Fade out
- float fade = 1.0 - clamp( depth * 1.5, 0.0, 1.0);
- // Apply occlusion
- occlusion += clamp(attenuation * (sin(horizonAngle) - sin(tangentAngle)), 0.0, 1.0) * normalCheck * rangeCheck * fade;
- }
- occlusion /= float(CONST_NUM_SAMPLING_STEPS);
- total += 1.0 - occlusion;
- }
- // Divide ao by amount of directions
- total /= CONST_SAMPLING_DIRECTIONS;
- // Power
- total = pow( clamp( total, 0.0, 1.0), CONST_POWER );
- // Output ssao
- out_Color = vec4(total, total, total, 1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement