Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3016)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3017)
@@ -11,6 +11,4 @@
 struct fragment
 {
-	 // normalized screen position
-	float4 pos: WPOS;
 	float2 texCoord: TEXCOORD0; 
 	float3 view: TEXCOORD1;
@@ -46,18 +44,12 @@
 
 // reconstruct world space position
-inline float3 ReconstructSamplePosition(
-										uniform sampler2D colors,
-										float2 texcoord, 
-										float3 bl, float3 br, float3 tl, float3 tr)
-{
-#if USE_EYE_SPACE_DEPTH
-	float eyeSpaceDepth = tex2Dlod(colors, float4(texcoord, 0, 0)).w;
-	//float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
-	float3 rotView = Interpol(texcoord, bl, br, tl, tr);
-	
-	float3 samplePos = -rotView * eyeSpaceDepth;
-#else
-	float3 samplePos = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL)).xyz;
-#endif
+inline float3 ReconstructSamplePos(uniform sampler2D colors,
+								   float2 texcoord, 
+								   float3 bl, float3 br, float3 tl, float3 tr)
+{
+	const float eyeSpaceDepth = tex2Dlod(colors, float4(texcoord, 0, 0)).w;
+	float3 viewVec = Interpol(texcoord, bl, br, tl, tr);
+	float3 samplePos = -viewVec * eyeSpaceDepth;
+
 	return samplePos;
 }
@@ -76,6 +68,6 @@
 		   uniform float3 br,
 		   uniform float3 tl,
-		   uniform float3 tr
-		   //, uniform float3 viewDir
+		   uniform float3 tr, 
+		   uniform float3 viewDir
 		   )
 {
@@ -96,5 +88,5 @@
 		// add random noise: reflect around random normal vector (warning: slow!)
 
-		float2 mynoise = tex2D(noiseTexture, IN.texCoord.xy).xy;
+		float2 mynoise = tex2D(noiseTexture, IN.texCoord).xy;
 		const float2 offsetTransformed = myreflect(offset, mynoise);
 #else
@@ -102,15 +94,15 @@
 #endif
 		// weight with projected coordinate to reach similar kernel size for near and far
-		float2 texcoord = IN.texCoord.xy + offsetTransformed * AREA_SIZE * scaleFactor;
+		float2 texcoord = IN.texCoord.xy + offsetTransformed * scaleFactor;
 
 		//if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f))++ numSamples;
 
-		float3 samplePos = ReconstructSamplePosition(colors, texcoord, bl, br, tl, tr);
-
-
-		///////
-		//-- compute contribution of current sample taking into account direction and angle
-
-		float3 dirSample = samplePos - centerPosition.xyz;
+		const float3 samplePos = ReconstructSamplePos(colors, texcoord, bl, br, tl, tr);
+
+
+		////////////////
+		//-- compute contribution of sample using the direction and angle
+
+		float3 dirSample = samplePos - centerPosition;
 		const float lengthSample = length(dirSample);
 
@@ -118,19 +110,18 @@
 
 		// angle between current normal and direction to sample controls AO intensity.
-		const float cos_angle = max(dot(nDirSample, currentNormal), 0.0f);
+		const float cosAngle = max(dot(nDirSample, currentNormal), 0.0f);
 
 		// the distance_scale offset is used to avoid singularity that occurs at global illumination when 
 		// the distance to a sample approaches zero
-		const float intensity = 
-			//(SAMPLE_INTENSITY * DISTANCE_SCALE) / (DISTANCE_SCALE + lengthSample * lengthSample);
-			SAMPLE_INTENSITY / (DISTANCE_SCALE + lengthSample * lengthSample);
-
-#if 0
+		const float intensity = SAMPLE_INTENSITY / (DISTANCE_SCALE + lengthSample * lengthSample);
+
+#if 1
 		// if surface normal perpenticular to view dir, approx. half of the samples will not count
 		// => compensate for this (on the other hand, projected sampling area could be larger!)
-		const float viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * (1.0f - dot(currentViewDir, currentNormal));
-		total_ao += cos_angle * intensity * viewCorrection;
+		const float viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * dot(viewDir, currentNormal);
+		total_ao += cosAngle * intensity * viewCorrection;
+#else
+		total_ao += cosAngle * intensity;
 #endif
-		total_ao += cos_angle * intensity;
 	}
 
@@ -138,4 +129,5 @@
 }
 
