1// cross bilateral filter
2// gaussian blur with photometric weighting
3// note: encode the viewspace z component in the accessibility texture to reduce
4// the texture fetch count
5#version 120
6varying vec2 uv;
7
8uniform sampler2D sAccessibility;
9uniform sampler2D sMRT2;
10uniform float stepX; // inverse viewport width
11uniform float cPhotometricExponent;
12
13void main()
14{
15    const int kernelWidth = 13;
16    float sigma = (kernelWidth - 1) / 6; // make the kernel span 6 sigma
17
18    float fragmentDepth = texture2D(sMRT2, uv).z;
19
20    float weights = 0;
21    float blurred = 0;
22
23    for (float i = -(kernelWidth - 1) / 2; i < (kernelWidth - 1) / 2; i++)
24    {
25        float geometricWeight = exp(-pow(i, 2) / (2 * pow(sigma, 2)));
26        float sampleDepth = texture2D(sMRT2, vec2(uv.x - i * stepX, uv.y)).z;
27        float photometricWeight = 1 / pow((1 + abs(fragmentDepth - sampleDepth)), cPhotometricExponent);
28
29        weights += (geometricWeight * photometricWeight);
30        blurred += texture2D(sAccessibility, vec2(uv.x - i * stepX, uv.y)).r * geometricWeight * photometricWeight;
31    }
32
33    blurred /= weights;
34    gl_FragColor = vec4(blurred, blurred, blurred, 1);
35}