Commits

Murat Sari committed f5f49e0

Add GLSL shaders for the SSAO demo

Comments (0)

Files changed (31)

Samples/Media/materials/scripts/SSAO/BoxFilterFP.glsl

+// a very simple 4x4 box filter
+// the kernel has the following form
+//   o o o o
+//   o o o o
+//   o o x o
+//   o o o o 
+// where x marks the fragment position and the o marks a sampling point
+#version 120
+
+varying vec2 uv;
+
+uniform sampler2D sOcclusion;
+uniform vec4 screenSize;
+uniform float farClipDistance;
+	
+void main()
+{
+    float color = 0;
+    for (int x = -2; x < 2; x++)
+    for (int y = -2; y < 2; y++)
+    {
+        color += texture2D(sOcclusion, vec2(uv.x + x * screenSize.z, uv.y + y * screenSize.w)).x;
+    }
+    color /= 16;
+        
+    gl_FragColor = vec4(color, color, color, 1);
+}

Samples/Media/materials/scripts/SSAO/CreaseShading.material

     profiles ps_2_x arbfp1
 }
 
+fragment_program SSAO/CreaseShading_fp_glsl glsl
+{
+    source CreaseShadingFP.glsl
+	
+	default_params
+	{
+		param_named sNormal int 0
+		param_named sPosition int 1
+		param_named sRandom int 2
+	}
+}
+
 fragment_program SSAO/CreaseShading_fp unified
 {
+	delegate SSAO/CreaseShading_fp_glsl 
 	delegate SSAO/CreaseShading_fp_hlsl 
 	delegate SSAO/CreaseShading_fp_cg
 }

Samples/Media/materials/scripts/SSAO/CreaseShadingFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sNormal;
+uniform sampler2D sPosition;
+uniform sampler2D sRandom;
+	
+uniform float cRange; // the three(four) artistic parameters
+uniform float cBias;
+uniform float cAverager;
+uniform float cMinimumCrease;
+uniform float cKernelSize; // Bias for the kernel size, Hack for the fixed size 11x11 stipple kernel 
+uniform vec4 cViewportSize;
+
+void main()
+{
+    // get the view space position and normal of the fragment
+    vec3 fragmentPosition = texture2D(sPosition, uv).xyz;
+    vec3 fragmentNormal = texture2D(sNormal, uv).xyz;
+	
+	float totalGI = 0.0f;
+	
+	const int stippleSize = 11; // must be odd
+    for (int i = 0; i < (stippleSize + 1) / 2; i++)
+    {
+        vec2 diagonalStart = vec2(-(stippleSize - 1.0) / 2.0, 0) + i;
+        for(int j = 0; j < (stippleSize + 1) / 2; j++)
+        {
+            vec2 sampleOffset = diagonalStart + vec2(j, -j);
+
+            vec2 sampleUV = uv + (sampleOffset * cViewportSize.zw * cKernelSize);
+            vec3 samplePos = texture2D(sPosition, sampleUV).xyz;
+
+            vec3 toCenter = samplePos - fragmentPosition;
+            float distance = length(toCenter);
+
+            toCenter = normalize(toCenter);
+            float centerContrib = clamp((dot(toCenter, fragmentNormal) - cMinimumCrease) * cBias, 0.0, 1.0);
+            float rangeAttenuation = 1.0f - clamp(distance / cRange, 0.0, 1.0);
+
+            totalGI += centerContrib * rangeAttenuation;
+        }
+    }
+    
+    totalGI /= cAverager;
+    gl_FragColor = 1.0 - vec4(totalGI, totalGI, totalGI, 1.0);
+}

Samples/Media/materials/scripts/SSAO/CrossBilateralFilterXFP.glsl

+// cross bilateral filter
+// gaussian blur with photometric weighting
+// note: encode the viewspace z component in the accessibility texture to reduce
+// the texture fetch count
+#version 120
+varying vec2 uv;
+
+uniform sampler2D sAccessibility;
+uniform sampler2D sMRT2;
+uniform float stepX; // inverse viewport width
+uniform float cPhotometricExponent;
+
+void main()
+{
+    const int kernelWidth = 13;
+    float sigma = (kernelWidth - 1) / 6; // make the kernel span 6 sigma
+    
+    float fragmentDepth = texture2D(sMRT2, uv).z;
+
+    float weights = 0;
+    float blurred = 0;
+    
+    for (float i = -(kernelWidth - 1) / 2; i < (kernelWidth - 1) / 2; i++)
+    {
+        float geometricWeight = exp(-pow(i, 2) / (2 * pow(sigma, 2)));
+        float sampleDepth = texture2D(sMRT2, vec2(uv.x - i * stepX, uv.y)).z;
+        float photometricWeight = 1 / pow((1 + abs(fragmentDepth - sampleDepth)), cPhotometricExponent);
+
+        weights += (geometricWeight * photometricWeight);
+        blurred += texture2D(sAccessibility, vec2(uv.x - i * stepX, uv.y)).r * geometricWeight * photometricWeight;
+    }
+
+    blurred /= weights;
+    gl_FragColor = vec4(blurred, blurred, blurred, 1);
+}

