Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/scripts/MetalTeapot.material
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/scripts/MetalTeapot.material	(revision 1854)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/scripts/MetalTeapot.material	(revision 1859)
@@ -119,6 +119,9 @@
 fragment_program MetalMultipleBouncePS hlsl
 {
-	source MetalTeapot.hlsl
-	entry_point MetalMultipleBouncePS
+	//source MetalTeapot.hlsl
+	//entry_point MetalMultipleBouncePS
+	source MetalTeapotNew.hlsl
+    entry_point mainPS
+
 	target ps_3_0
 	flow_control prefer
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapot.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapot.hlsl	(revision 1854)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapot.hlsl	(revision 1859)
@@ -37,5 +37,5 @@
     
     	
-	bool overshoot = false, undershoot = true;
+	bool overshoot = false, undershoot = false;
 	float dp, dl = 0, ppp, llp;
 	float lR = readDistanceCubeMap(mp, R);
@@ -53,7 +53,7 @@
 	ppp = length(p) / dist;
 	*/
-	t = 0;	
-		
-	while(t < 1.0 && !overshoot)
+	t = dt;	
+		
+	while(t <= 1.0 && !overshoot)
 	{
 		dp = a * t / (1 - t);
@@ -75,5 +75,5 @@
 			}
 		}
-		else 
+		else
 			undershoot = false;
 	
@@ -81,6 +81,6 @@
 	}
 	
-	if(t >= 1.0 && undershoot && dist)
-		overshoot = true;	
+	//if(t >= 1.0 && undershoot && dist)
+	//	overshoot = true;	
 	
 	if(overshoot)
@@ -249,5 +249,5 @@
 		float d1 = Hit(mPos, R, NormDistMap1, newDir1);
 		float3 normal1 = readCubeMap(NormDistMap1, newDir1);
-		bool valid1 = dot(normal1, R) < 0 && dot(newDir1,newDir1) != 0;
+		bool valid1 = /*dot(normal1, R) < 0 &&*/ dot(newDir1,newDir1) != 0;
 		if(valid1)
 			newDir1 = 0;
@@ -255,5 +255,5 @@
 		float d2 = Hit(mPos, R, NormDistMap2, newDir2);
 		float3 normal2 = readCubeMap(NormDistMap2, newDir2);
