Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp	(revision 2991)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp	(revision 2999)
@@ -86,4 +86,6 @@
 	mHeight = h;
 
+	int myformat = GL_RGBA;
+
 	switch (format)
 	{
@@ -94,4 +96,8 @@
 	case BUFFER_FLOAT_32: 
 		mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA32F_ARB; break;
+	case BUFFER_LUMINANCE_ALPHA: 
+		mGlFormat = GL_FLOAT; mInternalFormat = GL_LUMINANCE_ALPHA ;
+		myformat = GL_LUMINANCE_ALPHA;
+		break;
 	default:
 		mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8;
@@ -109,5 +115,5 @@
 	glGenTextures(1, &mTexId);
 	glBindTexture(GL_TEXTURE_2D, mTexId);
-	glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, w, h, 0, GL_RGBA, mGlFormat, NULL);
+	glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, w, h, 0, myformat, mGlFormat, NULL);
 
 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_TEXTURE_2D, mTexId, 0);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 2989)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 2999)
@@ -38,5 +38,6 @@
 {
   float4 col: COLOR0;
-  float4 pos: COLOR1;
+  //float4 pos: COLOR1;
+  float2 pos: COLOR1;
   float4 norm: COLOR2;
 };
@@ -65,20 +66,38 @@
 
 
+// bilinear interpolation
+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;
+}
+
+
 pixel fragtex(fragin IN, 
 			  uniform sampler2D dirtTex,
 			  uniform float maxDepth,
 			  uniform sampler2D tex,
-			  uniform float3 currentPos)
+			  uniform float3 eyePos,
+			  uniform float3 bl,
+			  uniform float3 br,
+			  uniform float3 tl,
+			  uniform float3 tr)
 {
+	float4 texColor = tex2D(tex, IN.texCoord.xy);
+
+	// account for alpha blending
+	if (texColor.w < 0.5f) discard;
+
 	pixel pix;
-
-	float4 texColor = tex2D(tex, IN.texCoord.xy);
 
 	// save color in first render target
 	// hack: use combination of emmisive + diffuse (emmisive used as constant ambient term)
 	pix.col = (glstate.material.emission + glstate.material.diffuse) * texColor; 
-	
+
 	// save world position in second render target
-	pix.pos = IN.worldPos * maxDepth;
+	//pix.pos = IN.worldPos * maxDepth;
 	// save world space normal in third rt
 	pix.norm.xyz = IN.normal;
@@ -86,14 +105,18 @@
 	// store projection coordinates with positions (used for ssao)
 	pix.norm.w = IN.projPos.w;
-	// write the depth
-	pix.pos.w = IN.mypos.z / IN.mypos.w;
 
-	// account for alpha blending
-	if (pix.col.w < 0.5f)
-		discard;
+	const float4 projPos = IN.mypos / IN.mypos.w;
+	// store the projected depth
+	pix.pos.y = projPos.z;
+
+	float2 screenCoord = projPos.xy * 0.5f + 0.5f;
+	const float magView = length(Interpol(screenCoord, bl, br, tl, tr));
 
 	// hack: squeeze some information about ambient into the texture
 	//pix.col.w = glstate.material.emission.x;
-	pix.col.w = length(currentPos - IN.worldPos) * maxDepth;
+
+	// eye linear depth
+	pix.col.w = (length(eyePos - IN.worldPos.xyz) * maxDepth) / magView;
+	pix.pos.x = pix.col.x;
 
 	return pix;
@@ -101,5 +124,11 @@
 
 
-pixel frag(fragin IN, uniform float maxDepth, uniform float3 currentPos)
+pixel frag(fragin IN, 
+		   uniform float maxDepth, 
+		   uniform float3 eyePos,
+		   uniform float3 bl,
+		   uniform float3 br,
+		   uniform float3 tl,
+		   uniform float3 tr)
 {
 	pixel pix;
@@ -107,5 +136,5 @@
 	// hack: use comination of emmisive + diffuse (emmisive used as constant ambient term)
 	pix.col = glstate.material.diffuse + glstate.material.emission;
-	pix.pos = IN.worldPos * maxDepth;
+	//pix.pos = IN.worldPos * maxDepth;
 
 	pix.norm.xyz = IN.normal;
@@ -113,10 +142,16 @@
 	// store projection coordinates with positions (used for ssao)
 	pix.norm.w = IN.mypos.w;
-	// the projected depth
-	pix.pos.w = IN.mypos.z / IN.mypos.w;
-	
+
+	const float4 projPos = IN.mypos / IN.mypos.w;
+	// store the projected depth
+	pix.pos.y = projPos.z;
+
+	float2 screenCoord = projPos.xy * 0.5f + 0.5f;
+	const float magView = length(Interpol(screenCoord, bl, br, tl, tr));
+
 	// hack: squeeze some information about the ambient term into the target
 	//pix.col.w = glstate.material.emission.x;
-	pix.col.w = length(currentPos - IN.worldPos) * maxDepth;
+	pix.col.w = (length(eyePos - IN.worldPos.xyz) * maxDepth) / magView;
+	pix.pos.x = pix.col.x;
 
 	return pix;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg	(revision 2992)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg	(revision 2999)
@@ -130,5 +130,5 @@
 	float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset;
 
-	if (oldLogLum > 0)
+	if (oldLogLum > 1e-5f) // too hight log lum
 		OUT.col.w = lerp(oldLogLum, logLumScaled, 0.1f);
 	else
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 2997)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 2999)
@@ -48,13 +48,14 @@
 										float3 bl, float3 br, float3 tl, float3 tr)
 {
-#if 0
+#if 1
 	float eyeSpaceDepth = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL)).w;
