Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 2964)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 2966)
@@ -1,20 +1,20 @@
 #ifndef __SHADERENV_H
 #define __SHADERENV_H
+
+
+////////////
+//-- ssao + gi parameters
 
 #define NUM_SAMPLES 8
 //#define NUM_SAMPLES 16
 
-
 // for linear falloff
 //#define SAMPLE_INTENSITY 500.0f
-//#define SAMPLE_INTENSITY 40.0f
 
 // for quadratic falloff
 #define SAMPLE_INTENSITY 0.32f
 //#define SAMPLE_INTENSITY 0.85f
-//#define SAMPLE_INTENSITY 5.0f
 
 //#define AREA_SIZE 15e-1f
-//#define AREA_SIZE 25e-1f
 #define AREA_SIZE 8e-1f
 
@@ -24,5 +24,4 @@
 //#define DISTANCE_SCALE 1e-4f
 #define DISTANCE_SCALE 1e-6f
-//#define DISTANCE_SCALE 1e-8f
 
 #define ILLUM_INTENSITY 5e-1f;
@@ -32,3 +31,18 @@
 #define GI_MIPMAP_LEVEL 2
 
+
+/////////
+//-- tone mapping
+
+//#define MIDDLE_GRAY 0.36f
+#define MIDDLE_GRAY 0.18f
+
+
+/////////
+//-- shadowing
+
+#define NUM_PCF_TABS 16
+
+
+
 #endif // __SHADERENV_H
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2965)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2966)
@@ -1,2 +1,5 @@
+#include "../shaderenv.h"
+
+
 struct fragment
 {
@@ -13,5 +16,26 @@
 };
 
-#define NUM_SAMPLES 16
+
+
+float3 ToneMap(const float imageKey, float3 color)
+{
+	float3 outCol;
+	const float pixLum = 0.2125f * color.x + 0.7154f * color.y + 0.0721f * color.z;
+	
+	// adjust to middle gray
+	const float lum = MIDDLE_GRAY * pixLum / imageKey;
+	 
+    // map to range
+	const float scaledLum = lum / (1.0f + lum);
+
+    /*outCol *= MIDDLE_GRAY / (vLum + 1e-3f);
+    outCol *= (1.0f + vColor / LUM_WHITE);
+	outCol /= (1.0f + vColor);*/
+	
+	outCol = color / scaledLum;
+	//vColor.rgb += 0.6f * vBloom;
+	
+	return outCol;
+}
 
 
@@ -40,5 +64,5 @@
 	float3 light2 = normalize(lightDir2.xyz);
 	float diffuseLight2 = saturate(dot(normal, light2));
-*/
+	*/
 	// diffuse intensity
 	const float angle = saturate(dot(normal, lightDir)); 
@@ -62,5 +86,6 @@
 		   uniform sampler2D positions,
 		   uniform sampler2D normals,
-		   uniform float3 lightDir
+		   uniform float3 lightDir,
+		   uniform float imageKey
 		   )
 {
@@ -90,5 +115,5 @@
 					 uniform float2 lightSpacePos,
 					 uniform float depth,
-					 uniform float2 samples[NUM_SAMPLES],
+					 uniform float2 samples[NUM_PCF_TABS],
 					 uniform sampler2D noiseTexture
 					 )
@@ -99,5 +124,5 @@
 	float total_d = 0.0;
 	
-	for (int i = 0; i < NUM_SAMPLES; ++ i) 
+	for (int i = 0; i < NUM_PCF_TABS; ++ i) 
 	{
 		const float2 offset = samples[i];
@@ -135,6 +160,7 @@
 				  uniform float sampleWidth,
 				  uniform sampler2D noiseTexture,
-				  uniform float2 samples[NUM_SAMPLES],
-				  uniform float3 lightDir
+				  uniform float2 samples[NUM_PCF_TABS],
+				  uniform float3 lightDir,
+				  uniform float imageKey
 				  )
 {
@@ -181,4 +207,6 @@
 	OUT.color = (emmisive < 0.95) ? (ambient + diffuse) * color : color;
 
+	OUT.color.xyz = ToneMap(imageKey, OUT.color.xyz);
+
 	// also write out depth component
 	OUT.color.w = color.w;
@@ -187,21 +215,2 @@
 }
 