Samples/Media/materials/scripts/SSAO/CrossBilateralFilterYFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sAccessibility;
+uniform sampler2D sMRT2;
+uniform float stepY; // inverse viewport width
+uniform float cPhotometricExponent;
+
+void main()
+{
+    const int kernelWidth = 13;
+    float sigma = (kernelWidth - 1) / 6; // make the kernel span 6 sigma
+    
+    float fragmentDepth = texture2D(sMRT2, uv).z;
+
+    float weights = 0;
+    float blurred = 0;
+    
+    for (float i = -(kernelWidth - 1) / 2; i < (kernelWidth - 1) / 2; i++)
+    {
+        float geometricWeight = exp(-pow(i, 2) / (2 * pow(sigma, 2)));
+        float sampleDepth = texture2D(sMRT2, vec2(uv.x, uv.y - i * stepY)).z;
+        float photometricWeight = 1 / pow((1 + abs(fragmentDepth - sampleDepth)), cPhotometricExponent);
+        
+        weights += (geometricWeight * photometricWeight);
+        blurred += texture2D(sAccessibility, vec2(uv.x, uv.y - i * stepY)).r * geometricWeight * photometricWeight;
+    }
+
+    blurred /= weights;
+    gl_FragColor = vec4(blurred, blurred, blurred, 1);
+}

Samples/Media/materials/scripts/SSAO/Crytek.material

     profiles ps_3_0 arbfp1 
 }
 
+fragment_program SSAO/Crytek_fp_glsl glsl
+{
+    source CrytekFP.glsl
+	
+	default_params
+	{
+		param_named sSceneDepthSampler int 0
+		param_named sRotSampler4x4 int 1
+	}
+}
+
 fragment_program SSAO/Crytek_fp unified
 {
+	delegate SSAO/Crytek_fp_glsl 
 	delegate SSAO/Crytek_fp_hlsl 
 	delegate SSAO/Crytek_fp_cg
 }

Samples/Media/materials/scripts/SSAO/CrytekFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sSceneDepthSampler;
+uniform sampler2D sRotSampler4x4;	
+uniform vec4 cViewportSize; // auto param width/height/inv. width/inv. height
+uniform float cFov; // vertical field of view in radians
+uniform float farClipDistance;
+uniform float nearClipDistance;
+uniform float cSampleInScreenspace; // whether to sample in screen or world space
+uniform float cSampleLengthScreenSpace; // The sample length in screen space [0, 1]
+uniform float cSampleLengthWorldSpace; // the sample length in world space in units
+uniform float cOffsetScale; // [0, 1] The distance of the first sample. samples are the 
+							// placed in [cOffsetScale * cSampleLengthScreenSpace, cSampleLengthScreenSpace]
+uniform float cDefaultAccessibility; // the default value used in the lerp() expression for invalid samples [0, 1]
+uniform float cEdgeHighlight; // multiplier for edge highlighting in [1, 2] 1 is full highlighting 2 is off
+
+void main()
+{
+    const int nSampleNum = 32; // number of samples
+
+    // compute the distance between the clipping planes to convert [0, 1] depth to world space units
+    float clipDepth = farClipDistance - nearClipDistance;
+
+    // get the depth of the current pixel and convert into world space unit [0, inf]
+    float fragmentWorldDepth = texture2D(sSceneDepthSampler, uv).w * clipDepth;
+
+    // get rotation vector, rotation is tiled every 4 screen pixels
+    vec2 rotationTC = uv * cViewportSize.xy / 4.0;
+    vec3 rotationVector = 2.0 * texture2D(sRotSampler4x4, rotationTC).xyz - 1.0; // [-1, 1]x[-1. 1]x[-1. 1]
+    
+    float rUV = 0; // radius of influence in screen space
+    float r = 0; // radius of influence in world space
+    if (cSampleInScreenspace == 1)
+    {
+        rUV = cSampleLengthScreenSpace;
+        r = tan(rUV * cFov) * fragmentWorldDepth;
+    }
+    else
+    {
+        rUV = atan(cSampleLengthWorldSpace / fragmentWorldDepth) / cFov; // the radius of influence projected into screen space
+        r = cSampleLengthWorldSpace;
+    }
+
+    float sampleLength = cOffsetScale; // the offset for the first sample
+    float sampleLengthStep = pow((rUV / sampleLength), 1.0f/nSampleNum);
+    
+    float accessibility = 0;
+    // sample the sphere and accumulate accessibility
+    for (int i = 0; i < (nSampleNum/8); i++)
+    {
+        for (int x = -1; x <= 1; x += 2)
+        for (int y = -1; y <= 1; y += 2)
+        for (int z = -1; z <= 1; z += 2)
+        {
+            //generate offset vector
+            vec3 offset = normalize(vec3(x, y, z)) * sampleLength;
+            
+            // update sample length
+            sampleLength *= sampleLengthStep;
+        
+            // reflect offset vector by random rotation sample (i.e. rotating it) 
+            vec3 rotatedOffset = reflect(offset, rotationVector);
+                    
+            vec2 sampleTC = uv + rotatedOffset.xy * rUV;
+                
+            // read scene depth at sampling point and convert into world space units (m or whatever)
+            float sampleWorldDepth = texture2D(sSceneDepthSampler, sampleTC).w * clipDepth;
+            
+            // check if depths of both pixels are close enough and sampling point should affect our center pixel
+            float fRangeIsInvalid = clamp((fragmentWorldDepth - sampleWorldDepth) / r, 0.0, 1.0);
+            
+            // accumulate accessibility, use default value of 0.5 if right computations are not possible
+			
+            accessibility += mix(float(sampleWorldDepth > (fragmentWorldDepth + rotatedOffset.z * r)) , cDefaultAccessibility, fRangeIsInvalid);
+        }
+    }
+    
+    // get average value
+    accessibility /= nSampleNum;
+
+    // normalize, remove edge highlighting
+    accessibility *= cEdgeHighlight;
+    
+    // amplify and saturate if necessary
+    gl_FragColor = vec4(accessibility, accessibility, accessibility, 1.0);
+}

