Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3304)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3305)
@@ -107,5 +107,5 @@
 						 uniform float3 tl,
 						 uniform float3 tr,
-						 uniform float2 resolution
+						 uniform float2 res
 						 )
 {
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg	(revision 3304)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg	(revision 3305)
@@ -19,4 +19,34 @@
 	float4 illum_col: COLOR0;
 };
+
+
+float ComputeConvergenceHalfRes(uniform sampler2D ssaoTex,
+								float2 texCoord, 
+								float2 halfres)
+{
+    // the following has to be done for half resolution ssao:
+	// get the minimum convergence by exactly sampling the 4 surrounding
+	// texels in the old texture, otherwise flickering because convergence
+	// will be interpolated when upsampling and filter size does not match!
+
+	float4 texelCenterConv;
+	const float xoffs = .5f / halfres.x; const float yoffs = .5f / halfres.y;
+
+	// get position exactly between old texel centers
+	float2 center;
+	center.x = (floor(texCoord.x * halfres.x - .5f) + 1.0f) / halfres.x;
+	center.y = (floor(texCoord.y * halfres.y - .5f) + 1.0f) / halfres.y;
+
+	texelCenterConv.x = tex2Dlod(ssaoTex, float4(center + float2( xoffs,  yoffs), 0, 0)).y;
+	texelCenterConv.y = tex2Dlod(ssaoTex, float4(center + float2( xoffs, -yoffs), 0, 0)).y;
+	texelCenterConv.z = tex2Dlod(ssaoTex, float4(center + float2(-xoffs, -yoffs), 0, 0)).y;
+	texelCenterConv.w = tex2Dlod(ssaoTex, float4(center + float2(-xoffs,  yoffs), 0, 0)).y;
+
+	const float m1 = min(texelCenterConv.x, texelCenterConv.y);
+	const float m2 = min(texelCenterConv.z, texelCenterConv.w);
+
+	const float minConvergence = min(m1, m2);
+	return minConvergence;
+}
 
 
@@ -45,5 +75,4 @@
 	// combine the weights
 	float w = convergenceFactor * convergenceFactor * spatialFactor;// * normalFactor;
-
 	float average = aoSample.x * w;
 
@@ -94,6 +123,6 @@
 						uniform float3 tl,
 						uniform float3 tr,
-						uniform float2 xyStep
-						 )
+						uniform float2 res
+						)
 {
 	pixel OUT;
@@ -108,4 +137,6 @@
 	// afterwards we do not use the filter anymore
 
+	float2 xyStep = float2(1.0f / res.x, 0);
+
 	// filter up to a certain convergance value and leave out background (sky) by checking depth
 	if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
@@ -118,17 +149,51 @@
 }
 
+/** In between step that only filters in one direction
+*/
+pixel FilterSsaoHalfRes(fragment IN, 
+						uniform sampler2D colorsTex,
+						uniform sampler2D ssaoTex,
+						uniform float3 bl,
+						uniform float3 br,
+						uniform float3 tl,
+						uniform float3 tr,
+						uniform float2 res
+						 )
+{
+	pixel OUT;
+
+	const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
+
+	OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
+	// just take unfiltered convergence in current pixel
+	const float convergence = ComputeConvergenceHalfRes(ssaoTex, IN.texCoord, res * 0.5f);
+
+	const float2 xyStep = float2(1.0f / res.x, 0);
+
+	// filter reaches size 1 pixel when sample size reaches threshold 
+	// afterwards we do not use the filter anymore
+
+	// filter up to a certain convergance value and leave out background (sky) by checking depth
+	if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
+	{
+		// the filtered ssao value
+		OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
+	}
+
+	return OUT;
+}
 
 /** Function combining image and indirect illumination buffer using a 
     depth and convergence aware discontinuity filter.
 */
-pixel CombineSsaoFullRes(fragment IN, 
-						 uniform sampler2D colorsTex,
-						 uniform sampler2D ssaoTex,
-						 uniform float3 bl,
-						 uniform float3 br,
-						 uniform float3 tl,
-						 uniform float3 tr,
-						 uniform float2 xyStep
-						 )
+pixel CombineSsao(fragment IN, 
+				  uniform sampler2D colorsTex,
+				  uniform sampler2D ssaoTex,
+				  uniform float3 bl,
+				  uniform float3 br,
+				  uniform float3 tl,
+				  uniform float3 tr,
+				  uniform float2 res
+				  )
 {
 	pixel OUT;
@@ -141,4 +206,6 @@
 	const float convergence = ao.y;
 
+	const float2 xyStep = float2(0, 1.0f / res.y);
+	
 	// filter reaches size 1 pixel when sample size reaches threshold 
 	// afterwards we do not use the filter anymore
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3301)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3305)
@@ -63,7 +63,4 @@
 	*/
 	void SetKernelRadius(float kernelRadius);
