Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3133)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3134)
@@ -58,7 +58,7 @@
 #define NUM_DOWNSAMPLES 9
 
+//#define NUM_SSAO_FILTERSAMPLES 25
 #define NUM_SSAO_FILTERSAMPLES 49
-//#define NUM_SSAO_FILTERSAMPLES 40
-//#define NUM_SSAO_FILTERSAMPLES 100
+//#define NUM_SSAO_FILTERSAMPLES 81
 
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3104)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3134)
@@ -291,2 +291,9 @@
 
 #endif
+
+
+float4 Output(fragment IN, uniform sampler2D colors): COLOR
+{    
+	// let bilinear filtering do its work
+	return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
+}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3133)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3134)
@@ -16,21 +16,27 @@
 
 
-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;
+
+
+inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
+{
+	float3 x1 = lerp(bl, tl, w.y);
+	float3 x2 = lerp(br, tr, w.y); 
+	float3 v = lerp(x1, x2, w.x); 
+
+	return v;
+}
+
+
+// reconstruct world space position
+inline float3 ReconstructSamplePos(uniform sampler2D tex,
+								   float2 texcoord, 
+								   float3 bl, float3 br, float3 tl, float3 tr)
+{
+	const float eyeSpaceDepth = tex2Dlod(tex, float4(texcoord, 0, 0)).w;
+	
+	float3 viewVec = Interpol(texcoord, bl, br, tl, tr);
+	float3 samplePos = -viewVec * eyeSpaceDepth;
+
+	return samplePos;
 }
 
@@ -56,4 +62,5 @@
 }
 
+#define USE_POSITION
 
 float DiscontinuityFilter(float2 texCoord,
@@ -64,37 +71,49 @@
 						  uniform float filterWeights[NUM_SSAO_FILTERSAMPLES],
 						  float scale,
-						  int index)
+						  float3 bl,
+						  float3 br,
+						  float3 tl,
+						  float3 tr)
 {
 	float average = .0f;
 	float total_w = .0f;
 
+#ifdef USE_POSITION
+	const float3 centerPos = ReconstructSamplePos(ssaoTex, texCoord, bl, br, tl, tr);
+#else
 	const float eyeSpaceDepth = ao.w;
+#endif
+
 	const float3 norm = normalize(tex2Dlod(normalsTex, float4(texCoord, 0, 0)).xyz);
 
 	float4 aoSample;
 	float3 sampleNorm;
+	float3 samplePos;
 	float w;
-	float4 offs;
+	float4 sampleTexCoord;
 	float depthFactor;
 	float normalFactor;
-	float converganceFactor;
+	float convergenceFactor;
 
 	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);
+		sampleTexCoord = float4(texCoord + filterOffs[i] * scale, 0, 0);
+		aoSample = tex2Dlod(ssaoTex, sampleTexCoord);
+		sampleNorm = normalize(tex2Dlod(normalsTex, sampleTexCoord).xyz);
+
+#ifdef USE_POSITION
+		samplePos = ReconstructSamplePos(ssaoTex, sampleTexCoord.xy, bl, br, tl, tr);
+		depthFactor = max(step(1.0f - 5e-1f, 1.0f - length(samplePos - centerPos)), 1e-3f);
+#else // use depth
 		depthFactor = max(step(5e-1f, 1.0f - abs(1.0f - eyeSpaceDepth / aoSample.w)), 1e-3f);
+#endif
 		normalFactor = max(step(0.6f, dot(sampleNorm, norm)), 1e-3f);
-		converganceFactor = max(step(8.5f, aoSample.y), 1e-3f);
-
-		//w = filterWeights[i] * normalFactor * depthFactor * converganceFactor;
-		w = filterWeights[i];// * normalFactor * converganceFactor;
-		//w = filterWeights[i] * depthFactor;
-
-		average += aoSample[index] * w;
+		convergenceFactor = min(60.0f, aoSample.y) * 0.01f;//max(step(18.5f, aoSample.y), 1e-3f);
+
+		w = filterWeights[i] * normalFactor * depthFactor * convergenceFactor;
+		//w = filterWeights[i] * normalFactor * converganceFactor;
+		//w = filterWeights[i] * normalFactor * depthFactor;
+
+		average += aoSample.x * w;
 		total_w += w;
 	}
@@ -112,6 +131,9 @@
 			  uniform sampler2D offsetTex,
 			  uniform float2 filterOffs[NUM_SSAO_FILTERSAMPLES],