-	float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
-	
-	float3 sample_position = eyePos - rotView * eyeSpaceDepth;
+	//float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
+	float3 rotView = Interpol(texcoord, bl, br, tl, tr);
+	
+	float3 samplePos = eyePos - rotView * eyeSpaceDepth;
 #else
-	float3 sample_position = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL)).xyz;
-#endif
-	return sample_position;
+	float3 samplePos = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL)).xyz;
+#endif
+	return samplePos;
 }
 
@@ -101,33 +102,40 @@
 		float2 texcoord = IN.texCoord.xy + offsetTransformed * AREA_SIZE * scaleFactor;
 
-		if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f))
-			++ numSamples;
-
-		float3 sample_position = ReconstructSamplePosition(eyePos, colors, texcoord, bl, br, tl, tr);
-
-		float3 vector_to_sample = sample_position - centerPosition.xyz;
-		const float length_to_sample = length(vector_to_sample);
-
-		float3 direction_to_sample = vector_to_sample / length_to_sample;
+		//if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f))++ numSamples;
+
+		// get sample world space position
+		float eyeSpaceDepth = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL)).w;
+		//float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
+		float3 rotView = Interpol(texcoord, bl, br, tl, tr);
+	
+		float3 samplePos = ReconstructSamplePosition(eyePos, colors, texcoord, bl, br, tl, tr);
+
+
+		///////
+		//-- compute contribution of current sample taking into account direction and angle
+
+		float3 dirSample = samplePos - centerPosition.xyz;
+		const float lengthSample = length(dirSample);
+
+		float3 nDirSample = dirSample / lengthSample;
 
 		// angle between current normal and direction to sample controls AO intensity.
-		const float cos_angle = max(dot(direction_to_sample, currentNormal), 0.0f);
+		const float cos_angle = 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 distance_intensity = 
-			(SAMPLE_INTENSITY * DISTANCE_SCALE) / (DISTANCE_SCALE + length_to_sample * length_to_sample);
+		const float intensity = 
+			(SAMPLE_INTENSITY * DISTANCE_SCALE) / (DISTANCE_SCALE + lengthSample * lengthSample);
 
 #if 0
 		// 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 view_correction = 1.0f + VIEW_CORRECTION_SCALE * (1.0f - dot(currentViewDir, currentNormal));
-		total_ao += cos_angle * distance_intensity * view_correction;
-#endif
-		total_ao += cos_angle * distance_intensity;
+		const float viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * (1.0f - dot(currentViewDir, currentNormal));
+		total_ao += cos_angle * intensity * viewCorrection;
+#endif
+		total_ao += cos_angle * intensity;
 	}
 
 	return float2(max(0.0f, 1.0f - total_ao), numSamples);
-	//return saturate(dot(currentViewDir, currentNormal));
 }
 
@@ -165,5 +173,5 @@
 	const float4 centerPosition = tex2D(positions, IN.texCoord.xy);
 
