#include "../shaderenv.h" struct fragment { float2 texCoord: TEXCOORD0; float3 view: TEXCOORD1; }; struct pixel { float4 illum_col: COLOR0; }; float Filter(float2 texCoord, uniform sampler2D ssaoTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES]) { float average = .0f; float w = .0f; for (int i = 0; i < NUM_SSAO_FILTERSAMPLES; ++ i) { average += filterWeights[i] * tex2Dlod(ssaoTex, float4(texCoord + filterOffs[i], 0, 0)).x; w += filterWeights[i]; } average *= 1.0f / (float)w; return average; } float Filter(float2 texCoord, uniform sampler2D ssaoTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES], float scale) { float average = .0f; float w = .0f; for (int i = 0; i < NUM_SSAO_FILTERSAMPLES; ++ i) { average += filterWeights[i] * tex2Dlod(ssaoTex, float4(texCoord + filterOffs[i] * scale, 0, 0)).x; w += filterWeights[i]; } average *= 1.0f / (float)w; return average; } float DiscontinuityFilter(float2 texCoord, float4 ao, uniform sampler2D ssaoTex, uniform sampler2D normalsTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES], float scale, int index) { float average = .0f; float total_w = .0f; const float eyeSpaceDepth = ao.w; const float3 norm = normalize(tex2Dlod(normalsTex, float4(texCoord, 0, 0)).xyz); float4 aoSample; float3 sampleNorm; float w; float4 offs; float depthFactor; float normalFactor; for (int i = 0; i < NUM_SSAO_FILTERSAMPLES; ++ i) { offs = float4(texCoord + filterOffs[i] * scale, 0, 0); aoSample = tex2Dlod(ssaoTex, offs); sampleNorm = normalize(tex2Dlod(normalsTex, offs).xyz); //depthFactor = clamp(1.0f - abs(1.0f - eyeSpaceDepth / aoSample.w), 1e-3f, 1.0f); depthFactor = max(step(5e-1f, 1.0f - abs(1.0f - eyeSpaceDepth / aoSample.w)), 1e-3f); normalFactor = max(step(0.6f, dot(sampleNorm, norm)), 1e-3f); w = filterWeights[i] * normalFactor * depthFactor; //w = filterWeights[i] * depthFactor; average += aoSample[index] * w; total_w += w; } average *= 1.0f / max(total_w, 1e-6f); return average; } pixel combine(fragment IN, uniform sampler2D colorsTex, uniform sampler2D ssaoTex, uniform sampler2D normalsTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES] ) { pixel OUT; float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)); float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0)); //if ((ao.y < 60.0f) && (col.w < 1e10f)) if (col.w < 1e10f) { const static float scaleFactor = 1.0f; //const static float scaleFactor = 10.0f; const static float adaptFactor = 50.0f; //ao.x = Filter(IN.texCoord, ssaoTex, filterOffs, filterWeights); //ao.x = Filter(IN.texCoord, ssaoTex, filterOffs, filterWeights, 1.0f / (1.0f + ao.y)); //ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, adaptFactor * scaleFactor * ao.z / (adaptFactor + ao.y), 0); ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, adaptFactor * scaleFactor / (adaptFactor + ao.y), 0); } //OUT.illum_col.xyz = col.xyz * ao.x; //OUT.illum_col = float4(ao.x, ao.x, ao.x, col.w); OUT.illum_col.xyz = float3(1.0f - ao.x, clamp(1.0f - ao.y * 1e-2f, 0, 1), 1); OUT.illum_col.w = col.w; return OUT; } float DiscontinuityFilter2(float2 texCoord, float4 ao, uniform sampler2D ssaoTex, uniform sampler2D normalsTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES], float scale, int index) { float average = .0f; float total_w = .0f; const float eyeSpaceDepth = ao.w; const float3 norm = normalize(tex2Dlod(normalsTex, float4(texCoord, 0, 0)).xyz); float4 aoSample; float3 sampleNorm; float w; float4 offs; float depthFactor; float normalFactor; for (int i = 0; i < NUM_SSAO_FILTERSAMPLES; ++ i) { offs = float4(texCoord + filterOffs[i] * scale, 0, 0); aoSample = tex2Dlod(ssaoTex, offs); sampleNorm = normalize(tex2Dlod(normalsTex, offs).xyz); //depthFactor = clamp(1.0f - abs(1.0f - eyeSpaceDepth / aoSample.w), 1e-3f, 1.0f); depthFactor = max(step(5e-1f, 1.0f - abs(1.0f - eyeSpaceDepth / aoSample.w)), 1e-3f); normalFactor = max(step(0.6f, dot(sampleNorm, norm)), 1e-3f); //w = filterWeights[i] * normalFactor * depthFactor; w = normalFactor * depthFactor; average += aoSample.y * w; total_w += w; } average *= 1.0f / max(total_w, 1e-3f); return average; } pixel smoothSsao(fragment IN, uniform sampler2D ssaoTex, uniform sampler2D normalsTex, uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES], uniform float filterWeights[NUM_SSAO_FILTERSAMPLES] ) { pixel OUT; float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0)); //const static float scaleFactor = 20.0f; const static float scaleFactor = 10.0f; ao.y = DiscontinuityFilter2(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, scaleFactor * ao.z, 1); //ao.y = DiscontinuityFilter2(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, scaleFactor, 1); OUT.illum_col = ao; return OUT; }