Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp	(revision 2954)
@@ -65,5 +65,5 @@
 void RenderTraverser::EnqueueNode(BvhNode *node)
 {
-	mBvh->UpdateMinDistance(node);
+	mBvh->UpdateDistance(node);
 	mDistanceQueue.push(node);
 }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 2930)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 2954)
@@ -27,4 +27,5 @@
 
 #define ILLUM_INTENSITY 5e-1f;
+//#define ILLUM_INTENSITY 9e-1f;
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2952)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2954)
@@ -36,6 +36,4 @@
 			 float3 lightDir)
 {
-	const float diffuseLight = saturate(dot(normal, lightDir));
-	
 	/*
 	float4 lightDir2 = float4(-0.5f, 0.5f, 0.4f, 0.0f);
@@ -43,10 +41,13 @@
 	float diffuseLight2 = saturate(dot(normal, light2));
 */
-	float diffuse = diffuseLight;// + diffuseLight2;
+	// diffuse intensity
+	const float angle = saturate(dot(normal, lightDir)); 
+	
+	float4 lightDiffuse = glstate.light[0].diffuse;
+	float4 diffuse = angle * lightDiffuse;
 
 	// global ambient
-	const float4 ambient = 0.25f;
-	//const float4 ambient = 0.0f;
-
+	const float4 ambient = glstate.light[0].ambient;
+	
 	return (ambient + diffuse) * color * (1.0f - amb) + amb * color;
 }
@@ -76,5 +77,4 @@
 	float4 col = shade(IN, color, position, normal, amb, lightDir);
 	
-	//OUT.color = float4(1.0f);
 	OUT.color = col;
 	OUT.color.w = color.w;
@@ -93,6 +93,9 @@
 					 )
 {
+	//float shadowDepth = tex2D(shadowMap, lightSpacePos).x;
+	//return step(depth, shadowDepth);
+
 	float total_d = 0.0;
-
+	
 	for (int i = 0; i < NUM_SAMPLES; ++ i) 
 	{
@@ -120,93 +123,4 @@
 	return total_d;
 }
-
-
-#if 0
-/** The mrt shader for standard rendering
-*/
-pixel main_shadow(fragment IN, 
-				  uniform sampler2D colors,
-				  uniform sampler2D positions,
-				  uniform sampler2D normals,		   
-				  uniform sampler2D shadowMap,
-				  uniform float4x4 shadowMatrix,
-				  uniform float maxDepth,
-				  uniform float sampleWidth,
-				  uniform float3 lightDir
-				  )
-{
-	pixel OUT;
-
-	float4 norm = tex2D(normals, IN.texCoord.xy);
-	float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0));
-	float4 position = tex2D(positions, IN.texCoord.xy);
-
-
-	// an ambient color term
-	float amb = norm.w;
-
-	float3 normal = normalize(norm.xyz);
-	float4 col = shade(IN, color, position, normal, amb);
-	
-	position *= maxDepth;
-	position.w = 1.0f;
-	
-	float4 lightSpacePos = mul(shadowMatrix, position);
-	lightSpacePos /= lightSpacePos.w;
-
-	OUT.color = col;
-
-	float shadowDepth[9];
-
-	float w = sampleWidth;
-
-	// pcf sampling using 3 x 3 tab
-	shadowDepth[0] = tex2D(shadowMap, lightSpacePos.xy).x;
-	
-	shadowDepth[1] = tex2D(shadowMap, lightSpacePos.xy + float2( w,  w)).x;
-	shadowDepth[2] = tex2D(shadowMap, lightSpacePos.xy + float2( w, -w)).x;
-	shadowDepth[3] = tex2D(shadowMap, lightSpacePos.xy + float2(-w, -w)).x;
-	shadowDepth[4] = tex2D(shadowMap, lightSpacePos.xy + float2(-w,  w)).x;
-
-	shadowDepth[5] = tex2D(shadowMap, lightSpacePos.xy + float2( w,  0)).x;
-	shadowDepth[6] = tex2D(shadowMap, lightSpacePos.xy + float2( 0,  w)).x;
-	shadowDepth[7] = tex2D(shadowMap, lightSpacePos.xy + float2(-w,  0)).x;
-	shadowDepth[8] = tex2D(shadowMap, lightSpacePos.xy + float2( 0, -w)).x;
-
-	
-	float depth = lightSpacePos.z;
-
-	float d = 0.0f;
-
-	for (int i = 0; i < 9; ++ i)
-	{
-		d += step(shadowDepth[i], depth);
-	}
-
-	d /= 9.0f;
-	
-	if (amb < 0.9f) // hack: prevent shadowing the sky	
-	{
-		// base lighting
-		const float x = 0.4f;
-		OUT.color *= x + (1.0f - x) * (1.0f - d);
-	}
-	
-	/*
-	// hard shadows
-	float shadowDepth = tex2D(shadowMap, lightSpacePos.xy).x;
-
-	if ((amb < 0.9f) && // hack: prevent shadowing the sky	
-		(lightSpacePos.z > shadowDepth))
-	{
-		OUT.color *= 0.1f;
-	}*/
-
-	OUT.color.w = color.w;
-
-	return OUT;
-}
-
-#else
 
 
@@ -237,5 +151,9 @@
 	// diffuse intensity
 	const float angle = saturate(dot(normal, lightDir)); 