-
-/*float4 FinalPass( SkyboxVS_Output Input ) : COLOR
-{
-	float4 vColor = tex2D( s0, Input.Tex );
-	float3 vBloom = tex2D( s1, Input.Tex );
-
-	float vLum = g_fImageKey;
-	vColor.rgb = vColor; 
-	 
-    // Tone mapping
-    vColor.rgb *= g_fMiddleGray /(vLum + 0.001f);
-    vColor.rgb *= (1.0f + vColor/LUM_WHITE);
-	vColor.rgb /= (1.0f + vColor);
-	
-	vColor.rgb += 0.6f * vBloom;
-	vColor.a = 1.0f;
-	
-	return vColor;
-}*/
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.cpp	(revision 2965)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.cpp	(revision 2966)
@@ -6,94 +6,54 @@
 {
 
-ToneMapper::ToneMapper(): mImageKey(.0f), mPreviousImageKey(.0f), mCurrentImageKey(.0f)
+
+ToneMapper::ToneMapper()
 {
 }
 
 
-bool ToneMapper::CalcLuminance(ColorBufferObject *colorBuffer)
+float ToneMapper::CalcImageKey(ColorBufferObject *colorBuffer) const
 {
-	int i = 0, j = 0;
-	float Rfloat, Gfloat, Bfloat;
+	float totalLum = 0;
 
-	int pixRGBE;
-
-	float pixLum = 0; 
-	float totalLum = 0;
-	float pixNum = 0;
-	
+	// we assume that we have a floating point rgba texture
 	float *pixels = (float *)colorBuffer->ReadTexture();
 
-	/*
-	V_RETURN( pd3dDevice->GetRenderTargetData( pSourceRenderTarget, pPixelData ) );
-	 
-	D3DSURFACE_DESC descSrc;
-    pPixelData->GetDesc( &descSrc );
-	
-	number_of_pixels = (float)(descSrc.Height * descSrc.Width);
+	const int w = colorBuffer->GetHeight();
+	const int h = colorBuffer->GetWidth();
 
-	// Lock the source texture for reading
-    D3DLOCKED_RECT rcSrc;
-    V_RETURN( pPixelData->LockRect( &rcSrc, NULL, D3DLOCK_READONLY ) );
-	
-	// Location of texture data
-	D3DXFLOAT16* pSourcePixels = (D3DXFLOAT16*)rcSrc.pBits;
+	// Get full scene luminance
+	for (int i = 0; i < h; ++ i)
+	{
+		for (int j = 0; j < w; ++ j)
+		{
+			const int idx = i * w + j;
 
-	int localwidth = descSrc.Width;
-	int localheight = descSrc.Height; 	
-	g_start = g_myTimer.GetTime();
-	
-	// Get full scene luminance
-	for( i = 0; i < localheight; i++ )
-	{
-		for( j = 0; j < localwidth; j++ )
-		{
-			RGBEpixel = i * (localwidth) + j;
-			Rfloat =(float)pSourcePixels[4*RGBEpixel + 0]/255;
-			Gfloat =(float)pSourcePixels[4*RGBEpixel + 1]/255;
-			Bfloat =(float)pSourcePixels[4*RGBEpixel + 2]/255;
+			float r = pixels[4 * idx + 0];
+			float g = pixels[4 * idx + 1];
+			float b = pixels[4 * idx + 2];
 
-			PixelLuminance = 0.2125f * Rfloat + 0.7154f * Gfloat + 0.0721f * Bfloat;
+			float pixLum = 0.2125f * r + 0.7154f * g + 0.0721f * b;
 
-			TotalLuminance += (PixelLuminance + 0.001f);
+			totalLum += log(pixLum + 1e-3f);
 		}
 	}
 
-	g_stop = g_myTimer.GetTime();
+	const float key = exp(totalLum) / (float)(w * h);
 
-	g_dLumCalcTime = (double)g_stop - (double)g_start;	
+	static float previousKey = key;
 
-	pPixelData->UnlockRect();	
+	//float delta = imageKey - mPreviousImageKey;
+	// Constaint change for temporal coherence
+	//const float maxChange = 5-e2f;
+	//Clamp(delta, -maxChange, maxChange);
+
+	const float factor = 0.5f;
+
+	const float imageKey = key * factor + previousKey * (1.0f - factor);
+	previousKey = imageKey;
 	
+	delete [] pixels;
 
-	g_fCurrentImageKey = (1/number_of_pixels) * TotalLuminance;
-
-	if(g_firstrun)
-	{
-		g_fPreviousImageKey = g_fCurrentImageKey;
-		g_firstrun = !g_firstrun;
-	}
-
-	float diff = (g_fCurrentImageKey - g_fPreviousImageKey);
-
-	// Constrain the luminance change to be more realistic
-	if (diff > 0.05f)
-	{
-		g_fImageKey = g_fPreviousImageKey + 0.05f;
-		g_fPreviousImageKey = g_fImageKey;
-	}
-	else if (diff < -0.05f)
-	{
-		g_fImageKey = g_fPreviousImageKey - 0.05f;
-		g_fPreviousImageKey = g_fImageKey;
-	}
-	else
-	{
-		g_fImageKey = g_fCurrentImageKey;
-		g_fPreviousImageKey = g_fImageKey;
-	}
-	
-	return S_OK;
-	*/
-	return true;
+	return imageKey;
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.h	(revision 2965)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ToneMapper.h	(revision 2966)
@@ -16,14 +16,7 @@
 	
 	ToneMapper();
-	/** Caculates scene luminance.
+	/** Caculates average log lumincance.
 	*/
-	bool CalcLuminance(ColorBufferObject *colorBuffer);
-
-
-protected:
-
-	float mImageKey;
-	float mPreviousImageKey;
-	float mCurrentImageKey;
+	float CalcImageKey(ColorBufferObject *colorBuffer) const;
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 2965)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 2966)
@@ -9,4 +9,5 @@
 #include "ShadowMapping.h"
 #include "Light.h"