+#pragma position_invariant main
 
 /** The mrt shader for screen space ambient occlusion
@@ -143,5 +135,4 @@
 pixel main(fragment IN, 
 		   uniform sampler2D colors,
-		   uniform sampler2D positions,
 		   uniform sampler2D normals,
 		   uniform sampler2D noiseTexture,
@@ -161,45 +152,33 @@
 
 	float4 norm = tex2Dlod(normals, float4(IN.texCoord, 0 ,0));
-	float3 normal = normalize(norm.xyz);
-
-	// the w coordinate from the persp. projection
-	float w = norm.w;
-
-
-#if USE_EYE_SPACE_DEPTH
+	const float3 normal = normalize(norm.xyz);
+
 	/// reconstruct position from the eye space depth
 	float3 viewDir = IN.view;
 	const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
-
 	const float3 eyeSpacePos = -viewDir * eyeDepth;
-
-	float3 centerPosition;
-	centerPosition.xyz = eyePos + eyeSpacePos;
-
-	const float2 ao = ssao(IN, colors, noiseTexture, samples, normal, eyeSpacePos, w, bl, br, tl, tr);
-
-#else
-
-	// the current world position
-	const float3 centerPosition = tex2Dlod(positions, float4(IN.texCoord, 0, 0)).xyz;
-
-	const float2 ao = ssao(IN, positions, noiseTexture, samples, normal, centerPosition, w, bl, br, tl, tr);
-
-#endif
+	const float3 centerPosition = eyePos + eyeSpacePos;
+
+	float4 realPos = float4(centerPosition, 1.0f);
+
+
+	////////////////
+	//-- calculcate the current projected depth for next frame
+	
+	float4 currentPos = mul(modelViewProj, realPos);
+	
+	const float w = SAMPLE_RADIUS / currentPos.w;
+	currentPos /= currentPos.w;
+	
+	const float currentDepth = currentPos.z * 1e-3f;
+
+	const float2 ao = ssao(IN, colors, noiseTexture, samples, normal, eyeSpacePos, w, bl, br, tl, tr, normalize(viewDir));
+
 
 	/////////////////
 	//-- compute temporally smoothing
 
-	float4 realPos = float4(centerPosition, 1.0f);
-
-
-	// calculcate the current projected depth for next frame
-	float4 currentPos = mul(modelViewProj, realPos);
-	currentPos /= currentPos.w;
-	const float currentDepth = currentPos.z;
-	
-
-	///////////
-	//-- reprojection new frame into old one 
+
+	// reproject new frame into old one 
 	
 	// calculate projected depth
@@ -208,18 +187,19 @@
 
 	// the current depth projected into the old frame
-	const float projDepth = projPos.z;
+	const float projDepth = projPos.z * 1e-3f;
 
 	// fit from unit cube into 0 .. 1
-	float2 tex = (projPos.xy) * 0.5f + 0.5f;
+	const float2 tex = projPos.xy * 0.5f + 0.5f;
 
 	// retrieve the sample from the last frame
 	float4 oldCol = tex2D(oldTex, tex);
 
-	const float oldDepth = oldCol.w;
-	const float depthDif = 1.0f - projDepth / oldDepth;
+	const float oldDepth = oldCol.z;
+	//const float depthDif = 1.0f - projDepth / oldDepth;
+	const float depthDif = projDepth - oldDepth;
 
 
 	//const float oldNumSamples = oldCol.y;
-	const float oldWeight = clamp(oldCol.z, 0, temporalCoherence);
+	const float oldWeight = clamp(oldCol.y, 0, temporalCoherence);
 
 	float newWeight;
@@ -227,5 +207,4 @@
 	// the number of valid samples in this frame
 	//const float newNumSamples = ao.y;
-
 
 	if (//(temporalCoherence > 0) &&
@@ -239,17 +218,39 @@
 		// increase the weight for convergence
 		newWeight = oldWeight + 1.0f;
-		OUT.illum_col.xy = (ao.xy + oldCol.xy * oldWeight) / newWeight;
+		OUT.illum_col.x = (ao.x + oldCol.x * oldWeight) / newWeight;
 		//if (!(oldNumSamples > ao.y - 1.5f)) newWeight = 0;
 	}
 	else
 	{	
-		OUT.illum_col.xy = ao.xy;
+		OUT.illum_col.x = ao.x;
 		newWeight = 0;
 	}
 
-	OUT.illum_col.z = newWeight;
-	OUT.illum_col.w = currentDepth;
+	//OUT.illum_col.y=depthDif;
+	OUT.illum_col.y = newWeight;
+	OUT.illum_col.z = currentDepth;
 
 	return OUT;
+}
+
+
+float Filter(float2 texCoord, 
+			 uniform sampler2D ssaoTex,
+			 uniform float2 filterOffs[NUM_DOWNSAMPLES],
+			 uniform float filterWeights[NUM_DOWNSAMPLES]
+)
+{
+	float average = .0f;
+	float w = .0f;
+
+	for (int i = 0; i < NUM_DOWNSAMPLES; ++ i)
+	{
+		average += filterWeights[i] * tex2Dlod(ssaoTex, float4(texCoord + filterOffs[i], 0, 0)).x;
+		w += filterWeights[i];
+	}
+
+	average *= 1.0f / (float)w;
+
+	return average;
 }
 
@@ -257,13 +258,19 @@
 pixel combine(fragment IN, 
 			  uniform sampler2D colors,
-			  uniform sampler2D ssaoTex)
+			  uniform sampler2D ssaoTex,
+			  uniform float2 filterOffs[NUM_DOWNSAMPLES],
+			  uniform float filterWeights[NUM_DOWNSAMPLES]
+			  )
 {
 	pixel OUT;
 
 	float4 col = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
-	float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
+	float3 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
+
+	if (ao.y < 2000.0f)
+		ao.x = Filter(IN.texCoord, ssaoTex, filterOffs, filterWeights);
 
 	OUT.illum_col = col * ao.x;
-	//OUT.illum_col = float4(ao.x,ao.x,ao.x, ao.w);
+	//OUT.illum_col.xyz = float3(ao.x,1-ao.y*1e-2f, 0);
 	OUT.illum_col.w = col.w;
 