-	float diffuse = angle;
+	//float4 lightDiffuse = float4(1.0f, 1.0f, 0.9f, 1.0f);
+	float4 lightDiffuse = glstate.light[0].diffuse;
+	//float4(1.0f, 1.0f, 0.9f, 1.0f);
+
+	float4 diffuse = lightDiffuse * angle;
 
 	// calc diffuse illumination + shadow term
@@ -256,5 +174,6 @@
 
 	// global ambient
-	const float4 ambient = 0.25f;
+	//const float4 ambient = 0.25f;
+	const float4 ambient = glstate.light[0].ambient;
 	
 	// base lighting
@@ -266,4 +185,2 @@
 	return OUT;
 }
-
-#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h	(revision 2951)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h	(revision 2954)
@@ -524,9 +524,9 @@
 	*/
 	void InitFrame(Camera *camera);
-	/** Stores the orthogonal distance from the viewpoint 
-		to the nearest bounding box vertex with the node. 
+	/** Stores the orthogonal distance from the viewpoint to a point on the node.
+		We choose the the nearest bounding box vertex . 
 		Note that negative values can appear because culling is done only afterwards
 	*/
-	void UpdateMinDistance(BvhNode *node) const;
+	void UpdateDistance(BvhNode *node) const;
 	/** Returns the maximum distance from the near plane to this node.
 	*/
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 2930)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 2954)
@@ -172,4 +172,5 @@
 void QuadraticDiscSampleGenerator2::Generate(float *samples) const
 {
+#if 0
 	float r[2];
 	Sample2 *s = (Sample2 *)samples;
@@ -185,7 +186,21 @@
 		s[i].x = mRadius * r[1] * sin(2.0f * M_PI * r[0]);
 		s[i].y = mRadius * r[1] * cos(2.0f * M_PI * r[0]);
-
-		//s[i].x = mRadius * r[1] * r[1] * sin(2.0f * M_PI * r[0]);
-		//s[i].y = mRadius * r[1] * r[1] * cos(2.0f * M_PI * r[0]);
-	}
-}
+	}
+#else
+
+	PoissonDiscSampleGenerator2 poisson(mNumSamples, 1.0f);
+	poisson.Generate(samples);
+
+	Sample2 *s = (Sample2 *)samples;
+
+	// multiply with lenght to get quadratic dependence on the distance
+	for (int i = 0; i < mNumSamples; ++ i)
+	{
+		Sample2 spl = s[i];
+
+		float len = sqrt(spl.x * spl.x + spl.y * spl.y);
+		spl.x *= len * mRadius;
+		spl.y *= len * mRadius;
+	}
+#endif
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 2954)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 2954)
@@ -0,0 +1,182 @@
+#include "SkyPreetham.h"
+//#include <rendering/effect/FEffect.h>
+//#include <rendering/FVertexbuffer.h>
+
+
+
+
+using namespace CHCDemoEngine;
+
+
+SkyPreetham::SkyPreetham():
+	mEffect(NULL),
+	mTurbidity(4.0),
+	mSunEffect(NULL),
+	mSunTexture(NULL),
+	mSunQuad(NULL)
+{
+	mEffect = D().getScene().getEffect("../effects/sky_preetham.fx");
+
+	mVertexBuffer = D().getScene().getVertexBuffer("../models/sky.vbo");
+
+	mSunEffect = D().getScene().getEffect("../effects/sky_sun.fx");
+	mSunTexture = D().getScene().getTexture2D("../textures/sky_sun.png");
+
+	createSunQuad();
+}
+
+
+SkyPreetham::~SkyPreetham()
+{
+	FDelete(mSunQuad);
+}
+
+
+
+void SkyPreetham::Compute()
+{
+
+	FVector2 sun_theta;
+	FVector3 l_dir = D().getScene().getLight().getDirection();
+	mTurbidity = D().getScene().getLight().getTurbitity();
+
+	sun_theta.x = acos(l_dir.y);
+	sun_theta.y = cos( sun_theta.x ) * cos( sun_theta.x );
+
+
+#define CBQ(X)		((X) * (X) * (X))
+#define SQR(X)		((X) * (X))
+
+	const double PI = (double)3.1415926535897932;
+
+	FVector3 zenithColor;
+
+	zenithColor.x  = ( 0.00165f * CBQ(sun_theta.x) - 0.00374f  * SQR(sun_theta.x) +
+		0.00208f *       sun_theta.x  +     0.0f) * SQR(mTurbidity) +
+		(-0.02902f * CBQ(sun_theta.x) + 0.06377f  * SQR(sun_theta.x) -
+		0.03202f *       sun_theta.x  + 0.00394f) *        mTurbidity +
+		( 0.11693f * CBQ(sun_theta.x) - 0.21196f  * SQR(sun_theta.x) +
+		0.06052f *       sun_theta.x + 0.25885f);
+
+	zenithColor.y  = ( 0.00275f * CBQ(sun_theta.x) - 0.00610f  * SQR(sun_theta.x) +
+		0.00316f *       sun_theta.x +     0.0f) * SQR(mTurbidity) +
+		(-0.04214f * CBQ(sun_theta.x) + 0.08970f  * SQR(sun_theta.x) -
+		0.04153f *       sun_theta.x  + 0.00515f) *        mTurbidity  +
+		( 0.15346f * CBQ(sun_theta.x) - 0.26756f  * SQR(sun_theta.x) +
+		0.06669f *       sun_theta.x  + 0.26688f);
+
+	zenithColor.z  = (float)((4.0453f * mTurbidity - 4.9710f) *
+		tan((4.0f / 9.0f - mTurbidity / 120.0f) * (PI - 2.0f * sun_theta.x)) -
+		0.2155f * mTurbidity + 2.4192f);
+	// convert kcd/m² to cd/m²
+	zenithColor.z *= 1000;
+
+	double ABCDE_x[5], ABCDE_y[5], ABCDE_Y[5];
+
+	ABCDE_x[0] = -0.01925 * mTurbidity   - 0.25922;
+	ABCDE_x[1] = -0.06651 * mTurbidity   + 0.00081;
+	ABCDE_x[2] = -0.00041 * mTurbidity   + 0.21247;
+	ABCDE_x[3] = -0.06409 * mTurbidity   - 0.89887;
+	ABCDE_x[4] = -0.00325 * mTurbidity   + 0.04517;
+
+	ABCDE_y[0] = -0.01669 * mTurbidity  - 0.26078;
+	ABCDE_y[1] = -0.09495 * mTurbidity   + 0.00921;
+	ABCDE_y[2] = -0.00792 * mTurbidity   + 0.21023;
+	ABCDE_y[3] = -0.04405 * mTurbidity   - 1.65369;
+	ABCDE_y[4] = -0.01092 * mTurbidity   + 0.05291;
+
+	ABCDE_Y[0] =  0.17872 * mTurbidity   - 1.46303;
+	ABCDE_Y[1] = -0.35540 * mTurbidity   + 0.42749;
+	ABCDE_Y[2] = -0.02266 * mTurbidity   + 5.32505;
+	ABCDE_Y[3] =  0.12064 * mTurbidity   - 2.57705;
+	ABCDE_Y[4] = -0.06696 * mTurbidity   + 0.37027;
+
+
+	F().getRenderDevice().setDefaultDepthStencilMode(FRenderDevice::DEPTHSTENCIL_TEST_NO_OVERWRITE);
+
+	// Move skybox with camera.
+	mPosition = D().getScene().getCamera().getPosition();
+
+	mPosition.y -= 2.0;
+
+	setTransform();
+
+	mEffect->setVariableVector3("LightDirection", D().getScene().getLight().getDirection());
+	mEffect->setVariableVector2("ThetaSun", sun_theta);
+	mEffect->setVariableVector3("ZenithColor", zenithColor);
+	mEffect->setVariableVector3("AColor",FVector3((FFloat)ABCDE_x[0], (FFloat)ABCDE_y[0], (FFloat)ABCDE_Y[0]));
+	mEffect->setVariableVector3("BColor",FVector3((FFloat)ABCDE_x[1], (FFloat)ABCDE_y[1], (FFloat)ABCDE_Y[1]));
+	mEffect->setVariableVector3("CColor",FVector3((FFloat)ABCDE_x[2], (FFloat)ABCDE_y[2], (FFloat)ABCDE_Y[2]));
+	mEffect->setVariableVector3("DColor",FVector3((FFloat)ABCDE_x[3], (FFloat)ABCDE_y[3], (FFloat)ABCDE_Y[3]));
+	mEffect->setVariableVector3("EColor",FVector3((FFloat)ABCDE_x[4], (FFloat)ABCDE_y[4], (FFloat)ABCDE_Y[4]));
+
+
+	mEffect->activate();
+
+	F().getRenderDevice().setDefaultPolygonMode(true, FRenderDevice::CULL_NONE);
+
+	// Render sky dome.
+	mVertexBuffer->render();
+
+	// Render additively blended sun disc.
+	renderSunDisk();
+
+	F().getRenderDevice().setDefaultPolygonMode(true, FRenderDevice::CULL_BACKFACES);
+
+
+	F().getRenderDevice().setDefaultDepthStencilMode(FRenderDevice::DEPTHSTENCIL_TEST_AND_OVERWRITE);
+}
+
+
+void SkyPreetham::renderSunDisk()
+{
+	F().getRenderDevice().setDefaultBlendingMode(FRenderDevice::BLENDING_ADDITIVE);
+
+	// Set world matrix to sun disc position.
+	FMatrix4 sunposition;
+	sunposition.translate(D().getScene().getCamera().getPosition());
+	sunposition.rotateAroundY(-D().getScene().getLight().getHorizontalOrientation() + 90.0f);
+	sunposition.rotateAroundX(-D().getScene().getLight().getVerticalOrientation());
+	F().getRenderDevice().getTransform().setWorldMatrix(sunposition);
+
+	FVector3 lightdirection = D().getScene().getLight().getDirection();
+	FFloat size = 0.5f + (1.0f - lightdirection.y) * 0.5f;
+
+	mSunEffect->setVariableVector3("LightDiffuseColor", D().getScene().getLight().getDiffuseColor());
+	mSunEffect->setVariableFloat("SunSize", size);
+	mSunEffect->setVariableTexture2D("SunTexture", mSunTexture);
+
+	mSunEffect->activate();
+	
+	mSunQuad->render();
+
+	mSunEffect->deactivate();
+
+	F().getRenderDevice().setDefaultBlendingMode(FRenderDevice::BLENDING_NONE);
+}
+
+
+void SkyPreetham::createSunQuad()
+{
+	mSunQuad = new FVertexBuffer();
+	mSunQuad->setupPrimitiveType(FVertexBuffer::PRIMITIVES_TRIANGLES);
+	mSunQuad->setupVertexFormat(3, 0, 0, true);
+	mSunQuad->setupTexCoordSet(0, 2);
+	mSunQuad->setVertexBufferSize(4, 6);
+
+	mSunQuad->setVertexPosition(0, FVector3(-0.1f,  0.1f, 1.0f));
+	mSunQuad->setVertexPosition(1, FVector3( 0.1f,  0.1f, 1.0f));
+	mSunQuad->setVertexPosition(2, FVector3(-0.1f, -0.1f, 1.0f));
+	mSunQuad->setVertexPosition(3, FVector3( 0.1f, -0.1f, 1.0f));
+	mSunQuad->setVertexTexCoord(0, 0, FVector2(0.0f, 0.0f));
+	mSunQuad->setVertexTexCoord(1, 0, FVector2(1.0f, 0.0f));
+	mSunQuad->setVertexTexCoord(2, 0, FVector2(0.0f, 1.0f));
+	mSunQuad->setVertexTexCoord(3, 0, FVector2(1.0f, 1.0f));
+
+	mSunQuad->setIndex(0, 0);
+	mSunQuad->setIndex(1, 1);
+	mSunQuad->setIndex(2, 2);
+	mSunQuad->setIndex(3, 2);
+	mSunQuad->setIndex(4, 1);
+	mSunQuad->setIndex(5, 3);
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.cpp	(revision 2954)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.cpp	(revision 2954)
@@ -0,0 +1,121 @@
+#include "SunColor.h"
+#include "Vector3.h"
+#include "common.h"
+
+
+using namespace CHCDemoEngine;
+
+
+inline float CBQ(float x)
+{
+	return x * x * x;
+}
+
+
+inline float SQR(float x)
+{
+	return x * x ;
+}
+
+
+void SunColor::Compute(const Vector3 &sunDir, Vector3 &ambient, Vector3 &diffuse) const
+{
+	const float turbidity = 3.0f;
+
+	// sunDir is sun direction
+	// ambient color :shadow color
+	// diffuse color :sun color
+
+	float sun_theta[2];
+	
+	sun_theta[0] = acos(sunDir.y);
+
+	const float cos_theta =  cos(sun_theta[0]);
+	sun_theta[1] = cos_theta * cos_theta;
+
+	Vector3 zenithColor;
+
+	zenithColor.x = ( 0.00165f * CBQ(sun_theta[0]) - 0.00374f * SQR(sun_theta[0]) + 0.00208f * sun_theta[0] + 0.0f)     * SQR(turbidity) +	
+				    (-0.02902f * CBQ(sun_theta[0]) + 0.06377f * SQR(sun_theta[0]) - 0.03202f * sun_theta[0] + 0.00394f) * turbidity +
+					( 0.11693f * CBQ(sun_theta[0]) - 0.21196f * SQR(sun_theta[0]) + 0.06052f * sun_theta[0] + 0.25885f);
+
+	zenithColor.y = (0.00275f  * CBQ(sun_theta[0]) - 0.00610f * SQR(sun_theta[0]) + 0.00316f * sun_theta[0] + 0.0f)     * SQR(turbidity) +
+	                (-0.04214f * CBQ(sun_theta[0]) + 0.08970f * SQR(sun_theta[0]) - 0.04153f * sun_theta[0] + 0.00515f) * turbidity +
+		            ( 0.15346f * CBQ(sun_theta[0]) - 0.26756f * SQR(sun_theta[0]) + 0.06669f * sun_theta[0] + 0.26688f);
+	
+	zenithColor.z  = (float)((4.0453f * turbidity - 4.9710f) *	tan((4.0f / 9.0f - turbidity / 120.0f) * 
+							 (M_PI - 2.0f * sun_theta[0])) - 0.2155f * turbidity + 2.4192f);
+
+	// convert kcd/m² to cd/m²
+	zenithColor.z *= 1000.0f;
+
+	ambient = zenithColor;
+
+	Vector3 zenith_XYZ;                                                                                             
+
+	zenith_XYZ.x = (ambient.x / ambient.y) * ambient.z;                                                                        
+	zenith_XYZ.y = ambient.z;                                                                                          
+	zenith_XYZ.z = ((1.0f - ambient.x - ambient.y) / ambient.y) * ambient.z;                                                                
+
+	ambient.x =  3.240479f * zenith_XYZ.x - 1.537150f * zenith_XYZ.y - 0.498535f * zenith_XYZ.z;
+	ambient.y = -0.969256f * zenith_XYZ.x + 1.875992f * zenith_XYZ.y + 0.041556f * zenith_XYZ.z;	
+	ambient.z =  0.055648f * zenith_XYZ.x - 0.204043f * zenith_XYZ.y + 1.057311f * zenith_XYZ.z;
+
+	// downscale ambient color
+	ambient *= 5e-5f;
+
+	// simulate the sun intensity by modulating the ambient term.
+	ambient *= (1.0f - 0.90f * DotProd(sunDir, Vector3(0, 1, 0)));
+	ambient += Vector3(0.2f);
+
+	float ABCDE_x[5], ABCDE_y[5], ABCDE_Y[5];
+
+	ABCDE_x[0] = -0.01925f * turbidity   - 0.25922f;
+	ABCDE_x[1] = -0.06651f * turbidity   + 0.00081f;
+	ABCDE_x[2] = -0.00041f * turbidity   + 0.21247f;
+	ABCDE_x[3] = -0.06409f * turbidity   - 0.89887f;
+	ABCDE_x[4] = -0.00325f * turbidity   + 0.04517f;
+
+	ABCDE_y[0] = -0.01669f * turbidity  - 0.26078f;
+	ABCDE_y[1] = -0.09495f * turbidity   + 0.00921f;
+	ABCDE_y[2] = -0.00792f * turbidity   + 0.21023f;
+	ABCDE_y[3] = -0.04405f * turbidity   - 1.65369f;
+	ABCDE_y[4] = -0.01092f * turbidity   + 0.05291f;
+
+	ABCDE_Y[0] =  0.17872f * turbidity   - 1.46303f;
+	ABCDE_Y[1] = -0.35540f * turbidity   + 0.42749f;
+	ABCDE_Y[2] = -0.02266f * turbidity   + 5.32505f;
+	ABCDE_Y[3] =  0.12064f * turbidity   - 2.57705f;
+	ABCDE_Y[4] = -0.06696f * turbidity   + 0.37027f;
+
+	Vector3 num;
+	  
+	num.x = (1.0f + ABCDE_x[0] * exp( ABCDE_x[1] / sunDir.y )) * (1.0f + ABCDE_x[2])+ ABCDE_x[4];    
+	num.y = (1.0f + ABCDE_y[0] * exp( ABCDE_y[1] / sunDir.y )) * (1.0f + ABCDE_y[2])+ ABCDE_y[4];   
+	num.z = (1.0f + ABCDE_Y[0] * exp( ABCDE_Y[1] / sunDir.y )) * (1.0f + ABCDE_Y[2])+ ABCDE_Y[4];   
+
+
+	Vector3 den;
+
+	den.x = (1.0f + ABCDE_x[0] * exp( ABCDE_x[1] )) * (1.0f + ABCDE_x[2] * exp( ABCDE_x[3] * sun_theta[0] ) + ABCDE_x[4] * sun_theta[1]);  
+	den.y = (1.0f + ABCDE_y[0] * exp( ABCDE_y[1] )) * (1.0f + ABCDE_y[2] * exp( ABCDE_y[3] * sun_theta[0]) + ABCDE_y[4] * sun_theta[1]);   
+	den.z = (1.0f + ABCDE_Y[0] * exp( ABCDE_Y[1] )) * (1.0f + ABCDE_Y[2] * exp( ABCDE_Y[3] * sun_theta[0] ) + ABCDE_Y[4] * sun_theta[1]);   
+
+
+	Vector3 xyY = num / den * zenithColor;    
+
+	Vector3 XYZ;                                                                                             
+
+	XYZ.x = (xyY.x / xyY.y) * xyY.z;                                                                        
+	XYZ.y = xyY.z;                                                                                          
+	XYZ.z = ((1.0f - xyY.x - xyY.y) / xyY.y) * xyY.z;                                                                
+
+
+	Vector3 color;	
+	color.x = 3.240479f*XYZ.x -1.537150f*XYZ.y-0.498535f*XYZ.z;
+	color.y = -0.969256f*XYZ.x +1.875992f*XYZ.y +0.041556f*XYZ.z;	
+	color.z = 0.055648f*XYZ.x -0.204043f*XYZ.y +1.057311f*XYZ.z;
+
+	// Calculate final sun diffuse color.
+	diffuse = color * 0.00017f;
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 2951)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 2954)
@@ -389,7 +389,8 @@
 
 
-void Bvh::UpdateMinDistance(BvhNode *node) const
-{
-	node->mDistance = node->GetBox().GetMinDistance(sNearPlane);
+void Bvh::UpdateDistance(BvhNode *node) const
+{
+	//node->mDistance = node->GetBox()GetMinDistance(sNearPlane);
+	node->mDistance = sNearPlane.Distance(node->GetBox().Center());
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 2954)
@@ -266,5 +266,6 @@
 	if (sinGamma < 1e-6f) return 1e6f;
 	
-	return (nearPlane + sqrt(nearPlane * (nearPlane + d * sinGamma))) /  sinGamma;
+	const float scale = 2.0f;
+	return scale * (nearPlane + sqrt(nearPlane * (nearPlane + d * sinGamma))) /  sinGamma;
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.h	(revision 2954)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.h	(revision 2954)
@@ -0,0 +1,28 @@
+#ifndef _SKYPREETHAM_H__
+#define _SKYPREETHAM_H__
+
+class SkyPreetham: public Entity
+{
+public:
+	// Constructor and destructor.
+	SkyPreetham(float turbitity);
+	virtual ~SkyPreetham();
+
+protected:
+
+	void renderSunDisk();
+	void createSunQuad();
+
+
+	/// Members.
+	FEffect*		mEffect;
+
+	FEffect*		mSunEffect;
+	FTexture2D*		mSunTexture;
+	FVertexBuffer*	mSunQuad;
+
+	float mTurbidity;
+};
+
+#endif //_SKYPREETHAM_H__
+
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2954)
@@ -37,4 +37,6 @@
 #include "Light.h"
 #include "SceneEntityConverter.h"