-#if 1	
+#if 0	
 	const float2 ao = ssao(IN, positions, noiseTexture, samples, normal, centerPosition, w, eyePos, bl, br, tl, tr);
 
@@ -197,9 +205,11 @@
 	float4 oldPos = mul(oldModelViewProj, realPos);
 
+	const float4 projPos = oldPos / oldPos.w;
+
 	// the current depth projected into the old frame
-	const float projDepth = oldPos.z / oldPos.w;
+	const float projDepth = projPos.z;
 
 	// fit from unit cube into 0 .. 1
-	float2 tex = (oldPos.xy / oldPos.w) * 0.5f + 0.5f;
+	float2 tex = (projPos.xy) * 0.5f + 0.5f;
 
 	// optain the sample from the last frame
@@ -212,9 +222,8 @@
 	const float depthDif = 1.0f - projDepth / oldDepth;
 
-
 	float newWeight;
 
 	// the number of valid samples in this frame
-	const float newNumSamples = ao.y;
+	//const float newNumSamples = ao.y;
 
 
@@ -224,5 +233,5 @@
 		(abs(depthDif) < 1e-4f) 
 		// if visibility changed in the surrounding area we have to recompute
-		&& (oldNumSamples > 0.8f * newNumSamples)
+		//&& (oldNumSamples > 0.8f * newNumSamples)
 		)
 	{
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/globillum.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/globillum.cg	(revision 2991)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/globillum.cg	(revision 2999)
@@ -65,5 +65,4 @@
 				   uniform float4 centerPosition,
 				   float w,
-				   // uniform float3 viewDir,
 				   uniform float3 eyePos,
 				   uniform float3 bl,
@@ -71,4 +70,5 @@
 				   uniform float3 tl,
 				   uniform float3 tr
+				   //, uniform float3 viewDir
 				   )
 {
@@ -102,11 +102,11 @@
 		float2 texcoord = IN.texCoord.xy + offsetTransformed * AREA_SIZE * w;
 
-		if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f))
-			++ numSamples;
+		//if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f)) ++ numSamples;
 
 		// reconstruct world space position from sample
 		float4 sample = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL));
 		const float eyeSpaceDepth = sample.w;
-		float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
+		//float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
+		float3 rotView = Interpol(texcoord, bl, br, tl, tr);
 		
 		const float3 sample_position = eyePos - rotView * eyeSpaceDepth;
@@ -213,11 +213,10 @@
 	const float oldAvgDepth = oldSsao.z;
 
-	if ((temporalCoherence > 0.0f) &&
+	if (//(temporalCoherence > 0.0f) &&
 		(tex.x >= 0.0f) && (tex.x < 1.0f) && 
 		(tex.y >= 0.0f) && (tex.y < 1.0f) && 
 		(abs(depthDif) < 1e-3f)
 		// check if something changed in the surrounding area
-		&& (oldNumSamples > 0.2 * gi.ao.y)
-		//&& (oldAvgDepth / newAvgDepth > 0.99)
+		//&& (oldNumSamples > 0.2 * gi.ao.y)
 		)
 	{
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2997)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2999)
@@ -274,6 +274,16 @@
 static CGparameter sMaxDepthParam;
 static CGparameter sMaxDepthParamTex;
-static CGparameter sCurrentPosParamTex;
-static CGparameter sCurrentPosParam;
+static CGparameter sEyePosParamTex;
+static CGparameter sEyePosParam;
+
+static CGparameter sTLParam;
+static CGparameter sTRParam;
+static CGparameter sBRParam;
+static CGparameter sBLParam;
+
+static CGparameter sTLParamTex;
+static CGparameter sTRParamTex;
+static CGparameter sBRParamTex;
+static CGparameter sBLParamTex;
 
 static Matrix4x4 oldViewProjMatrix;
@@ -457,12 +467,13 @@
 		exit(0);
 	}
-
+	
+#if 0
+
+	int merged = 0;
+
+	SceneEntity *oldEnt = NULL;
+
+	cout << "merging entities .. " << endl;
 	SceneEntityContainer::const_iterator sit, sit_end = sceneEntities.end();