Samples/Media/materials/scripts/SSAO/GBuffer.material

     profiles ps_3_0 arbfp1
 }
 
+vertex_program SSAO/GBuffer_vp_glsl glsl
+{
+ 	source GBufferVP.glsl
+} 
+
+fragment_program SSAO/GBuffer_fp_glsl glsl
+{
+	source GBufferFP.glsl
+}
+
 vertex_program SSAO/GBuffer_vp unified
 {
+	delegate SSAO/GBuffer_vp_glsl 
 	delegate SSAO/GBuffer_vp_hlsl 
 	delegate SSAO/GBuffer_vp_cg
 }
 fragment_program SSAO/GBuffer_fp unified
 {
+	delegate SSAO/GBuffer_fp_glsl 
 	delegate SSAO/GBuffer_fp_hlsl 
 	delegate SSAO/GBuffer_fp_cg
 }

Samples/Media/materials/scripts/SSAO/GBufferFP.glsl

+#version 120
+#extension GL_ARB_draw_buffers : enable
+
+varying	vec3 oViewPos;
+varying	vec3 oNormal;
+
+uniform float cNearClipDistance;
+uniform float cFarClipDistance; // !!! might be 0 for infinite view projection.
+
+void main() 
+{
+	gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
+
+	float clipDistance = cFarClipDistance - cNearClipDistance;
+	gl_FragData[1] = vec4(normalize(oNormal).xyz, (length(oViewPos) - cNearClipDistance) / clipDistance); // normal + linear depth [0, 1]
+	gl_FragData[2] = vec4(oViewPos, 0.0); // view space position
+}

Samples/Media/materials/scripts/SSAO/GBufferVP.glsl

+#version 120
+
+attribute vec4 vertex;
+attribute vec3 normal;
+
+uniform	mat4 cWorldViewProj;
+uniform	mat4 cWorldView;
+
+varying	vec3 oViewPos;
+varying	vec3 oNormal;
+
+void main()
+{
+	oViewPos = (cWorldView * vertex).xyz; // transform the vertex position to the view space
+	oNormal = (cWorldView * vec4(normal, 0)).xyz; // transform the vertex normal to view space
+	gl_Position = cWorldViewProj * vertex;
+}

Samples/Media/materials/scripts/SSAO/GaussianBlurXFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D mrt1;
+
+uniform float stepX;
+uniform float cKernelWidthBias;
+
+void main()
+{
+    const int kernelWidth = 19;
+    float sigma = (kernelWidth - 1) / 6; // make the kernel span 6 sigma
+
+    float weights = 0;
+    float blurredDepth = 0;
+    
+    for (float i = -(kernelWidth - 1) / 2; i < (kernelWidth - 1) / 2; i++)
+    {
+        float geometricWeight = exp(-pow(i, 2) / (2 * pow(sigma, 2)));
+        weights += geometricWeight;
+        blurredDepth += texture2D(mrt1, vec2(uv.x - i * stepX * cKernelWidthBias, uv.y)).w * geometricWeight;
+    }
+
+    blurredDepth /= weights;
+    gl_FragColor = vec4(texture2D(mrt1, uv).xyz, blurredDepth);
+}

