Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3226)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3227)
@@ -21,4 +21,5 @@
 
 #define SSAO_CONVERGENCE_THRESHOLD 700.0f
+//#define SSAO_CONVERGENCE_THRESHOLD 1500.0f
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.h	(revision 3129)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.h	(revision 3227)
@@ -3,229 +3,49 @@
 
 #include <iostream>
+#include <vector>
+
+class Halton 
+{
+public:
+
+	static void TestHalton(int n, int dim);
+
+	static void TestPrime();
 
 
-/** Assert whether the argument is a prime number.
-	@param number the number to be checked
-*/
-inline bool IsPrime(const int number) 
-{
-	bool isIt = true;
-
-	for(int i = 2; i < number; ++ i) 
-	{
-		if(number % i == 0) 
-		{
-			isIt = false;
-			break;
-		}
-	}
-
-	if(number == 2) 
-	{
-		isIt = false;
-	}
-
-	return isIt;
-}
+	Halton(int dim);
 
 
-/**
-	Find the nth prime number.
-	@param index the ordinal position in the sequence
-*/
-inline int FindPrime(const int index) 
-{
-
-	const int primes[] = {-1, 1, 3, 5, 7, 11, 13};
-	if (index <= 6)
-		return primes[index];
-
-	int prime = 1;
-	int found = 1;
-	while(found != index) {
-		prime += 2;
-		if(IsPrime(prime) == true) {
-			found++;
-		}
-	}
-	return prime;
-}
-
-  
-inline float halton(float baseRec, float prev) 
-{
-	float r = 1.0f - prev;
-	
-	if (baseRec < r)
-		return prev + baseRec;
-	
-	float h = baseRec;
-	
-	float hh;
-	
-	do 
-	{
-		hh = h;
-		h *= baseRec;
-	} while (h > r);
-	
-	return prev + hh + h - 1.0f;
-}
+	float GetNext();
 
 
-template<int T> struct Halton 
+protected:
+
+	static bool IsPrime(int n);
+    
+    static int FindPrime(int idx);
+
+
+	////////////////////
+
+	unsigned int mIndex;
+	int mBase;
+};		
+
+
+class HaltonSequence
 {
-	static float _invBases[T];
-	float _prev[T];
-
 public:
 
-	void Reset() 
-	{
-		for (int i=0; i < T; i++) 
-			_prev[i] = 0;
-	}
+	static void TestHalton(int n, int dim);
 
-	Halton(const bool initializeBases) 
-	{
-		for (int i=0; i < T; i++) 
-		{
-			int base = FindPrime(i+1);
-		
-			if (base == 1)
-				base++;
-			_invBases[i] = 1.0f/base;
-		}
-	}
+	HaltonSequence(int dim);
 
-	Halton() 
-	{
-		Reset();
-	}
-  
-	void GetNext(float *a) 
-	{
-		for (int i=0; i < T; i++) 
-		{
-			a[i] = halton(_invBases[i], _prev[i]);
-			_prev[i] = a[i];
-		}
-	}
-
-};
-
-struct Halton2 
-{
-	static float _invBases[2];
-	float _prev[2];
-
-public:
-
-	void Reset() 
-	{
-		_prev[0] =_prev[1] = 0;
-	}
-
-	Halton2() 
-	{
-		_invBases[0] = 1.0f / 2;
-		_invBases[1] = 1.0f / 3;
-		Reset();
-	}
-
-	void GetNext(float &a, float &b) 
-	{
-		a = halton(_invBases[0], _prev[0]);
-		b = halton(_invBases[1], _prev[1]);
-
-		_prev[0] = a;
-		_prev[1] = b;
-	}
-};
+	void GetNext(float *numbers);
 
 
-  
-struct HaltonSequence 
-{
-public:
-	int index;
+protected:
 
-	static int sPregeneratedDim;
-	static int sPregeneratedNumber;
-	static float *sPregeneratedValues;
-
-	// special construtor for pregenerating static halton sequences
-	HaltonSequence(int dim, int number);
-
-	HaltonSequence(): index(1) 
-	{ 
-		float dummy[2]; 
-		for (int i = 0; i < 20; ++ i) GetNext(2, dummy);
-	}
-
-	void Reset() { index = 1; }
-
-	void GetNext(int dimensions, float *p);
-
-	void GenerateNext() { ++ index; }
-
-	double GetNumber(const int dimension)  
-	{
-		int base = FindPrime(dimension);
-		if (base == 1) 
-		{
-			base++;  // The first dimension uses base 2.
-		} 
-
-		int _p1 = base;
-		float _ip1 = 1.0f / base;
-		float p, u=0.0f;
-		int kk, a;
-
-		// the first coordinate
-		for (p = _ip1, kk = index ; kk ;  p *= _ip1, kk /= _p1)   
-			if ((a = kk % _p1))
-				u += a * p;
-
-		return u;
-	}
-
-	/**
-		Returns the nth number in the sequence, taken from a specified dimension.
-		@param index the ordinal position in the sequence
-		@param dimension the dimension
-	*/
-	double GetNumberOld(int dimension)  
-	{
-		int base = FindPrime(dimension);
-		if(base == 1) 
-		{
-			++ base;  //The first dimension uses base 2.
-		} 
-
-		double remainder;
-		double output = 0.0;
-		double fraction = 1.0 / (double)base;
-		int N1 = 0;
-		int copyOfIndex = index;
-		
-		if ((base >= 2) && (index >= 1)) 
-		{
-			while (copyOfIndex > 0) 
-			{
-				N1 = (copyOfIndex / base);
-				remainder = copyOfIndex % base;
-				output += fraction * remainder;
-				copyOfIndex = (int)(copyOfIndex / base);
-				fraction /= (double)base;
-			} 
-			return output;
-		}
-		else 
-		{
-			std::cerr << "Error generating Halton sequence." << std::endl;
-			exit(1);
-		}
-	}
+	std::vector<Halton> mHaltons;
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3226)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3227)
@@ -1,4 +1,4 @@
 #include "../shaderenv.h"