+#include "SunColor.h"
+
 
 
@@ -71,5 +73,5 @@
 int renderMode = RenderTraverser::CHCPLUSPLUS;
 // eye near plane distance
-float nearDist = 1.0f;
+float nearDist = 0.2f;
 float farDist = 1e6f;
 /// the field of view
@@ -171,4 +173,6 @@
 
 bool useLODs = true;
+
+bool moveLight = false;
 
 //DeferredRenderer::SAMPLING_METHOD samplingMethod = DeferredRenderer::SAMPLING_POISSON;
@@ -235,4 +239,6 @@
 void InitFBO();
 
+void RightMotionLight(int x, int y);
+
 void RenderShadowMap(float newfar);
 
@@ -638,4 +644,12 @@
 	Transform3 *tf = new Transform3(NULL);
 	cube = SceneEntityConverter().ConvertBox(box, mat, tf);
+
+	//////////////////////////////
+
+	GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
+
+	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
 }
 
@@ -751,14 +765,44 @@
 void SetupLighting()
 {
-	glEnable(GL_LIGHTING);
+	//glEnable(GL_LIGHTING);
 	glEnable(GL_LIGHT0);
 	
+	Vector3 lightDir = -light->GetDirection();
+
+
 	///////////
 	//-- first light: sunlight
 
-	//GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
-	GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
-	GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
-	GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
+	GLfloat ambient[] = {0.25f, 0.25f, 0.3f, 1.0f};
+	GLfloat diffuse[] = {1.0f, 0.95f, 0.85f, 1.0f};
+	GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+	Vector3 sunAmbient;
+	Vector3 sunDiffuse;
+
+	Vector3 h;
+
+	h.x = lightDir.x;
+	h.y = lightDir.z;
+	h.z = lightDir.y;
+
+
+	SunColor().Compute(h, sunAmbient, sunDiffuse);
+
+	const float maxComponent = sunDiffuse.MaxComponent();
+	//cout<< "sunambient: " << sunAmbient << " mag " << Magnitude(sunDiffuse) << " max: " << maxComponent << endl;
+
+	ambient[0] = sunAmbient.x;
+	ambient[1] = sunAmbient.y;
+	ambient[2] = sunAmbient.z;
+
+	sunDiffuse /= maxComponent;
+
+	diffuse[0] = sunDiffuse.x;
+	diffuse[1] = sunDiffuse.y;
+	diffuse[2] = sunDiffuse.z;
+
+	//cout<< "sunambient: " << sunAmbient << endl;
+	//cout<< "sundiffuse: " << sunDiffuse << endl;
 
 	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
@@ -766,40 +810,6 @@
 	glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
 
-	Vector3 lightDir = -light->GetDirection();
 	GLfloat position[] = {lightDir.x, lightDir.y, lightDir.z, 0.0f};
 	glLightfv(GL_LIGHT0, GL_POSITION, position);
-
-#if 0
-
-	////////////
-	//-- second light
-	
-	// physically incorrect to have second directional light, 
-	// but gives nicer shading for fixed function
-
-	glEnable(GL_LIGHT1);
-
-	GLfloat ambient1[] = {0.2, 0.2, 0.2, 1.0};
-	GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
-	GLfloat specular1[] = {0.0, 0.0, 0.0, 1.0};
-
-	glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
-	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
-	glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
-
-	GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
-	glLightfv(GL_LIGHT1, GL_POSITION, position1);
-
-	//GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
-
-#endif
-
-	//////////////////////////////
-
-	GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
-
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
-	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
-	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
 }
 