-
-	int merged = 0;
-	
-	SceneEntity *oldEnt = NULL;
-#if 0
-	cout << "merging entities .. " << endl;
 
 	for (sit = sceneEntities.begin(); sit < sit_end; ++ sit)
@@ -498,4 +509,5 @@
 	cout << "merged " << merged << " of " << (int)sceneEntities.size() << " entities " << endl;
 #endif
+
 	// set far plane based on scene extent
 	farDist = 10.0f * Magnitude(bvh->GetBox().Diagonal());
@@ -599,8 +611,13 @@
 
 		sMaxDepthParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "maxDepth");
-		sCurrentPosParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "currentPos");
+		sEyePosParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "eyePos");
 		RenderState::sTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "tex");
 	
 		cgGLSetParameter1f(sMaxDepthParamTex, MAX_DEPTH_CONST / farDist);
+
+		sTLParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "tl"); 
+		sTRParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "tr"); 
+		sBRParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "br"); 
+		sBLParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "bl"); 
 	}
 	else
@@ -620,7 +637,12 @@
 
 		sMaxDepthParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "maxDepth");
-		sCurrentPosParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "currentPos");
+		sEyePosParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "eyePos");
 		
 		cgGLSetParameter1f(sMaxDepthParam, MAX_DEPTH_CONST / farDist);
+
+		sTLParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "tl"); 
+		sTRParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "tr"); 
+		sBRParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "br"); 
+		sBLParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "bl"); 
 	}
 	else
@@ -646,5 +668,6 @@
 	fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, ColorBufferObject::FILTER_NEAREST);
 	// the positions buffer
-	fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, ColorBufferObject::FILTER_NEAREST);
+	//fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, ColorBufferObject::FILTER_NEAREST);
+	fbo->AddColorBuffer(ColorBufferObject::BUFFER_LUMINANCE_ALPHA, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, ColorBufferObject::FILTER_NEAREST);
 	// the normals buffer
 	fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, ColorBufferObject::FILTER_NEAREST);
@@ -935,4 +958,17 @@
 
 
+static void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
+{
+	Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
+
+	camera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
+
+	bl = Normalize(nbl - fbl);
+	br = Normalize(nbr - fbr);
+	tl = Normalize(ntl - ftl);
+	tr = Normalize(ntr - ftr);
+}
+
+
 void InitDeferredRendering()
 {
@@ -952,6 +988,20 @@
 
 	const Vector3 pos = camera->GetPosition();
-	cgGLSetParameter3f(sCurrentPosParam, pos.x, pos.y, pos.z);
-	cgGLSetParameter3f(sCurrentPosParamTex, pos.x, pos.y, pos.z);
+
+	cgGLSetParameter3f(sEyePosParam, pos.x, pos.y, pos.z);
+	cgGLSetParameter3f(sEyePosParamTex, pos.x, pos.y, pos.z);
+
+	Vector3 tl, tr, bl, br;
+	ComputeViewVectors(tl, tr, bl, br);
+
+	cgGLSetParameter3f(sBLParam, bl.x, bl.y, bl.z);
+	cgGLSetParameter3f(sBRParam, br.x, br.y, br.z);
+	cgGLSetParameter3f(sTLParam, tl.x, tl.y, tl.z);
+	cgGLSetParameter3f(sTRParam, tr.x, tr.y, tr.z);
+
+	cgGLSetParameter3f(sBLParamTex, bl.x, bl.y, bl.z);
+	cgGLSetParameter3f(sBRParamTex, br.x, br.y, br.z);
+	cgGLSetParameter3f(sTLParamTex, tl.x, tl.y, tl.z);
+	cgGLSetParameter3f(sTRParamTex, tr.x, tr.y, tr.z);
 
 	// draw to 3 color buffers
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2966)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2999)
@@ -15,5 +15,5 @@
 public:
 
-	enum FORMAT { BUFFER_UBYTE, BUFFER_FLOAT_16, BUFFER_FLOAT_32 };
+	enum FORMAT { BUFFER_UBYTE, BUFFER_FLOAT_16, BUFFER_FLOAT_32, BUFFER_LUMINANCE_ALPHA };
 	enum WRAP_TYPE { WRAP_REPEAT, WRAP_CLAMP_TO_EDGE };
 	enum FILTER_TYPE { FILTER_NEAREST, FILTER_LINEAR };
