stk-code_catmod/data/shaders/ssao.frag
2013-11-30 21:33:06 +00:00

79 lines
2.3 KiB
GLSL

#version 120
uniform sampler2D tex;
uniform sampler2D oldtex;
const float totStrength = 2.38;
const float strength = 0.07;
const float falloff = 0.000002;
#define SAMPLES 16
const float invSamples = 1.0 / SAMPLES;
void main(void)
{
// A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4
// Again not using const because of broken Intel Windows drivers
vec2 vecs[16] = vec2[](vec2(0.43589, -0.9), vec2(-0.9, 0.43589),
vec2(-0.8, -0.6), vec2(0.6, 0.8),
vec2(0.866025, -0.5), vec2(-0.5, 0.866025),
vec2(-0.3, -0.953939), vec2(0.953939, 0.3),
vec2(0.3, -0.781025), vec2(-0.781025, 0.3),
vec2(-0.56, -0.621611), vec2(0.621611, 0.56),
vec2(0.734847, -0.4), vec2(-0.4, 0.734847),
vec2(-0.2, -0.6), vec2(0.6, 0.2));
vec2 uv = gl_TexCoord[0].xy;
vec4 cur = texture2D(tex, uv);
float curdepth = cur.a;
// Will we skip this pixel? (if it's the sky)
float len = dot(vec3(1.0), abs(cur.xyz));
if (len < 0.2 || curdepth > 0.8) discard;
float mytotstrength = 3.0 * totStrength * curdepth * (1.0 - curdepth);
// get the normal of current fragment
vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
float bl = 0.0;
// adjust for the depth, 0.1 close, 0.01 far
float radD = 0.10 - 0.09 * smoothstep(0.0, 0.2, curdepth);
for(int i = 0; i < SAMPLES; ++i) {
vec2 ray = uv + radD * vecs[i];
// get the depth of the occluder fragment
vec4 occluderFragment = texture2D(tex, ray);
float normAcceptable = step(0.2, dot(vec3(1.0), abs(occluderFragment.xyz)));
// get the normal of the occluder fragment
vec3 occNorm = normalize(occluderFragment.xyz * vec3(2.0) - vec3(1.0));
// if depthDifference is negative = occluder is behind current fragment
float depthDifference = curdepth - occluderFragment.a;
// calculate the difference between the normals as a weight
float normDiff = 1.0 - max(dot(occNorm, norm), 0.0);
normDiff = smoothstep(0.1, 0.3, normDiff);
// the falloff equation, starts at falloff and is kind of 1/x^2 falling
bl += step(falloff, depthDifference) * normDiff * normAcceptable *
(1.0 - smoothstep(falloff, strength, depthDifference));
}
// output the result
float ao = 1.0 - mytotstrength * bl * invSamples;
// Mix with old result to avoid flicker
float oldao = texture2D(oldtex, uv).x;
ao = mix(ao, oldao, 0.3);
gl_FragColor = vec4(vec3(ao), curdepth);
}