Samples/Media/materials/scripts/SSAO/GaussianBlurYFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D mrt1;
+
+uniform float stepY;
+uniform float cKernelWidthBias;
+
+void main()
+{
+    const int kernelWidth = 19;
+    float sigma = (kernelWidth - 1) / 6; // make the kernel span 6 sigma
+
+    float weights = 0;
+    float blurredDepth = 0;
+    
+    for (float i = -(kernelWidth - 1) / 2; i < (kernelWidth - 1) / 2; i++)
+    {
+        float geometricWeight = exp(-pow(i, 2) / (2 * pow(sigma, 2)));
+        weights += geometricWeight;
+        blurredDepth += texture2D(mrt1, vec2(uv.x, uv.y - i * stepY * cKernelWidthBias)).w * geometricWeight;
+    }
+
+    blurredDepth /= weights;
+    gl_FragColor = vec4(texture2D(mrt1, uv).xyz, blurredDepth);
+}

Samples/Media/materials/scripts/SSAO/HemisphereMC.material

     profiles ps_3_0 arbfp1 
 }
 
+fragment_program SSAO/HemisphereMC_fp_glsl glsl
+{
+	source HemisphereMCFP.glsl
+	
+	default_params
+	{
+		param_named sMRT1 int 0
+		param_named sMRT2 int 1
+		param_named sRand int 2
+	}
+}
+
 fragment_program SSAO/HemisphereMC_fp unified
 {
+	delegate SSAO/HemisphereMC_fp_glsl 
 	delegate SSAO/HemisphereMC_fp_hlsl 
 	delegate SSAO/HemisphereMC_fp_cg
 }

Samples/Media/materials/scripts/SSAO/HemisphereMCFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sMRT1;
+uniform sampler2D sMRT2;
+uniform sampler2D sRand;
+	
+uniform vec4 cViewportSize; // (viewport_width, viewport_height, inverse_viewport_width, inverse_viewport_height)
+uniform float cFov; // vertical field of view in radians
+uniform float cSampleInScreenspace; // whether to sample in screen or world space
+uniform float cSampleLengthScreenSpace; // The sample length in screen space [0, 1]
+uniform float cSampleLengthWorldSpace; // the sample length in world space in units
+uniform float cSampleLengthExponent; // The exponent of the sample length
+
+void main()
+{
+	const int interleaved = 4;
+    const int m = 8;
+    const int n = 4;
+    const int numSamples = m * n;
+    vec2 interleaveOffset = uv * cViewportSize.xy / interleaved;
+    vec3 fragmentPosition = texture2D(sMRT2, uv).xyz; // the current fragment in view space
+    vec3 fragmentNormal = texture2D(sMRT1, uv).xyz; // the fragment normal
+    float rUV = 0; // radius of influence in screen space
+    float r = 0; // radius of influence in world space
+
+    if (cSampleInScreenspace == 1)
+    {
+        rUV = cSampleLengthScreenSpace;
+        r = tan(rUV * cFov) * -fragmentPosition.z;
+    }
+    else
+    {
+        rUV = atan(cSampleLengthWorldSpace / -fragmentPosition.z) / cFov; // the radius of influence projected into screen space
+        r = cSampleLengthWorldSpace;
+    }
+
+    if (rUV < cViewportSize.z) // abort if the projected radius of influence is smaller than 1 fragment
+    {
+        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+        return;
+    }
+
+    float accessibility = 0; // accessibility of the fragment
+
+    const vec3 viewVector = vec3(0.0, 0.0, 1.0); // the constant view vector in view space
+
+    // the reflection vector to align the hemisphere with the fragment normal
+    // somehow the x component must be flipped...???
+    vec3 reflector = normalize(fragmentNormal + viewVector) * vec3(-1.0, 1.0, 1.0); 
+
+    float count = 0;
+    float sampleLength;
+
+    for (float i = 0.0f; i < m; i++)
+    for (float j = 0.0f; j < n; j++)
+    {
+        count ++;
+
+        vec2 randomTC = interleaveOffset + vec2(i/(interleaved * m), j/(interleaved * n)); 
+        vec3 randomVector = (texture2D(sRand, randomTC) * 2 - 1).xyz; // unpack to [-1, 1]x[-1, 1]x[1, 1]
+
+        sampleLength = pow(count/(numSamples * 1.0), cSampleLengthExponent);
+
+        vec3 sampleVector = reflect(randomVector, reflector) * sampleLength;
+
+        vec2 sampleTC = uv + sampleVector.xy * rUV;
+
+        vec3 samplePosition = texture2D(sMRT2, sampleTC).xyz;
+
+        if (samplePosition.z < (fragmentPosition.z - sampleVector.z * r)) // thin air
+            accessibility++;
+        else if(length(fragmentPosition - samplePosition) > r) // solid geometry
+			accessibility++; // out of reach, i.e. false occluder
+    }
+
+    accessibility /= numSamples;
+    gl_FragColor = vec4(accessibility, accessibility, accessibility, 1.0);
+}