@@ -876,5 +886,4 @@
 	cgGLBindProgram(RenderState::sCgMrtFragmentProgram);
 
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 }
 
@@ -956,4 +965,5 @@
 		state.SetUseAlphaToCoverage(false);
 
+		state.Reset();
 		state.SetRenderType(RenderState::DEPTH_PASS);
 
@@ -1009,4 +1019,6 @@
 		glEnableClientState(GL_NORMAL_ARRAY);
 
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
 		break;
 	}
@@ -1022,11 +1034,5 @@
 
 	// set up lights
-	Vector3 lightDir = -light->GetDirection();
-	GLfloat lightPos[] = {lightDir.x, lightDir.y, lightDir.z, 0.0f};
-	glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
-
-	// second light
-	//GLfloat lightPos1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
-	//glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
+	SetupLighting();
 
 
@@ -1380,5 +1386,7 @@
 		showAlgorithmTime = !showAlgorithmTime;
 		break;
-
+	case GLUT_KEY_F10:
+		moveLight = !moveLight;
+		break;
 	case GLUT_KEY_LEFT:
 		{
@@ -1405,7 +1413,4 @@
 		}
 		break;
-	case GLUT_ACTIVE_ALT:
-		altKeyPressed = true;
-		break;
 	default:
 		return;