-	/** Sets ssao filter radius.
-	*/
-	void SetSsaoFilterRadius(float radius);
 	/** Passes the number of pixels that are visible from the sun.
 	*/
@@ -161,6 +158,4 @@
 
 	void LenseFlare(FrameBufferObject *fbo, DirectionalLight *light);
- 
-	void PrepareSsaoFilter();
 
 	void SaveFrame(FrameBufferObject *fbo);
@@ -196,4 +191,5 @@
 
 	FrameBufferObject *mDownSampleFbo;
+	FrameBufferObject *mTempFbo;
 
 	FBOContainer mFBOs;
@@ -211,5 +207,4 @@
 
 	float mKernelRadius;
-	float mSsaoFilterRadius;
 	float mSampleIntensity;
 
@@ -224,5 +219,7 @@
 	bool mUseToneMapping;
 	bool mUseAntiAliasing;
-	bool mUseDepthOfField;	  
+	bool mUseDepthOfField;
+
+	bool mSsaoUseFullResolution;
 };
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3297)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3305)
@@ -204,5 +204,5 @@
 float ssaoKernelRadius = 1e-8f;
 float ssaoSampleIntensity = 0.2f;
-float ssaoFilterRadius = 12.0f;
+float ssaoFilterRadius = 3.0f;
 float ssaoTempCohFactor = 255.0;
 bool sortSamples = true;
@@ -1383,5 +1383,4 @@
 			deferredShader->SetKernelRadius(ssaoKernelRadius);
 			deferredShader->SetSampleIntensity(ssaoSampleIntensity);
-			deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		}
 
@@ -1574,14 +1573,14 @@
 		cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
 		break;
-	case 'o':
-		ssaoFilterRadius *= 0.9f;
+	/*case 'o':
+		if (ssaoFilterRadius >= 0.0f) ssaoFilterRadius -= 1.0f;
 		if (deferredShader) deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
 		break;
 	case 'O':
-		ssaoFilterRadius *= 1.0f / 0.9f;
+		ssaoFilterRadius += 1.0f;
 		if (deferredShader) deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
-		break;
+		break;*/
 	/*	case 'o':
 	case 'O':
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3301)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3305)
@@ -248,5 +248,4 @@
 	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -300,5 +299,4 @@
 mSortSamples(true),
 mKernelRadius(1e-8f),
-mSsaoFilterRadius(12.0f),
 mSampleIntensity(0.2f),
 mSunVisiblePixels(0),
@@ -309,5 +307,6 @@
 mUseToneMapping(false),
 mUseAntiAliasing(false),
-mUseDepthOfField(false)
+mUseDepthOfField(false),
+mSsaoUseFullResolution(ssaoUseFullResolution)
 {
 	///////////
@@ -316,5 +315,5 @@
 	int downSampledWidth, downSampledHeight;
 
-	if (ssaoUseFullResolution)
+	if (mSsaoUseFullResolution)
 	{
 		downSampledWidth = w; downSampledHeight = h;
@@ -327,9 +326,9 @@
 	}
 
-	///////
+
+	/////////
 	//-- the illumination fbo is either half size or full size
 
 	mIllumFbo = new FrameBufferObject(downSampledWidth, downSampledHeight, FrameBufferObject::DEPTH_NONE);
-
 	mFBOs.push_back(mIllumFbo);
 
@@ -343,5 +342,5 @@
 	///////////////
 	//-- the downsampled ssao + color bleeding textures: 
-	//-- as GI is mostly low frequency, we can use lower resolution toimprove performance
+	//-- as GI is mostly low frequency, we can use lower resolution to improve performance
 
 	mDownSampleFbo = new FrameBufferObject(downSampledWidth, downSampledHeight, FrameBufferObject::DEPTH_NONE);
@@ -358,4 +357,15 @@
 
 	mFBOs.push_back(mDownSampleFbo);
+
+
+	/////////
+	//-- temporal buffer
+
+	mTempFbo = new FrameBufferObject(mWidth, mHeight, FrameBufferObject::DEPTH_NONE);
+	mFBOs.push_back(mTempFbo);
+
+	mTempFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
+	FrameBufferObject::InitBuffer(mTempFbo, 0);
+	
 
 	// create noise texture for ssao
@@ -397,7 +407,15 @@
 	sCgGiProgram = sm->CreateFragmentProgram("globillum", "main", "GiFrag");
 	sCgCombineIllumProgram = sm->CreateFragmentProgram("globillum", "combine", "CombineGi");
-	//sCgCombineSsaoProgram = sm->CreateFragmentProgram("combineSsao", "CombineSsaoHalfRes", "CombineSsao");
-	sCgCombineSsaoProgram = sm->CreateFragmentProgram("combineSsaoSep", "CombineSsaoFullRes", "CombineSsao");
-	sCgFilterSsaoProgram = sm->CreateFragmentProgram("combineSsaoSep", "FilterSsaoFullRes", "FilterSsao");
+
+	if (mSsaoUseFullResolution)
+	{
+		sCgFilterSsaoProgram = sm->CreateFragmentProgram("combineSsaoSep", "FilterSsaoFullRes", "FilterSsao");
+	}
+	else
+	{
+		sCgFilterSsaoProgram = sm->CreateFragmentProgram("combineSsaoSep", "FilterSsaoHalfRes", "FilterSsao");
+	}
+	
+	sCgCombineSsaoProgram = sm->CreateFragmentProgram("combineSsaoSep", "CombineSsao", "CombineSsao");
 	sCgAntiAliasingProgram = sm->CreateFragmentProgram("antialiasing", "main", "AntiAliasing");
 	sCgToneProgram = sm->CreateFragmentProgram("tonemap", "ToneMap", "ToneMap");
@@ -446,11 +464,6 @@
 	////////////////
 
-	/*string combineSsaoParams[] = 
-		{"colorsTex", "normalsTex", "ssaoTex", "filterOffs", "filterWeights", 
-		"ssaoFilterRadius", "modelViewProj", "bl", "br", "tl", 
-		"tr", "w", "h"};
-	*/
 	string combineSsaoParams[] = 