Samples/Media/materials/scripts/SSAO/HorizonBased.material

     profiles ps_3_0 arbfp1
 }
 
+fragment_program SSAO/HorizonBased_fp_glsl glsl
+{
+	source HorizonBasedFP.glsl
+	
+	default_params
+	{
+		param_named sMRT1 int 0
+		param_named sMRT2 int 1
+		param_named sRand int 2
+	}
+}
 fragment_program SSAO/HorizonBased_fp unified
 {
+	delegate SSAO/HorizonBased_fp_glsl 
 	delegate SSAO/HorizonBased_fp_hlsl 
 	delegate SSAO/HorizonBased_fp_cg
 }

Samples/Media/materials/scripts/SSAO/HorizonBasedFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sMRT1;
+uniform sampler2D sMRT2;
+uniform sampler2D sRand;
+	
+uniform vec4 cViewportSize; // (viewport_width, viewport_height, inverse_viewport_width, inverse_viewport_height)
+uniform float cFov; // vertical field of view in radians
+uniform float cSampleInScreenspace; // whether to sample in screen or world space
+uniform float cSampleLengthScreenSpace; // The sample length in screen space [0, 1]
+uniform float cSampleLengthWorldSpace; // the sample length in world space in units
+uniform float cAngleBias; // angle bias to avoid shadows in low tessellated curvatures [0, pi/2]
+
+void main()
+{
+    const float pi = 3.1415926535897932384626433832795028841971693993751;
+
+    const float numSteps = 7; // number of samples/steps along a direction
+    const float numDirections = 4; // number of sampling directions in uv space
+    
+    vec3 p = texture2D(sMRT2, uv).xyz; // the current fragment in view space
+    vec3 pointNormal = texture2D(sMRT1, uv).xyz; // the fragment normal
+
+    float Ruv = 0; // radius of influence in screen space
+    float R = 0; // radius of influence in world space
+    if (cSampleInScreenspace == 1)
+    {
+        Ruv = cSampleLengthScreenSpace;
+        R = tan(Ruv * cFov) * -p.z;
+    }
+    else
+    {
+        Ruv = atan(cSampleLengthWorldSpace / -p.z) / cFov; // the radius of influence projected into screen space
+        R = cSampleLengthWorldSpace;
+    }
+
+    // if the radius of influence is smaller than one fragment we exit early,
+    // since all samples would hit the current fragment.
+    if (Ruv < (1 / cViewportSize.x))
+    {
+        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+        return;
+    }
+
+    float occlusion = 0; // occlusion of the fragment
+    
+	// the matrix to create the sample directions
+    // the compiler should evaluate the directions at compile time
+	mat2 directionMatrix = mat2( cos( (2 * pi) / numDirections ), -sin( (2 * pi) / numDirections ),
+								 sin( (2 * pi) / numDirections ),  cos( (2 * pi) / numDirections ));
+						 
+    vec2 deltaUV = vec2(1, 0) * (Ruv / (numSteps + 1)); // The step vector in view space. scale it to the step size
+           
+    // we don't want to sample to the perimeter of R since those samples would be 
+    // omitted by the distance attenuation (W(R) = 0 by definition)
+    // Therefore we add a extra step and don't use the last sample.
+    vec3 randomValues = texture2D(sRand, (uv * cViewportSize.xy) / 4).xyz; //4px tiles
+	mat2 rotationMatrix = mat2( (randomValues.x - 0.5) * 2, -(randomValues.y - 0.5) * 2,
+								(randomValues.y - 0.5) * 2,  (randomValues.x - 0.5) * 2);
+
+    float jitter = randomValues.z;
+
+    for (int i = 0; i < numDirections; i++)
+    {
+        deltaUV = directionMatrix * deltaUV; // rotate the deltaUV vector by 1/numDirections
+        vec2 sampleDirection = rotationMatrix * deltaUV; // now rotate this vector with the random rotation
+
+        float oldAngle = cAngleBias;
+
+        for (int j = 1; j <= numSteps; j++) // sample along a direction, needs to start at one, for the sake of the next line
+        {
+            vec2 sampleUV = uv + ((jitter + j) * sampleDirection); // jitter the step a little bit
+            
+            vec3 sample = texture2D(sMRT2, sampleUV).xyz; // the sample in view space
+            vec3 sampleVector = (sample - p);
+            float gamma = (pi / 2) - acos(dot(pointNormal, normalize(sampleVector))); //the angle between the fragment tangent and the sample
+
+            if (gamma > oldAngle) 
+            {
+                float attenuation = clamp(1 - (pow((length(sampleVector) / R), 2)), 0.0, 1.0);
+                occlusion += attenuation * (sin(gamma) - sin(oldAngle));
+                oldAngle = gamma;
+            }
+        }
+    }
+
+    // ??? should step samples that fall under the horizontal be considered in the following line??? 
+    occlusion /= (numDirections * numSteps);
+    gl_FragColor = 1 - vec4(occlusion, occlusion, occlusion, 1) * 2 * pi;
+}