@@ -1443,6 +1448,4 @@
 void Mouse(int button, int state, int x, int y) 
 {
-	int specialKey = glutGetModifiers();
-
 	if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
 	{
@@ -1458,5 +1461,8 @@
 		yMotionBegin = y;
 
-		glutMotionFunc(RightMotion);
+		if (!moveLight)
+			glutMotionFunc(RightMotion);
+		else
+			glutMotionFunc(RightMotionLight);
 	}
 	else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
@@ -1490,4 +1496,26 @@
 	camera->SetPosition(pos);
 	
+	xEyeBegin = x;
+	yMotionBegin = y;
+
+	glutPostRedisplay();
+}
+
+
+void RightMotionLight(int x, int y) 
+{
+	float theta = 0.2f * M_PI * (xEyeBegin - x) / 180.0f;
+	float phi = 0.2f * M_PI * (yMotionBegin - y) / 180.0f;
+	
+	Vector3 lightDir = light->GetDirection();
+
+	Matrix4x4 roty = RotationYMatrix(theta);
+	Matrix4x4 rotx = RotationXMatrix(phi);
+
+	lightDir = roty * lightDir;
+	lightDir = rotx * lightDir;
+
+	light->SetDirection(lightDir);
+
 	xEyeBegin = x;
 	yMotionBegin = y;
@@ -1928,4 +1956,5 @@
 		glDrawBuffers(3, mrt);
 		glClear(GL_COLOR_BUFFER_BIT);
+		//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	}
 	else
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.h	(revision 2954)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SunColor.h	(revision 2954)
@@ -0,0 +1,19 @@
+#ifndef __SUNCOLOR_H__
+#define __SUNCOLOR_H__
+
+//#include "Vector3.h"
+
+namespace CHCDemoEngine{
+
+class Vector3;
+}
+/** Class describing a plane in 3D space.
+*/
+class SunColor 
+{
+public:
+
+	void Compute(const CHCDemoEngine::Vector3 &sunDir, CHCDemoEngine::Vector3 &ambient, CHCDemoEngine::Vector3 &diffuse) const;
+};
+
+#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Light.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Light.h	(revision 2952)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Light.h	(revision 2954)
@@ -19,4 +19,5 @@
 
 	Vector3 GetDirection() const { return mDirection; }
+	void SetDirection(const Vector3 &dir) { mDirection = dir; }
 
 	RgbaColor GetColor() const { return mColor; }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Readme.txt
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Readme.txt	(revision 2878)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Readme.txt	(revision 2954)
@@ -86,5 +86,7 @@
 glfont2 (http://students.cs.byu.edu/~bfish/glfont2.php) for the antialiased fonts of the HUD. Thanks to the author Brad Fish. 
 
-Thanks also to Alexander Kusternig for providing me his code for the SSAO shader.
+Thanks to Ralf Habel for providing me the code for computing the sun illumination and Pretham model.
+Thanks to Alexander Kusternig for providing me his code for the SSAO shader.
 
+The deferred shading algorithm features a 
 If you find any problem with the code or have any comments, please feel free to ask us at any time.
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 2954)
@@ -11,9 +11,9 @@
 camPosition=483.398f 242.364f 186.078f
 camDirection=1 0 0
-#lightDirection=-0.8f 1.0f -0.7f
-lightDirection=0.2f -1.0f -.5f
+lightDirection=-0.8f 1.0f -0.7f
+#lightDirection=0.2f -1.0f -.5f
 useFullScreen=0
 useLODs=1
-shadowSize=2048
+shadowSize=4096
 #modelPath=data/city/model/
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2954)
@@ -276,12 +276,4 @@
 			</File>
 			<File
-				RelativePath=".\src\ObjConverter.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\src\ObjConverter.h"
-				>
-			</File>
-			<File
 				RelativePath=".\src\PerformanceGraph.cpp"
 				>
@@ -349,4 +341,20 @@
 			<File
 				RelativePath=".\src\ShadowMapping.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\SkyPreetham.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\SkyPreetham.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\SunColor.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\SunColor.h"
 				>
 			</File>