-		{"colorsTex", "ssaoTex", "bl", "br", "tl", "tr", "xyStep"};
+	{"colorsTex", "ssaoTex", "bl", "br", "tl", "tr", "res"};
 
 	//sCgCombineSsaoProgram->AddParameters(combineSsaoParams, 0, 13);
@@ -461,5 +474,5 @@
 
 	string filterSsaoParams[] = 
-		{"colorsTex", "ssaoTex", "bl", "br", "tl", "tr", "xyStep"};
+		{"colorsTex", "ssaoTex", "bl", "br", "tl", "tr", "res"};
 
 	sCgFilterSsaoProgram->AddParameters(filterSsaoParams, 0, 7);
@@ -515,10 +528,4 @@
 
 	sCgDOFProgram->AddParameters(dofParams, 0, 4);
-
-
-	////////////////
-	//-- prepare filter for ssao
-
-	PrepareSsaoFilter();
 
 
@@ -642,87 +649,4 @@
 }
 
-#if 0
-
-void DeferredRenderer::PrepareSsaoFilter()
-{
-	const float filterWidth = 1.0f;
-
-	PoissonDiscSampleGenerator2D poisson(NUM_SSAO_FILTER_SAMPLES, 1.0f);
-	poisson.Generate((float *)ssaoFilterOffsets);
-
-	const float xoffs = (float)filterWidth / mWidth;
-	const float yoffs = (float)filterWidth / mHeight;
-
-	for (int i = 0; i < NUM_SSAO_FILTER_SAMPLES; ++ i)
-	{
-		float x = ssaoFilterOffsets[2 * i + 0];
-		float y = ssaoFilterOffsets[2 * i + 1];
-
-		ssaoFilterWeights[i] = GaussianDistribution(x, y, 1.0f);
-		//ssaoFilterWeights[i] = 1.0f;
-
-		ssaoFilterOffsets[2 * i + 0] *= xoffs;
-		ssaoFilterOffsets[2 * i + 1] *= yoffs;
-	}
-}
-
-#else
-
-/** star filter
-*/
-void DeferredRenderer::PrepareSsaoFilter()
-{
-	const float filterWidth = 1.0f;
-
-	PoissonDiscSampleGenerator2D poisson(NUM_SSAO_FILTER_SAMPLES, 1.0f);
-	poisson.Generate((float *)ssaoFilterOffsets);
-
-	const float xoffs = (float)filterWidth / mWidth;
-	const float yoffs = (float)filterWidth / mHeight;
-
-	const int n = NUM_SSAO_FILTER_SAMPLES / 2 + 1;
-
-	for (int i = 0; i < n; ++ i)
-	{
-		const int idx = i - NUM_SSAO_FILTER_SAMPLES / 4;
-
-		const float x = xoffs * (float)idx;
-		const float y = 0;
-
-		ssaoFilterWeights[i] = GaussianDistribution(x, y, 1.0f);
-		
-		ssaoFilterOffsets[2 * i + 0] = x;
-		ssaoFilterOffsets[2 * i + 1] = y;
-	}
-
-	int j = 2 * n;
-
-	for (int i = 0; i < n; ++ i)
-	{ 
-		const int idx = i - NUM_SSAO_FILTER_SAMPLES / 4;
-
-		if (idx)
-		{
-			const float x = 0;
-			const float y = yoffs * (float)idx;
-
-			ssaoFilterWeights[i] = GaussianDistribution(x, y, 1.0f);
-			//ssaoFilterWeights[i] = 1.0f;
-			
-			ssaoFilterOffsets[j + 0] = x;
-			ssaoFilterOffsets[j + 1] = y;
-
-			j += 2;
-		}
-	}
-
-	for (int i = 0; i < NUM_SSAO_FILTER_SAMPLES; ++ i)
-	{
-		cout << "samples " << i << ": " << ssaoFilterOffsets[i * 2] << " " << ssaoFilterOffsets[i * 2 + 1] << endl;
-	}
-}
-
-#endif
-
 
 static inline float SqrMag(const Sample2 &s)