Samples/Media/materials/scripts/SSAO/NoFilterFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sOcclusion;
+
+void main ()
+{
+    gl_FragColor = vec4(texture2D(sOcclusion, uv).xyz, 1);
+} 

Samples/Media/materials/scripts/SSAO/SSAOPost.material

     profiles ps_3_0 arbfp1
 }
 
+fragment_program SSAO/Post/NoFilter_fp_glsl glsl
+{
+    source NoFilterFP.glsl
+    	
+	default_params
+	{
+		param_named sOcclusion int 0
+	}
+}
+
+fragment_program SSAO/Post/BoxFilter_fp_glsl glsl
+{
+    source BoxFilterFP.glsl
+    	
+	default_params
+	{
+		param_named sOcclusion int 0
+	}
+}
+
+fragment_program SSAO/Post/SmartBoxFilter_fp_glsl glsl
+{
+    source SmartBoxFilterFP.glsl
+    	
+	default_params
+	{
+		param_named sMrt1 int 0
+		param_named sOcclusion int 1
+	}
+}
+
+fragment_program SSAO/HorizonBased/CrossBilateralFilter/X_fp_glsl glsl
+{
+    source CrossBilateralFilterXFP.glsl
+    	
+	default_params
+	{
+		param_named sAccessibility int 0
+		param_named sMRT2 int 1
+	}
+}
+
+fragment_program SSAO/HorizonBased/CrossBilateralFilter/Y_fp_glsl glsl
+{
+    source CrossBilateralFilterYFP.glsl
+    	
+	default_params
+	{
+		param_named sAccessibility int 0
+		param_named sMRT2 int 1
+	}
+}
+
 fragment_program SSAO/Post/NoFilter_fp unified
 {
+	delegate SSAO/Post/NoFilter_fp_glsl
 	delegate SSAO/Post/NoFilter_fp_hlsl
 	delegate SSAO/Post/NoFilter_fp_cg 
 }
 
 fragment_program SSAO/Post/BoxFilter_fp unified
 {
+	delegate SSAO/Post/BoxFilter_fp_glsl
 	delegate SSAO/Post/BoxFilter_fp_hlsl
 	delegate SSAO/Post/BoxFilter_fp_cg 
 }
 
 fragment_program SSAO/Post/SmartBoxFilter_fp unified
 {
+	delegate SSAO/Post/SmartBoxFilter_fp_glsl
 	delegate SSAO/Post/SmartBoxFilter_fp_hlsl
 	delegate SSAO/Post/SmartBoxFilter_fp_cg 
 }
 
 fragment_program SSAO/HorizonBased/CrossBilateralFilter/X_fp unified
 {
+	delegate SSAO/HorizonBased/CrossBilateralFilter/X_fp_glsl
 	delegate SSAO/HorizonBased/CrossBilateralFilter/X_fp_hlsl
 	delegate SSAO/HorizonBased/CrossBilateralFilter/X_fp_cg
 }
 
 fragment_program SSAO/HorizonBased/CrossBilateralFilter/Y_fp unified
 {
+	delegate SSAO/HorizonBased/CrossBilateralFilter/Y_fp_glsl
 	delegate SSAO/HorizonBased/CrossBilateralFilter/Y_fp_hlsl
 	delegate SSAO/HorizonBased/CrossBilateralFilter/Y_fp_cg
 }

Samples/Media/materials/scripts/SSAO/ShowDepth.material

     profiles ps_2_x arbfp1
 }
 
+fragment_program SSAO/ShowDepth_fp_glsl glsl
+{
+	source ShowDepthFP.glsl
+	
+	default_params
+	{
+		param_named mrt1 int 0
+		param_named tex int 1
+	}
+}
+
 fragment_program SSAO/ShowDepth_fp unified
 {
+	delegate SSAO/ShowDepth_fp_glsl 
 	delegate SSAO/ShowDepth_fp_hlsl 
 	delegate SSAO/ShowDepth_fp_cg
 }

Samples/Media/materials/scripts/SSAO/ShowDepthFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D mrt1;
+uniform sampler2D tex;
+	
+void main()
+{
+    float depth = texture2D(mrt1, uv).w;
+    gl_FragColor = vec4(texture2D(tex, vec2(depth*20.0, 0)).rgb, 1.0);
+}

Samples/Media/materials/scripts/SSAO/ShowNormals.material

     profiles ps_2_0 arbfp1
 }
 
+fragment_program SSAO/ShowNormals_fp_glsl glsl
+{
+	source ShowNormalsFP.glsl
+	
+	default_params
+	{
+		param_named mrt1 int 0
+	}
+}
+
 fragment_program SSAO/ShowNormals_fp unified
 {
+	delegate SSAO/ShowNormals_fp_glsl 
 	delegate SSAO/ShowNormals_fp_hlsl 
 	delegate SSAO/ShowNormals_fp_cg
 }