-		bool valid2 = dot(normal2, R) < 0 && dot(newDir2,newDir2) != 0;
+		bool valid2 = /*dot(normal2, R) < 0 &&*/ dot(newDir2,newDir2) != 0;
 		if(valid2)
 			newDir2 = 0;
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapotNew.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapotNew.hlsl	(revision 1859)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapotNew.hlsl	(revision 1859)
@@ -0,0 +1,268 @@
+float3 F0;
+
+float4 readCubeMap(samplerCUBE cm, float3 coord)		
+{
+	float4 color = texCUBElod( cm, float4(coord.xy, - coord.z,0) );
+	return color;
+}
+
+float readDistanceCubeMap(samplerCUBE dcm, float3 coord)		
+{
+	float dist = texCUBElod(dcm, float4(coord.xy, - coord.z,0)).a;
+	return dist;
+}
+
+#define MAX_LIN_ITERATIONCOUNT 20
+#define MIN_LIN_ITERATIONCOUNT 6
+#define SECANT_ITERATIONCOUNT 1
+#define MAX_RAY_DEPTH 2
+
+void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
+                    out float3 p,
+                    out float dl,
+                    out float dp,
+                    out float llp,
+                    out float ppp)
+{
+ float3 Ra = abs(R), xa = abs(x);
+ float xm =  max(max(xa.x,xa.y),xa.z);
+ float Rm = max(max(Ra.x,Ra.y),Ra.z);
+ float a = xm / Rm;
+           
+ bool undershoot = true, overshoot = false; 
+ 
+ float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
+ dt = max(dt, MIN_LIN_ITERATIONCOUNT);
+ dt = 1.0 / dt;
+    
+ float t = dt;
+ float pa;
+ bool first = true;
+ //Linear iteration
+ while(t <= 1.0 && !overshoot)
+ {
+   dp = a * t / (1 - t);
+   p = x + R * dp;
+   pa = readDistanceCubeMap(mp, p);
+   if(pa > 0)
+   {
+    ppp = length(p) / pa;
+    if(ppp < 1)
+    {
+      dl = dp;
+      llp = ppp;
+      undershoot = true;
+    }
+    else if(undershoot)
+      overshoot = true;
+   }
+   else
+     undershoot = false;
+   t += dt;  
+ }
+ 
+ if(!overshoot)
+  p = float3(0,0,0);
+ else if(t == 2 * dt)
+ {
+	 float3 hitp = pa * normalize(p);
+    if(dot(normalize(hitp - x), N) < 0.1f)
+	   p = float3(0,0,0);
+ }
+}
+
+void secantSearch(float3 x, float3 R, samplerCUBE mp, 
+	               float dl,
+	               float dp,
+	               float llp,
+	               float ppp,
+	               out float3 p)
+{
+  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
+  {
+   float dnew;
+   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
+   p = x + R * dnew;
+   half pppnew = length(p) / readDistanceCubeMap(mp, p);
+   if(pppnew < 1)
+   {
+    llp = pppnew;
+    dl = dnew;
+   }
+   else
+   {
+    ppp = pppnew;
+    dp = dnew;
+   }
+  }
+}
+
+float3 Hit(float3 x, float3 R, float3 N, 
+           samplerCUBE mp1,
+           samplerCUBE mp2,
+           samplerCUBE mp3Color,
+           samplerCUBE mp3Dist,
+           out float4 Il, out float3 Nl)
+{
+ float dl1 = 0, dp1, llp1, ppp1;
+ float3 p1;
+ linearSearch(x, R, N, mp1, p1, dl1, dp1, llp1, ppp1);
+ float dl2 = 0, dp2, llp2, ppp2;
+ float3 p2;
+ linearSearch(x, R, N, mp2, p2, dl2, dp2, llp2, ppp2);
+ 
+ bool valid1 = dot(p1,p1) != 0;
+ bool valid2 = dot(p2,p2) != 0;
+		
+ float dl, dp, llp, ppp;
+ float3 p;
+ 
+ if(!valid1 && ! valid2)
+ {
+    linearSearch(x, R, N, mp3Dist, p, dl, dp, llp, ppp);
+    Il.a = 1; 
+    secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
+    Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb;  
+ }
+ else
+ {
+    if( !valid2 || (valid1 && dp1 < dp2))
+    {
+     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
+     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
+     p = p1;
+    }
+    else
+    {
+     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
+     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
+     p = p2;
+    }
+    Il.a = 0;   
+ }
+ 
+ return p;
+}
+
+struct VertOut
+{
+	float3 wPos	: TEXCOORD1;
+	float3 cPos	: TEXCOORD3;
+	float2 texCoord : TEXCOORD0;
+	float3 mNormal  : TEXCOORD2;
+	float4 hPos : POSITION;			
+};
+
+VertOut DefaultVS(float4 position : POSITION,						
+				float2 texCoord : TEXCOORD0,
+				float3 normal   : NORMAL,
+				uniform float4x4 worldViewProj,
+				uniform float4x4 world,
+				uniform float4x4 worldview,
+				uniform float4x4 worldI	)
+{
+  VertOut OUT;
+  OUT.hPos = mul(worldViewProj, position);
+  OUT.wPos = mul(world, position).xyz;  
+  OUT.cPos = mul(worldview, position).xyz;  
+  OUT.mNormal = mul(normal, worldI);  
+  //OUT.mNormal = normal;
+  OUT.texCoord = texCoord;
+  return OUT;
+}
+
+float4 SingleReflectionPS(VertOut IN,
+							uniform float3 cameraPos,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 lastCenter)
+{
+ float4 Color = float4(1,1,1,1);
+		
+ float3 N = normalize(IN.mNormal);
+ float3 newTexCoord;	
+ float3 x = IN.wPos - lastCenter;
+ float3 V  = (IN.wPos - cameraPos);
+ 
+ V = normalize(V);
+ float3 R = normalize(reflect( V, N));
+ //float3 R = normalize(refract( V, N, 0.8));
+			
+ float3 Nl;
+ float4 Il;
+ float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+ if(Il.a == 0)
+  Il = readCubeMap(CubeMap, l);
+  
+ return Il;
+}
+
+
+float4 MultipleReflectionPS(VertOut IN,
+							uniform float3 cameraPos,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 lastCenter)
+{
+	 float4 I = float4(0,0,0,0);
+			
+	 float3 N = normalize(IN.mNormal);
+	 float3 newTexCoord;	
+	 float3 x = IN.wPos - lastCenter;
+	 float3 V  = (IN.wPos - cameraPos);
+	 
+	 V = normalize(V);
+	 float3 l;
+	 
+	 int depth = 0;
+	 while(depth < MAX_RAY_DEPTH)
+	 {
+	   float3 R = normalize(reflect( V, N));
+	  // float3 R = normalize(refract( V, N, 0.8));
+				
+	   float3 Nl;
+	   float4 Il;
+	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+	   if(Il.a == 0)
+	   {
+		   depth += 1;
+		  // I = float4(0.2,0.2,0.2,1.0);
+	   }
+	   else
+	   {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	   }
+	   x = l;	   
+	   N = normalize(Nl);
+	   V = R;
+	  // if(dot(N, V) > 0) N = -N;
+	}
+	
+	/*if(I.a == 0)
+       I = readCubeMap(CubeMap, l);*/
+  
+ 	return I;
+}
+
+float4 mainPS(VertOut IN,
+							uniform float3 cameraPos,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 lastCenter,
+							uniform float SingleBounce):COLOR
+{
+	float4 Color = 1.0;
+	if(SingleBounce == 1)
+	 Color = SingleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter);
+	else
+	 Color = MultipleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter);
+	 
+	return Color;
+}