-
+#include "common.h"
 
 ////////////////////
@@ -28,30 +28,4 @@
 }
 
-
-inline float SqrLen(float3 v)
-{
-	return v.x * v.x + v.y * v.y + v.z * v.z;
-}
-
-
-inline float2 myreflect(float2 pt, float2 n)
-{
-	// distance to plane
-	float d = dot(n, pt);
-	// reflect around plane
-	float2 rpt = pt - d * 2.0f * n;
-
-	return rpt;
-}
-
-
-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;
-}
 
 
@@ -225,14 +199,13 @@
 	total_ao /= numSamples;
 
-#if 0
+#if 1
 	// 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 viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * max(dot(viewDir, normal), 0.0f);
-	total_ao *= viewCorrection;
+	total_ao += cosAngle * aoContrib * viewCorrection;
 
 #endif
 
-	//return float3(max(0.0f, 1.0f - total_ao), validSamples, numSamples);
-	return float3(total_ao, validSamples, numSamples);
+	return float3(max(0.0f, 1.0f - total_ao), validSamples, numSamples);
 }
 
@@ -261,6 +234,5 @@
 			float newWeight,
 			float sampleIntensity,
-			bool isMovingObject,
-			sampler2D normalTex
+			bool isMovingObject
 			)
 {
@@ -273,14 +245,15 @@
 		const float2 offset = samples[i];
 
-#if 1
+		float2 offsetTransformed;
+
 		////////////////////
 		//-- add random noise: reflect around random normal vector 
-		//-- (slows down the computation for some reason!)
+		//-- (affects performance for some reason!)
 
 		float2 mynoise = tex2Dlod(noiseTex, float4(IN.texCoord * 4.0f, 0, 0)).xy;
-		const float2 offsetTransformed = myreflect(offset, mynoise);
-#else
-		const float2 offsetTransformed = offset;
-#endif
+		//float2 mynoise = tex2Dlod(noiseTex, float4(IN.texCoord, 0, 0)).xy;
+		//offsetTransformed = myreflect(offset, mynoise);
+		offsetTransformed = myrotate(offset, mynoise.x);
+		
 		// weight with projected coordinate to reach similar kernel size for near and far
 		const float2 texcoord = IN.texCoord.xy + offsetTransformed * scaleFactor;
@@ -290,9 +263,4 @@
 		
 
-		// the normal of the current sample
-		//const float3 sampleNormal = tex2Dlod(normalTex, float4(texcoord, 0, 0)).xyz;
-		// angle between current normal and direction to sample controls AO intensity.
-		//float cosAngle2 = .5f + dot(sampleNormal, -normal) * 0.5f;
-
 		////////////////
 		//-- compute contribution of sample using the direction and angle
@@ -300,16 +268,18 @@
 		float3 dirSample = samplePos - centerPosition;
 
-		const float sqrLen = max(SqrLen(dirSample), 1e-2f);
-		const float lengthToSample = sqrt(sqrLen);
+		//const float sqrLen = max(SqrLen(dirSample), 1e-2f);
+		//const float lengthToSample = sqrt(sqrLen);
+		const float lengthToSample =  max(length(dirSample), 1e-2f);
 
 		dirSample /= lengthToSample; // normalize
 
 		// angle between current normal and direction to sample controls AO intensity.
-		const float cosAngle = max(dot(dirSample, normal), .0f);
-		const float aoContrib = sampleIntensity / sqrLen;
+		float cosAngle = dot(dirSample, normal);
+
+		//const float aoContrib = sampleIntensity / sqrLen;
+		const float aoContrib = sampleIntensity / lengthToSample;
 		//const float aoContrib = (1.0f > lengthToSample) ? occlusionPower(9e-2f, DISTANCE_SCALE + lengthToSample): .0f;
 
-		//total_ao += cosAngle2 * cosAngle * aoContrib;
-		total_ao += cosAngle * aoContrib;
+		total_ao += max(cosAngle, 0) * aoContrib;
 
 		++ numSamples;
@@ -324,7 +294,7 @@
 		// to have any influence in the current or last frame
 		const float tooFarAway = step(0.5f, lengthToSample - changeFactor);
-		validSamples = max(validSamples, (1.0f - tooFarAway) * pixelValid);
-
-#if 1//#ifdef U//USE_GTX
+		validSamples = max(validSamples, (1.0f - tooFarAway) * pixelValid * step(-0.1f, cosAngle));
+
+#ifdef USE_GTX
 		// we can bail out early and use a minimal #samples)
 		// if some conditions are met as long as the hardware supports it
@@ -351,5 +321,4 @@
 
 	return float3(total_ao, validSamples, numSamples);
-	//return float3(max(0.0f, 1.0f - total_ao), validSamples, numSamples);
 }
 