Samples/Media/materials/scripts/SSAO/ShowNormalsFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D mrt1;
+	
+void main()
+{
+    gl_FragColor = vec4(texture2D(mrt1, uv).rgb / 2.0 + 0.5, 1.0);
+}

Samples/Media/materials/scripts/SSAO/ShowViewPos.material

     profiles ps_2_0 arbfp1
 }
 
+fragment_program SSAO/ShowViewPos_fp_glsl glsl
+{
+	source ShowViewPosFP.glsl
+	
+	default_params
+	{
+		param_named mrt2 int 0
+	}
+}
+
 fragment_program SSAO/ShowViewPos_fp unified
 {
+	delegate SSAO/ShowViewPos_fp_glsl 
 	delegate SSAO/ShowViewPos_fp_hlsl 
 	delegate SSAO/ShowViewPos_fp_cg
 }

Samples/Media/materials/scripts/SSAO/ShowViewPosFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D mrt2;
+	
+void main()
+{
+    gl_FragColor = vec4(texture2D(mrt2, uv).rgb * vec3(0.1, 0.1, -0.01), 1.0);
+}

Samples/Media/materials/scripts/SSAO/SmartBoxFilterFP.glsl

+// a very simple and slightly dumb depth aware 4x4 box filter
+// the kernel has the following form
+//   o o o o
+//   o o o o
+//   o o x o
+//   o o o o 
+// where x marks the fragment position and the o marks a sampling point
+#version 120
+varying vec2 uv;
+
+uniform sampler2D sMrt1;
+uniform sampler2D sOcclusion;
+uniform vec4 screenSize;
+uniform float farClipDistance;
+	
+void main()
+{
+    float fragmentDepth = texture2D(sMrt1, uv).x;
+
+    float color = 0;
+    float weight = 0;
+    for (int x = -2; x < 2; x++)
+    for (int y = -2; y < 2; y++)
+    {
+        float sampleDepth = texture2D(sMrt1, vec2(uv.x + x * screenSize.z, uv.y + y * screenSize.w)).x;
+        float dist = abs(fragmentDepth - sampleDepth) * farClipDistance + 0.5;
+        float sampleWeight = 1 / (pow(dist, 1) + 1);
+        color += sampleWeight * texture2D(sOcclusion, vec2(uv.x + x * screenSize.z, uv.y + y * screenSize.w)).x;
+        weight += sampleWeight;
+    }
+    color /= weight;
+        
+    gl_FragColor = vec4(color, color, color, 1);
+}

Samples/Media/materials/scripts/SSAO/UnsharpMask.material

     profiles ps_2_0 arbfp1
 }
 
+fragment_program SSAO/UnsharpMask_fp_glsl glsl
+{
+    source UnsharpMaskFP.glsl
+
+	default_params
+	{
+		param_named blurred int 0
+		param_named mrt0 int 1
+		param_named mrt1 int 2
+	}
+}
+
+fragment_program SSAO/UnsharpMask/GaussianBlurX_fp_glsl glsl
+{
+    source GaussianBlurXFP.glsl
+
+	default_params
+	{
+		param_named mrt1 int 0
+	}	
+}
+
+fragment_program SSAO/UnsharpMask/GaussianBlurY_fp_glsl glsl
+{
+    source GaussianBlurYFP.glsl
+
+	default_params
+	{
+		param_named mrt1 int 0
+	}
+}
+
 fragment_program SSAO/UnsharpMask_fp unified
 {
+	delegate SSAO/UnsharpMask_fp_glsl 
 	delegate SSAO/UnsharpMask_fp_hlsl 
 	delegate SSAO/UnsharpMask_fp_cg
 }
 
 fragment_program SSAO/UnsharpMask/GaussianBlurX_fp unified
 {
+	delegate SSAO/UnsharpMask/GaussianBlurX_fp_glsl 
 	delegate SSAO/UnsharpMask/GaussianBlurX_fp_hlsl 
 	delegate SSAO/UnsharpMask/GaussianBlurX_fp_cg
 }
 
 fragment_program SSAO/UnsharpMask/GaussianBlurY_fp unified
 {
+	delegate SSAO/UnsharpMask/GaussianBlurY_fp_glsl 
 	delegate SSAO/UnsharpMask/GaussianBlurY_fp_hlsl 
 	delegate SSAO/UnsharpMask/GaussianBlurY_fp_cg
 }

Samples/Media/materials/scripts/SSAO/UnsharpMaskFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D blurred;
+uniform sampler2D mrt0;
+uniform sampler2D mrt1;
+
+uniform float cLambda;
+
+void main()
+{
+    float spacialImportance = texture2D(blurred, uv).w - texture2D(mrt1, uv).w;
+    vec4 color = texture2D(mrt0, uv);
+    if (spacialImportance < 0) // darkening only
+    {
+        gl_FragColor = vec4(color.rgb + (cLambda * spacialImportance), 1);
+    } 
+	else 
+    {
+        gl_FragColor = color;
+    }
+}