@@ -1045,8 +969,9 @@
 	GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex)->GetTexture();
 	
-	mIllumFbo->Bind();
-	glDrawBuffers(1, mrt + mIllumFboIndex + 1);
-	
-
+	//mIllumFbo->Bind();
+	//glDrawBuffers(1, mrt + mIllumFboIndex + 1);
+	mTempFbo->Bind();
+	glDrawBuffers(1, mrt);
+	
 	int i = 0;
 
@@ -1059,8 +984,7 @@
 	}
 
-	sCgFilterSsaoProgram->SetValue2f(i ++, 1.0f / (float)mWidth, 0);
+	sCgFilterSsaoProgram->SetValue2f(i ++, (float)mWidth, (float)mHeight);
 
 	DrawQuad(sCgFilterSsaoProgram);
-	
 	PrintGLerror("combine ssao");
 }
@@ -1071,5 +995,6 @@
 	GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
 	GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
-	GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex + 1)->GetTexture();
+	//GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex + 1)->GetTexture();
+	GLuint ssaoTex = mTempFbo->GetColorBuffer(0)->GetTexture();
 	
 	FlipFbos(fbo);
@@ -1080,9 +1005,4 @@
 	sCgCombineSsaoProgram->SetTexture(i ++, ssaoTex);
 
-	//sCgCombineSsaoProgram->SetArray2f(i ++, (float *)ssaoFilterOffsets, NUM_SSAO_FILTER_SAMPLES);
-	//sCgCombineSsaoProgram->SetArray1f(i ++, (float *)ssaoFilterWeights, NUM_SSAO_FILTER_SAMPLES);
-	//sCgCombineSsaoProgram->SetValue1f(i ++, mSsaoFilterRadius);
-	//sCgCombineSsaoProgram->SetMatrix(i ++, mProjViewMatrix);
-
 	for (int j = 0; j < 4; ++ j, ++ i)
 	{
@@ -1090,8 +1010,5 @@
 	}
 
-	//float xOffs, yOffs;
-
-	//sCgCombineSsaoProgram->SetValue2f(i ++, 1.0f / (float)mWidth, 1.0f / (float)mHeight);
-	sCgCombineSsaoProgram->SetValue2f(i ++, 0, 1.0f / (float)mHeight);
+	sCgCombineSsaoProgram->SetValue2f(i ++, mWidth, mHeight);
 
 	DrawQuad(sCgCombineSsaoProgram);
@@ -1545,11 +1462,4 @@
 
 
-void DeferredRenderer::SetSsaoFilterRadius(float ssaoFilterRadius)
-{
-	mSsaoFilterRadius = ssaoFilterRadius;
-	mRegenerateSamples = true;
-}
-
-
 /*void DeferredRenderer::SetSortSamples(bool sortSamples) 
 {
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3297)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3305)
@@ -144,6 +144,4 @@
 # ssao temporal coherence factor
 tempCohFactor=2000.0f
-# ssao filter radius
-ssaoFilterRadius=12.0f
 
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 3296)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 3305)
@@ -820,8 +820,4 @@
 			</File>
 			<File
-				RelativePath=".\src\shaders\combineSsao.cg"
-				>
-			</File>
-			<File
 				RelativePath=".\src\shaders\combineSsaoSep.cg"
 				>
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3295)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3305)
@@ -298,5 +298,4 @@
 					++ mNumShapes;
 
-					if (!currentMat) cout << "here3" << endl;
 					LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
 