+#include "ToneMapper.h"
 
 
@@ -96,4 +97,6 @@
 static CGparameter sLightDirShadowParam;
 
+static CGparameter sImageKeyParam;
+static CGparameter sImageKeyShadowParam;
 
 //#define USE_3D_SSAO
@@ -108,5 +111,7 @@
 static Sample2 samples2[NUM_SAMPLES];
 #endif
-Sample2 pcfSamples[16];
+
+// number of pcf tabs
+Sample2 pcfSamples[NUM_PCF_TABS];
 
 static int colorBufferIdx = 0;
@@ -281,4 +286,6 @@
 		sNormalsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
 		sLightDirParam = cgGetNamedParameter(sCgDeferredProgram, "lightDir");
+
+		sImageKeyParam = cgGetNamedParameter(sCgDeferredProgram, "imageKey");
 	}
 	else
@@ -433,8 +440,10 @@
 		sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
 
-		PoissonDiscSampleGenerator2 poisson(16, 1.0f);
+		sImageKeyShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "imageKey");
+
+		PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
 		poisson.Generate((float *)pcfSamples);
 
-		cgGLSetParameterArray2f(sSamplesShadowParam, 0, 16, (const float *)pcfSamples);
+		cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
 	}
 	else
@@ -699,4 +708,6 @@
 void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
 {
+	const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(0));
+
 	GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
 	GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
@@ -725,4 +736,6 @@
 	Vector3 lightDir = -light->GetDirection();
 	cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
+
+	cgGLSetParameter1f(sImageKeyParam, imageKey);
 
 	glColor3f(1.0f, 1.0f, 1.0f);
@@ -965,4 +978,6 @@
 									   ShadowMap *shadowMap)
 {
+	const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(0));
+
 	GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
 
@@ -1009,4 +1024,6 @@
 	cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
 
+	// the average log luminance for tone mapping
+	cgGLSetParameter1f(sImageKeyShadowParam, imageKey);
 
 	glColor3f(1.0f, 1.0f, 1.0f);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2965)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2966)
@@ -41,10 +41,14 @@
 	~ColorBufferObject();
 
-	unsigned int GetTexture() const { return mTexId; }
+	inline unsigned int GetTexture() const { return mTexId; }
 
+	inline int GetWidth() { return mWidth; }
+
+	inline int GetHeight() { return mHeight; }
 	/** Returns texture data.
 	*/
 	void *ReadTexture() const;
 
+	
 
 protected:
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 2961)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 2966)
@@ -293,6 +293,6 @@
 
 
-Real Random(Real max);
-int Random(int max);
+Real Random(Real maxValue);
+int Random(int maxValue);
 void Randomize();
 void Randomize(unsigned int seed);
@@ -310,10 +310,11 @@
 }
   
-void InitTiming();
-long GetTime();
-long GetRealTime();
-Real TimeDiff(long t1, long t2);
-char *TimeString();
-
+inline Real Clamp(float x, float minVal, float maxVal)
+{
+	if (x < minVal) return minVal;
+	if (x > maxVal) return maxVal;
+
+	return x;
+}
 
 