-			  uniform float filterWeights[NUM_SSAO_FILTERSAMPLES]
-			  )
+			  uniform float filterWeights[NUM_SSAO_FILTERSAMPLES],
+			  uniform float3 bl,
+			  uniform float3 br,
+			  uniform  float3 tl,
+			  uniform float3 tr)
 {
 	pixel OUT;
@@ -132,5 +154,4 @@
 
 		float border = step(0.001f,  b2
-
 		//float3 id = tex2Dlod(attribsTex, float4(IN.texCoord, 0, 0)).xyz;
 */
@@ -155,5 +176,5 @@
 		//ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, adaptFactor * scaleFactor  / (adaptFactor + ao.y), 0);
 
-		if (ao.y < 10.5f) ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, 1, 0);
+		if (ao.y < 60.5f) ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, scaleFactor, bl, br, tl, tr);
 		//ao.x = DiscontinuityFilter(IN.texCoord, ao, ssaoTex, normalsTex, filterOffs, filterWeights, 1, 0);
 	}
@@ -163,7 +184,7 @@
 	OUT.illum_col.xyz = col.xyz * ao.x;
 
-//	if (ao.y < 1.5f) OUT.illum_col.xyz = float3(10000, 10000, 0);
-//	else if (ao.y < 3.5f) OUT.illum_col.xyz = float3(10000, 0, 10000);
-//	else
+	//	if (ao.y < 1.5f) OUT.illum_col.xyz = float3(10000, 10000, 0);
+	//	else if (ao.y < 3.5f) OUT.illum_col.xyz = float3(10000, 0, 10000);
+	//	else
 	//	if (ao.y < 10.5f) OUT.illum_col.xyz = float3(0, 10000, 0);
 	//OUT.illum_col = float4(dummy3, dummy3, dummy3, col.w);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3128)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3134)
@@ -1186,4 +1186,7 @@
 	{
 	case 27:
+		Debug << "camPosition=" << camera->GetPosition().x << " " << camera->GetPosition().y << " " << camera->GetPosition().z << endl;
+		Debug << "camDirection=" << camera->GetDirection().x << " " << camera->GetDirection().y << " " << camera->GetDirection().z << endl;
+
 		CleanUp();
 		exit(0);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3133)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3134)
@@ -112,50 +112,27 @@
 }
 