Samples/Media/materials/scripts/SSAO/Volumetric.material

     profiles arbfp1 ps_3_0
 }
 
+fragment_program SSAO/Volumetric_fp_glsl glsl
+{
+    source VolumetricFP.glsl
+
+	default_params
+	{
+		param_named sMRT1 int 0
+		param_named sMRT2 int 1
+		param_named sRand int 2
+	}
+}
+
 fragment_program SSAO/Volumetric_fp unified
 {
+	delegate SSAO/Volumetric_fp_glsl 
 	delegate SSAO/Volumetric_fp_hlsl 
 	delegate SSAO/Volumetric_fp_cg
 }

Samples/Media/materials/scripts/SSAO/VolumetricFP.glsl

+#version 120
+varying vec2 uv;
+
+uniform sampler2D sMRT1; // fragment normals
+uniform sampler2D sMRT2; // view space position, remember that we are looking down the negative Z axis!!!
+uniform sampler2D sRand;
+
+uniform vec4 cViewportSize; // (viewport_width, viewport_height, inverse_viewport_width, inverse_viewport_height)
+uniform float cFov; // vertical field of view in radians
+uniform float cSampleInScreenspace; // whether to sample in screen or world space
+uniform float cSampleLengthScreenSpace; // The sample length in screen space [0, 1]
+uniform float cSampleLengthWorldSpace; // the sample length in world space in units
+	
+void main()
+{
+    const int interleaved = 4;
+    const int m = 8;
+    const int n = 4;
+    const int numSamples = m * n;    
+
+    vec2 interleaveOffset = uv * cViewportSize.xy / interleaved;
+    
+    vec3 fragmentPosition = texture2D(sMRT2, uv).xyz; // the current fragment in view space
+    vec3 fragmentNormal = texture2D(sMRT1, uv).xyz * vec3(1, -1, 1); // the fragment normal
+
+    float rUV = 0; // radius of influence in screen space
+    float r = 0; // radius of influence in world space
+    if (cSampleInScreenspace == 1)
+    {
+        rUV = cSampleLengthScreenSpace;
+        r = tan(rUV * cFov) * -fragmentPosition.z;
+    }
+    else
+    {
+        rUV = atan(cSampleLengthWorldSpace / -fragmentPosition.z) / cFov; // the radius of influence projected into screen space
+        r = cSampleLengthWorldSpace;
+    }
+
+
+    if (rUV < (cViewportSize.z)) // abort if the projected radius of influence is smaller than 1 fragment
+    {
+        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+        return;
+    }
+    
+    float r2 = r/2;
+    float rUV2 = rUV /2;
+    
+    vec3 center = fragmentPosition + fragmentNormal * (r2);
+    vec2 centerUV = uv + (fragmentNormal * (rUV2)).xy;
+
+    float F = 0; // unoccluded Volume
+    float V = 0; // occluded Volume
+    float invalid = 0;
+
+    for (float i = 0.0f; i < m; i++)
+    for (float j = 0.0f; j < n; j++)
+    {
+        vec2 randomTC = interleaveOffset + vec2(i/(interleaved * m), j/(interleaved * n)); 
+        vec2 randomVector = (texture2D(sRand, randomTC) * 2 - 1).xy; // unpack to [-1, 1]^2
+
+        vec2 sample = randomVector * (r2);
+        vec2 sampleUV = randomVector * (rUV2);
+
+        float zEntry = center.z + (r2) * sqrt(1 - sample.x * sample.x - sample.y * sample.y);
+        float zExit = center.z - (r2) * sqrt(1 - sample.x * sample.x - sample.y * sample.y);
+        float zStar = texture2D(sMRT2, centerUV + sampleUV).z;
+
+        F += zExit - zEntry;
+
+        if (zExit <= zStar && zStar <= zEntry)
+            V += zStar - zEntry;
+        else //if (zStar < zExit)
+            V += zExit - zEntry;
+    }
+
+    float accessibility = V / F;
+    gl_FragColor = vec4(accessibility, accessibility, accessibility, 1.0);
+
+}

Samples/Media/materials/scripts/StdQuad_vp.program

 // Unified definitions
 vertex_program Ogre/Compositor/StdQuad_vp unified
 {
+	delegate Ogre/Compositor/StdQuad_GLSL_vp
 	delegate Ogre/Compositor/StdQuad_GLSLES_vp
 	delegate Ogre/Compositor/StdQuad_Cg_vp
 }

Samples/SSAO/include/SSAO.h

     StringVector getRequiredPlugins()
     {
         StringVector names;
-        names.push_back("Cg Program Manager");
+        //names.push_back("Cg Program Manager");
         return names;
     }