@@ -426,5 +395,5 @@
 	if (eyeSpaceDepth < 1e10f)
 	{
-		ao = ssao(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, isMovingObject, normals);
+		ao = ssao(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, isMovingObject);
 		//ao = ssao2(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), normals, sampleIntensity);
 	}
@@ -460,13 +429,13 @@
 	}
 
+	//////////
+	//-- blend ao between old and new samples (and avoid division by zero)
+
+	OUT.illum_col.x = (ao.x * newWeight + oldSsao * oldWeight);// / (newWeight + oldWeight);//max(1e-6f, newWeight + oldWeight);
+
+	OUT.illum_col.x /= (newWeight + oldWeight);
+
 	// the new weight for the next frame
 	const float combinedWeight = clamp(newWeight + oldWeight, .0f, temporalCoherence);
-
-
-	//////////
-	//-- blend ao between old and new samples (and avoid division by zero)
-
-	//OUT.illum_col.x = (ao.x * newWeight + oldSsao * oldWeight) / max(1e-6f, newWeight + oldWeight);
-	OUT.illum_col.x = (ao.x * newWeight + oldSsao * oldWeight) / (newWeight + oldWeight);
 
 	OUT.illum_col.y = combinedWeight;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3226)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3227)
@@ -229,5 +229,6 @@
 
 	// compute position from old frame for dynamic objects + translational portion
-	const float3 translatedPos = difVec - oldEyePos + worldPos.xyz;
+	//const float3 translatedPos = difVec - oldEyePos + worldPos.xyz;
+	const float3 translatedPos = - oldEyePos + worldPos.xyz;
 
 
@@ -275,9 +276,11 @@
 		pixelValid = pixelNotValid;
 	}