-static void ComputeSampleOffsets(float *sampleOffsets, int w, int h)
-{
-	/*
-	const float xoffs = 0.5f / w;
-	const float yoffs = 0.5f / h;
-
-	sampleOffsets[0] =  xoffs; sampleOffsets[1] =  yoffs;
-	sampleOffsets[2] =  xoffs; sampleOffsets[3] = -yoffs;
-	sampleOffsets[4] = -xoffs; sampleOffsets[5] = -yoffs;
-	sampleOffsets[6] = -xoffs; sampleOffsets[7] =  yoffs;
-	*/
-	//const float xoffs = .5f / w;
-	//const float yoffs = .5f / h;
-	
-	const float xoffs = 1.0f / w;
-	const float yoffs = 1.0f / h;
-
-	int idx  = 0;
-
-	for (int x = -1; x <= 1; ++ x)
-	{
-		for (int y = -1; y <= 1; ++ y)
+
+static void ComputeSampleOffsets(float *sampleOffsets, 
+								 int imageW, int imageH,
+								 float width, 
+								 int samples)
+{
+	const float xoffs = width / (float)imageW;
+	const float yoffs = width / (float)imageH;
+	
+	const int numSamples = (int)sqrt((float)samples);
+	const int startSamples = -numSamples / 2;
+	const int endSamples = numSamples + startSamples - 1;
+	//cout << startSamples << " " << endSamples << endl;
+
+	int idx = 0;
+
+	for (int x = startSamples; x <= endSamples; ++ x)
+	{
+		for (int y = startSamples; y <= endSamples; ++ y)
 		{
-			sampleOffsets[idx + 0] = x * xoffs;
-			sampleOffsets[idx + 1] = y * yoffs;
-
+			sampleOffsets[idx + 0] = (float)x * xoffs;
+			sampleOffsets[idx + 1] = (float)y * yoffs;
 			idx += 2;
-		}
-	}
-}
-
-
-static void ComputeSampleOffsets2(float *sampleOffsets, int w, int h, float width, int samples)
-{
-	const float xoffs = width / (float)w;
-	const float yoffs = width / (float)h;
-	
-	const int numSamples = (int)sqrt((float)samples);
-
-	for (int x = 0; x < numSamples; ++ x)
-	{
-		for (int y = 0; y < numSamples; ++ y)
-		{
-			int idx = (y * numSamples + x) * 2;
-			sampleOffsets[idx + 0] = ((float)x - 0.5f * numSamples) * xoffs;
-			sampleOffsets[idx + 1] = ((float)y - 0.5f * numSamples) * yoffs;
 		}
 	}
@@ -434,6 +411,6 @@
 	////////////////
 
-	string combineSsaoParams[] = {"colorsTex", "normalsTex", "ssaoTex", "filterOffs", "filterWeights"};
-	sCgCombineSsaoProgram->AddParameters(combineSsaoParams, 0, 5);
+	string combineSsaoParams[] = {"colorsTex", "normalsTex", "ssaoTex", "filterOffs", "filterWeights", "bl", "br", "tl", "tr"};
+	sCgCombineSsaoProgram->AddParameters(combineSsaoParams, 0, 9);
 
 	//////////////
@@ -464,9 +441,10 @@
 	///////////
 
-#if 0
+	const float filterWidth = 10.0f;
+
+#if 1
 	PoissonDiscSampleGenerator2 poisson(NUM_SSAO_FILTERSAMPLES, 1.0f);
 	poisson.Generate((float *)ssaoFilterOffsets);
 
-	const float filterWidth = 10.0f;
 	const float xoffs = (float)filterWidth / mWidth;
 	const float yoffs = (float)filterWidth / mHeight;
@@ -484,7 +462,7 @@
 	}
 #else
-	//ComputeSampleOffsets(ssaoFilterOffsets, 1024, 768, sqrt(NUM_SSAO_FILTERSAMPLES), NUM_SSAO_FILTERSAMPLES); 
-	ComputeSampleOffsets2(ssaoFilterOffsets, 1024, 768, 5, NUM_SSAO_FILTERSAMPLES); 
-
+	//ComputeSampleOffsets(ssaoFilterOffsets, mWidth, mHeight, sqrt(NUM_SSAO_FILTERSAMPLES), NUM_SSAO_FILTERSAMPLES); 
+	ComputeSampleOffsets(ssaoFilterOffsets, mWidth, mHeight, filterWidth, NUM_SSAO_FILTERSAMPLES); 
+	//cout<<"ssao filter size: " << NUM_SSAO_FILTERSAMPLES << endl;
 	for (int i = 0; i < NUM_SSAO_FILTERSAMPLES; ++ i)
 		ssaoFilterWeights[i] = 1.0f;
@@ -829,4 +807,15 @@
 	sCgCombineSsaoProgram->SetArray1f(i ++, (float *)ssaoFilterWeights, NUM_SSAO_FILTERSAMPLES);
 	
+	Vector3 bl = mCornersView[0];
+	Vector3 br = mCornersView[1];
+	Vector3 tl = mCornersView[2];
+	Vector3 tr = mCornersView[3];
+
+	sCgCombineSsaoProgram->SetValue3f(i ++, bl.x, bl.y, bl.z);
+	sCgCombineSsaoProgram->SetValue3f(i ++, br.x, br.y, br.z);
+	sCgCombineSsaoProgram->SetValue3f(i ++, tl.x, tl.y, tl.z);
+	sCgCombineSsaoProgram->SetValue3f(i ++, tr.x, tr.y, tr.z);
+
+
 	DrawQuad(sCgCombineSsaoProgram);
 	
@@ -968,7 +957,8 @@
 	sCgDownSampleProgram->SetTexture(0, colorsTex);
 
+	const float filterWidth = 1.0f;
 	float downSampleOffsets[NUM_DOWNSAMPLES * 2];
-	ComputeSampleOffsets(downSampleOffsets, fbo->GetWidth(), fbo->GetHeight());
-
+	//ComputeSampleOffsets(downSampleOffsets, fbo->GetWidth(), fbo->GetHeight(), filterWidth, NUM_DOWNSAMPLES);
+	
 	sCgDownSampleProgram->SetArray2f(1, (float *)downSampleOffsets, NUM_DOWNSAMPLES);
 
@@ -979,5 +969,4 @@
 	
 	glPopAttrib();
-	
 	PrintGLerror("downsample");
 }
@@ -1019,5 +1008,5 @@
 	DrawQuad(sCgDownSampleProgram);
 
-	PrintGLerror("OUTPUT");
+	PrintGLerror("output");
 }
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3123)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3134)
@@ -30,7 +30,10 @@
 
 # initial camera position
-camPosition=483.398f 242.364f 186.078f
+#camPosition=483.398f 242.364f 186.078f
 # initial camera orientation
-camDirection=1 0 0
+#camDirection=1 0 0
+
+camPosition=468.025 267.591 182.478
+camDirection=0.937282 0.348573 -0
 
 #lightDirection=-0.8f 1.0f -0.7f