-	else if (
+	else if (!((oldEyeSpaceDepth > 1e10f) || (projectedEyeSpaceDepth > 1e10f)) &&
 		// check if changed from dynamic to not dynamic object
-		(oldDynamic && !newDynamic) || (!oldDynamic && newDynamic) ||
+		((oldDynamic && !newDynamic) || (!oldDynamic && newDynamic) ||
 		// check if we have a dynamic object and is a depth discontinuity
-		((oldDynamic || newDynamic) && (depthDif <= MIN_DEPTH_DIFF)))
+		(
+		//(oldDynamic || newDynamic) && 
+		(depthDif > MIN_DEPTH_DIFF))))
 	{	
 		pixelValid = pixelCouldBeValid; 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/common.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/common.h	(revision 3213)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/common.h	(revision 3227)
@@ -45,2 +45,16 @@
 	return rpt;
 }
+
+
+
+
+inline float2 myrotate(float2 pt, float angle)
+{
+	float2 rpt;
+
+	rpt.x = pt.x * cos(angle) - pt.y * sin(angle);
+	rpt.y = pt.y * cos(angle) + pt.x * sin(angle);
+
+	//normalize(rpt);
+	return rpt;
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.cpp	(revision 2839)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Halton.cpp	(revision 3227)
@@ -3,46 +3,130 @@
 
 
-float Halton2::_invBases[2];
 
-template<int T> float Halton<T>::_invBases[T];
-  
-Halton<1> dummmyHalton1(true);
-Halton<2> dummmyHalton2(true);
-Halton<3> dummmyHalton3(true);
-Halton<4> dummmyHalton4(true);
-Halton<5> dummmyHalton5(true);
-Halton<6> dummmyHalton6(true);
+void Halton::TestHalton(int n, int dim)
+{
+	Halton h(dim);
 
-
-int HaltonSequence::sPregeneratedDim = 0;
-int HaltonSequence::sPregeneratedNumber = 0;
-float *HaltonSequence::sPregeneratedValues = NULL;
-
-
-// special construtor for pregenerating static halton sequences
-HaltonSequence::HaltonSequence(const int dim, const int number) 
-{
-
-	sPregeneratedDim = 0;
-	sPregeneratedNumber = 0;
-	sPregeneratedValues = new float[number*dim];
-
-	float *p = sPregeneratedValues;
-
-	for (int i=0; i < number; i++, p+=dim) 
+	for (int i = 1; i <= n; ++ i)
 	{
-		GetNext(dim, p);
+		std::cout << "halton " << i << " of dim " << dim << " = " << h.GetNext() << std::endl;
 	}
-
-	sPregeneratedDim = dim;
-	sPregeneratedNumber = number;
 }
 
 
-void HaltonSequence::GetNext(const int dimensions, float *p)
+void Halton::TestPrime()
 {
-	for (int i = 0; i < dimensions; ++ i)
-		p[i] = (float)GetNumber(i + 1);
+	int dim = 2;
 
-	GenerateNext();
+	for (int i = 1; i < 10; ++ i)
+	{
+		std::cout << "prime for dim " << i << " " << Halton::FindPrime(i) << std::endl;
+	}
 }
+
+
+Halton::Halton(int dim): mIndex(0)
+{
+	mBase = FindPrime(dim);
+}
+
+
+float Halton::GetNext()
+{
+	++ mIndex;
+
+	float result = .0f;
+	float fraction = 1.0f / (float)mBase;
+	int idx = mIndex;
+
+	while (idx > 0) 
+	{
+		int digit = idx % mBase;
+		result += fraction * (float)digit;
+
+		idx  = (idx - digit) / mBase;
+		fraction /= (float)mBase;
+	}
+
+	mIndex %= 100000000;
+	return result;
+}
+
+
+bool Halton::IsPrime(int n) 
+{
+	bool isPrime = true;
+
+	for (int i = 2; i < n; ++ i) 
+	{
+		if (n % i == 0) 
+		{
+			isPrime = false;
+			break;
+		}
+	}
+
+	return isPrime;
+}
+ 
+
+int Halton::FindPrime(int idx) 
+{
+	if (idx < 1) 
+	{
+		std::cerr << "error: cannot find " << idx << "th prime" << std::endl;
+		return 0;
+	}
+
+	// only even prime number
+	if (idx == 1) return 2;
+
+	int number = 3;
+	int primeFound = 1;
+
+	while (1)
+	{
+		if (IsPrime(number)) ++ primeFound;
+		if (primeFound == idx) break;
+
+		number += 2;
+	}
+
+	return number;
+}
+
+
+void HaltonSequence::TestHalton(int n, int dim)
+{
+	HaltonSequence h(dim);
+	float *haltons = new float[dim];
+
+	for (int i = 1; i <= n; ++ i)
+	{
+		h.GetNext(haltons);
+		std::cout << "halton " << i << " of dim " << dim << " = ";
+
+		for (int j = 0; j < dim; ++ j)
+			std::cout << haltons[j] << " ";
+
+		std::cout << std::endl;
+	}
+}
+
+
+HaltonSequence::HaltonSequence(int dim)
+{
+	for (int i = 0; i < dim; ++ i)
+	{
+		mHaltons.push_back(Halton(i + 1));
+	}
+}
+
+
+void HaltonSequence::GetNext(float *numbers)
+{
+	for (size_t i = 0; i < mHaltons.size(); ++ i)
+	{
+		numbers[i] = mHaltons[i].GetNext();
+	}
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 3221)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 3227)
@@ -6,8 +6,7 @@
 using namespace CHCDemoEngine;
 
-HaltonSequence SphericalSampleGenerator3::sHalton;
-HaltonSequence PoissonDiscSampleGenerator2::sHalton;
-HaltonSequence RandomSampleGenerator2::sHalton;
-HaltonSequence QuadraticDiscSampleGenerator2::sHalton;
+HaltonSequence PoissonDiscSampleGenerator2D::sHalton(2);
+HaltonSequence RandomSampleGenerator2D::sHalton(2);
+HaltonSequence QuadraticDiscSampleGenerator2D::sHalton(2);
 
 
@@ -17,10 +16,10 @@
 
 
-PoissonDiscSampleGenerator2::PoissonDiscSampleGenerator2(int numSamples, float radius):
-SampleGenerator(numSamples, radius)
-{}
-
-
-void PoissonDiscSampleGenerator2::Generate(float *samples) const
+PoissonDiscSampleGenerator2D::PoissonDiscSampleGenerator2D(int numSamples, float radius):
+SampleGenerator(numSamples, radius)
+{}
+
+
+void PoissonDiscSampleGenerator2D::Generate(float *samples) const
 {
 	// this is a hacky poisson sampling generator which does random dart-throwing on a disc.
@@ -32,5 +31,5 @@
 	const float f_reduction = 0.9f;
 
-	//static HaltonSequence halton;
+
 	float r[2];
 
@@ -59,7 +58,5 @@
 
 			// note: should use halton, but seems somewhat broken
-			//r[0] = RandomValue(.0f, mRadius);
-			//r[1] = RandomValue(.0f, mRadius);
-			sHalton.GetNext(2, r);
+			sHalton.GetNext(r);
 
 			// scale to -1 .. 1
@@ -72,5 +69,5 @@
 			if ((rx * rx + ry * ry > mRadius * mRadius) 
 				// also avoid case that sample exactly in center 			
-				|| (distanceSquared <= 1e-3f)
+				//|| (distanceSquared <= 1e-3f)
 				)
 				continue;
@@ -108,10 +105,10 @@
 
 
-RandomSampleGenerator2::RandomSampleGenerator2(int numSamples, float radius):
-SampleGenerator(numSamples, radius)
-{}
-
-
-void RandomSampleGenerator2::Generate(float *samples) const
+RandomSampleGenerator2D::RandomSampleGenerator2D(int numSamples, float radius):
+SampleGenerator(numSamples, radius)
+{}
+
+
+void RandomSampleGenerator2D::Generate(float *samples) const
 {
 	Sample2 *s = (Sample2 *)samples;
@@ -123,7 +120,5 @@
 	while (numSamples < mNumSamples)
 	{
-		//r[0] = RandomValue(-mRadius, mRadius);
-		//r[1] = RandomValue(-mRadius, mRadius);
-		sHalton.GetNext(2, r);
+		sHalton.GetNext(r);
 		
 		const float rx = r[0] * 2.0f - 1.0f;
@@ -142,10 +137,10 @@
 
 
-SphericalSampleGenerator3::SphericalSampleGenerator3(int numSamples, float radius):
-SampleGenerator(numSamples, radius)
-{}
-
-
-void SphericalSampleGenerator3::Generate(float *samples) const
+SphericalSampleGenerator3D::SphericalSampleGenerator3D(int numSamples, float radius):
+SampleGenerator(numSamples, radius)
+{}
+
+
+void SphericalSampleGenerator3D::Generate(float *samples) const
 {
 	float r[2];
@@ -156,6 +151,4 @@
 		r[0] = RandomValue(0, 1);
 		r[1] = RandomValue(0, 1);
-
-		//sHalton.GetNext(2, r);
 
 		// create stratified samples over sphere
@@ -170,10 +163,10 @@
 
 
-QuadraticDiscSampleGenerator2::QuadraticDiscSampleGenerator2(int numSamples, float radius):
-SampleGenerator(numSamples, radius)
-{}
-
-
-void QuadraticDiscSampleGenerator2::Generate(float *samples) const
+QuadraticDiscSampleGenerator2D::QuadraticDiscSampleGenerator2D(int numSamples, float radius):
+SampleGenerator(numSamples, radius)
+{}
+
+
+void QuadraticDiscSampleGenerator2D::Generate(float *samples) const
 {
 #if 0
@@ -183,7 +176,5 @@
 	for (int i = 0; i < mNumSamples; ++ i)
 	{
-		//r[0] = samples[i * 2];
-		//r[1] = samples[i * 2 + 1];
-		sHalton.GetNext(2, r);
+		sHalton.GetNext(r);
 
 		// create samples over disc: the sample density
@@ -194,5 +185,5 @@
 #else
 
-	PoissonDiscSampleGenerator2 poisson(mNumSamples, 1.0f);
+	static PoissonDiscSampleGenerator2D poisson(mNumSamples, 1.0f);
 	poisson.Generate(samples);
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h	(revision 2930)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h	(revision 3227)
@@ -47,9 +47,9 @@
 
 
-class RandomSampleGenerator2: public SampleGenerator
+class RandomSampleGenerator2D: public SampleGenerator
 {
 public:
 	
-	RandomSampleGenerator2(int numSamples, float radius);
+	RandomSampleGenerator2D(int numSamples, float radius);
 
 	virtual void Generate(float *samples) const;
@@ -65,9 +65,9 @@
 	according to some d related to the number of samples.
 */
-class PoissonDiscSampleGenerator2: public SampleGenerator
+class PoissonDiscSampleGenerator2D: public SampleGenerator
 {
 public:
 	
-	PoissonDiscSampleGenerator2(int numSamples, float radius);
+	PoissonDiscSampleGenerator2D(int numSamples, float radius);
 
 	virtual void Generate(float *samples) const;
@@ -83,9 +83,9 @@
 	with the distance
 */
-class QuadraticDiscSampleGenerator2: public SampleGenerator
+class QuadraticDiscSampleGenerator2D: public SampleGenerator
 {
 public:
 	
-	QuadraticDiscSampleGenerator2(int numSamples, float radius);
+	QuadraticDiscSampleGenerator2D(int numSamples, float radius);
 
 	virtual void Generate(float *samples) const;
@@ -99,15 +99,11 @@
 /** This class generates random spherical samples.
 */
-class SphericalSampleGenerator3: public SampleGenerator
+class SphericalSampleGenerator3D: public SampleGenerator
 {
 public:
 	
-	SphericalSampleGenerator3(int numSamples, float radius);
+	SphericalSampleGenerator3D(int numSamples, float radius);
 
 	virtual void Generate(float *samples) const;
-
-protected:
-
-	static HaltonSequence sHalton;
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3226)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3227)
@@ -58,4 +58,5 @@
 #include "WalkThroughRecorder.h"
 #include "StatsWriter.h"
+#include "Halton.h"
 
 
@@ -645,5 +646,5 @@
 
 	// this function assign the render queue bucket ids of the materials in beforehand
-	// => probably a little less overhead for new parts of the scene that are not yet assigned
+	// => probably less overhead for new parts of the scene that are not yet assigned
 	PrepareRenderQueue();
 	/// forward rendering is the default
@@ -651,4 +652,12 @@
 	// frame time is restarted every frame
 	frameTimer.Start();
+
+	Halton::TestHalton(7, 1);
+	Halton::TestHalton(7, 2);
+
+	HaltonSequence::TestHalton(15, 2);
+	HaltonSequence::TestHalton(15, 1);
+
+	Halton::TestPrime();
 
 	// the rendering loop
@@ -1405,9 +1414,9 @@
 		break;
 	case '7':
-		ssaoTempCohFactor *= 0.5f;
+		ssaoTempCohFactor *= 1.0f / 1.2f;
 		cout << "new temporal coherence factor: " << ssaoTempCohFactor << endl;
 		break;
 	case '8':
-		ssaoTempCohFactor *= 2.0f;
+		ssaoTempCohFactor *= 1.2f;
 		cout << "new temporal coherence factor: " << ssaoTempCohFactor << endl;
 		break;
@@ -1417,5 +1426,5 @@
 		break;
 	case '0':
-		ssaoKernelRadius *= 1.2f;
+		ssaoKernelRadius *= 1.0f / 0.8f;
 		cout << "new ssao kernel radius: " << ssaoKernelRadius << endl;
 		break;
@@ -1425,5 +1434,5 @@
 		break;
 	case 'N':
-		ssaoSampleIntensity *= 1.1f;
+		ssaoSampleIntensity *= 1.0f / 0.9f;
 		cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
 		break;
@@ -1433,5 +1442,5 @@
 		break;
 	case 'O':
-		ssaoFilterRadius *= 1.1f;
+		ssaoFilterRadius *= 1.0f / 0.9f;
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
 		break;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3222)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3227)
@@ -198,5 +198,5 @@
 	case DeferredRenderer::SAMPLING_POISSON:
 		{
-			PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
+			static PoissonDiscSampleGenerator2D poisson(NUM_SAMPLES, 1.0f);
 			poisson.Generate((float *)samples2);
 		}
@@ -204,5 +204,5 @@
 	case DeferredRenderer::SAMPLING_QUADRATIC:
 		{
-			QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
+			static QuadraticDiscSampleGenerator2D g(NUM_SAMPLES, 1.0f);
 			g.Generate((float *)samples2);
 		}
@@ -210,5 +210,5 @@
 	default: // SAMPLING_DEFAULT
 		{
-			RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
+			static RandomSampleGenerator2D g(NUM_SAMPLES, 1.0f);
 			g.Generate((float *)samples2);
 		}
@@ -220,21 +220,17 @@
 {
 	//GLubyte *randomNormals = new GLubyte[mWidth * mHeight * 3];
-	float *randomNormals = new float[w * h * 3];
-
-	static HaltonSequence halton;
-	float r[2];
-
-	for (int i = 0; i < w * h * 3; i += 3)
+	Vector3 *randomNormals = new Vector3[w * h];
+
+	for (int i = 0; i < w * h; ++ i)
 	{
 		// create random samples on a circle
-		r[0] = RandomValue(0, 1);
-		//halton.GetNext(1, r);
-
-		const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
-		
-		randomNormals[i + 0] = cos(theta);
-		randomNormals[i + 1] = sin(theta);
-		randomNormals[i + 2] = 0;
-	}
+		const float r = RandomValue(0, 1);
+
+		const float theta = 2.0f * acos(sqrt(1.0f - r));
+		//randomNormals[i] = Vector3(cos(theta), sin(theta), 0);
+		randomNormals[i] = Vector3(RandomValue(-M_PI, M_PI), 0, 0);
+		//Normalize(randomNormals[i]);
+	}
+
 
 	glEnable(GL_TEXTURE_2D);
@@ -242,10 +238,13 @@
 	glBindTexture(GL_TEXTURE_2D, noiseTex2D);
 		
-	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_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);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, randomNormals);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, (float *)randomNormals);
 
 	glBindTexture(GL_TEXTURE_2D, 0);
@@ -257,42 +256,4 @@
 
 	PrintGLerror("noisetexture");
-}
-
-
-static void CreateNoiseTex1D(int w)
-{
-	float *randomValues = new float[w * 3];
-
-	static HaltonSequence halton;
-	
-	randomValues[0] = randomValues[1] = randomValues[2] = 0;
-
-	for (int i = 3; i < w * 3; i += 3)
-	{
-		// create random samples on a circle
-		randomValues[i + 0] = 20.0f * RandomValue(0, 1) / 512.0f;
-		randomValues[i + 1] = 20.0f * RandomValue(0, 1) / 384.0f;
-		randomValues[i + 2] = 0;
-	}
-
-	glEnable(GL_TEXTURE_2D);
-	glGenTextures(1, &noiseTex1D);
-	glBindTexture(GL_TEXTURE_2D, noiseTex1D);
-		
-	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_WRAP_S, GL_REPEAT);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, 1, 0, GL_RGB, GL_FLOAT, randomValues);
-
-	glBindTexture(GL_TEXTURE_2D, 0);
-	glDisable(GL_TEXTURE_2D);
-
-	delete [] randomValues;
-
-	cout << "created noise texture 1D" << endl;
-
-	PrintGLerror("noisetexture 1D");
 }
 
@@ -385,4 +346,5 @@
 	// for performance reasons we use a smaller texture and repeat it over the screen
 	CreateNoiseTex2D(mIllumFbo->GetWidth() / 4, mIllumFbo->GetWidth() / 4);
+	//CreateNoiseTex2D(mIllumFbo->GetWidth(), mIllumFbo->GetWidth());
 	
 	mProjViewMatrix = IdentityMatrix();
@@ -526,5 +488,5 @@
 
 	float filterWeights[NUM_PCF_TABS];
-	PoissonDiscSampleGenerator2 poisson2(NUM_PCF_TABS, 1.0f);
+	PoissonDiscSampleGenerator2D poisson2(NUM_PCF_TABS, 1.0f);
 	poisson2.Generate((float *)pcfSamples);
 
@@ -625,5 +587,5 @@
 	const float filterWidth = 1.0f;
 
-	PoissonDiscSampleGenerator2 poisson(NUM_SSAO_FILTER_SAMPLES, 1.0f);
+	PoissonDiscSampleGenerator2D poisson(NUM_SSAO_FILTER_SAMPLES, 1.0f);
 	poisson.Generate((float *)ssaoFilterOffsets);
 
@@ -777,5 +739,5 @@
 	sCgSsaoProgram->SetTexture(i ++, attribsTex);
 	sCgSsaoProgram->SetValue1f(i ++, mKernelRadius);
-	sCgSsaoProgram->SetValue1f(i ++, mSampleIntensity);
+	sCgSsaoProgram->SetValue1f(i ++, mSampleIntensity * mKernelRadius);
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3226)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3227)
@@ -41,12 +41,6 @@
 #camDirection=1 0 0
 
-#camPosition=468.025 267.591 182.478
-#camDirection=0.937282 0.348573 -0
-
-#camPosition=470.548 265.479 181.578
-#camDirection=-0.0383892 0.999263 -0
-
-camPosition=470.541 267.286 181.978
-camDirection=-0.100954 0.993856 -0.045363
+camPosition=468.025 267.591 182.478
+camDirection=0.937282 0.348573 -0
 
 #lightDirection=-0.8f 1.0f -0.7f
@@ -57,11 +51,9 @@
 ## window options
 
-winWidth=800
-winHeight=600
+#winWidth=800
+#winHeight=600
 
-#winWidth=1024
-#winHeight=768
-#winWidth=512
-#winHeight=384
+winWidth=1024
+winHeight=768
 
 useFullScreen=0
@@ -98,7 +90,9 @@
 ssaoUseFullResolution=1
 # ssao kernel radius
-ssaoKernelRadius=8e-1f
+#ssaoKernelRadius=8e-1f
+ssaoKernelRadius=4e-1f
 # ssao sample intensity
-ssaoSampleIntensity=0.1f
+#ssaoSampleIntensity=0.2f
+ssaoSampleIntensity=1.0f
 # ssao temporal coherence factor
 tempCohFactor=1000.0f
