Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleReflectionMinMax/GTPMultipleReflectionMinMax.material
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleReflectionMinMax/GTPMultipleReflectionMinMax.material	(revision 2054)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleReflectionMinMax/GTPMultipleReflectionMinMax.material	(revision 2095)
@@ -35,5 +35,5 @@
 				get_minmax true
 				min_var_name min
-				max_var_name max				
+				max_var_name Max				
 			}
 			RenderTechnique ColorCubeMap
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection.hlsl	(revision 2095)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection.hlsl	(revision 2095)
@@ -0,0 +1,348 @@
+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 50  //80
+#define MIN_LIN_ITERATIONCOUNT 15  //60
+#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;
+ 
+ int shootL = 0, shootP = 0;          
+ bool found = false; 
+ 
+ float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
+ dt = max(dt, MIN_LIN_ITERATIONCOUNT);
+ dt = 1.0 / dt;
+    
+ float t = 0.01;//dt;
+ float pa;
+ 
+ //Linear iteration
+ while(t <= 1.0 && !found)
+ {
+   dp = a * t / (1 - t);
+   p = x + R * dp;
+   pa = readDistanceCubeMap(mp, p);
+      
+   if(pa > 0)
+   {
+    ppp = length(p) / pa;
+    if(ppp < 1)
+      shootP = -1;
+    else 
+      shootP = 1;      
+    if(shootL * shootP == -1)
+      found = true;
+    else
+    {
+      shootL = shootP;
+      dl = dp;
+      llp = ppp;
+    }
+   }
+   else
+     shootL = 0;
+      
+   t += dt;  
+ }
+
+ if(!found)
+  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 Shaded_OUT
+{
+ float4 vPos : POSITION;
+ float4 wNormal : TEXCOORD0;
+ float4 wPos    : TEXCOORD1; 
+};
+
+float4 MultipleReflectionPS(Shaded_OUT IN,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 cameraPos,
+							uniform float3 lastCenter) : COLOR0
+{	
+	 float4 I = float4(0,0,0,0);
+			
+	 float3 N = normalize(IN.wNormal.xyz);
+	 float3 x = IN.wPos.xyz - lastCenter;
+	 float3 V  = (IN.wPos.xyz - cameraPos);
+	 
+	 V = normalize(V);
+	 float3 l;
+
+		
+	//return readCubeMap(NormDistMap2, x).a /2.0 + 0.000000000001 * x.x;
+	  
+	 int depth = 0;
+	
+	 while(depth < MAX_RAY_DEPTH)
+	 {
+	   float3 R;  
+	   R = normalize(reflect( V, N));	  
+	  	
+	   float3 Nl;
+	   float4 Il = 0;
+	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+	   if(Il.a == 0)
+	   {	   
+		  depth += 1;		 
+	   }
+	   else
+	   {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	   }
+	   x = l;	   
+	   N = Nl;
+	   V = R;   
+	   
+	}
+	if(I.a == 0)
+	   I = readCubeMap(CubeMap, l);
+	
+	return I;
+}
+
+float4 MultipleRefractionPS(Shaded_OUT IN,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 cameraPos,
+							uniform float3 lastCenter,
+							uniform float sFresnel,
+							uniform float refIndex ) : COLOR0
+{
+	 float4 I = float4(0,0,0,0);
+			
+	 float3 N = normalize(IN.wNormal.xyz);
+	 float3 x = IN.wPos.xyz - lastCenter;
+	 float3 V  = (IN.wPos.xyz - cameraPos);
+	  V = normalize(V);
+	 
+	 float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);	 
+	
+	 float3 l;
+	 float4 Irefl;
+	 int depth = 0;
+	
+	 while(depth < MAX_RAY_DEPTH)
+	 {
+	   float3 R;
+	   R = normalize(reflect( V, N));
+	  	
+	   float3 Nl;
+	   float4 Il;
+	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+	   if(Il.a == 0)
+	   {
+		   depth += 1;		 
+	   }
+	   else
+	   {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	   }
+	   x = l;	   
+	   N = Nl;
+	   V = R;
+	}
+	if(I.a == 0)
+	   I = readCubeMap(CubeMap, l);
+	Irefl = I;
+	
+	{
+	float4 Irefr;
+	N = normalize(IN.wNormal.xyz);
+	x = IN.wPos.xyz - lastCenter;
+	V  = (IN.wPos.xyz - cameraPos);
+	depth = 0;
+	
+	while(depth < MAX_RAY_DEPTH)
+	{
+	  float3 R;  
+	  
+	  float ri = refIndex;
+	 
+	  if(dot(V,N) > 0)
+	  {
+		ri = 1.0 / ri;
+		N = -N;	    
+	  }
+	  R = refract( V, N, ri);
+	  if(dot(R,R) == 0) R = reflect( V, N); 
+					
+	  float3 Nl;
+	  float4 Il;
+	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+	  if(Il.a == 0)
+	  {
+		   depth += 1;		 
+	  }
+	  else
+	  {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	  }
+	  x = l;	   
+	  N = normalize(Nl);
+	  V = R;	   	   
+	}
+	
+	if(I.a == 0)
+	   I = readCubeMap(CubeMap, l);
+	Irefr = I;
+	    
+	I = Irefl * F + (1.0 - F) * Irefr;	
+    }
+ 	return I;
+}
+
+float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
+									uniform samplerCUBE DistanceMap : register(s0),
+									uniform samplerCUBE NormDistMap1 : register(s1),
+									uniform samplerCUBE NormDistMap2 : register(s2),
+									uniform float3 cameraPos,
+									uniform float3 lastCenter,
+									uniform float refIndex) : COLOR0
+{
+	float4 I = float4(0,0,0,0);
+		 
+	float3 N = normalize(IN.wNormal.xyz);
+	float3 x = IN.wPos.xyz - lastCenter;
+	float3 V  = (IN.wPos.xyz - cameraPos);
+	V = normalize(V);
+	float3 l;
+	int depth = 0;
+		
+	while(depth < MAX_RAY_DEPTH)
+	{
+	  float3 R;  
+	  
+	  float ri = refIndex;
+	 
+	  if(dot(V,N) > 0)
+	  {
+		ri = 1.0 / ri;
+		N = -N;	    
+	  }
+	  R = refract( V, N, ri);
+	  if(dot(R,R) == 0) R = reflect( V, N); 
+					
+	  float3 Nl;
+	  float4 Il;
+	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, Il, Nl);
+	  if(Il.a == 0)
+	  {
+		   depth += 1;		 
+	  }
+	  else
+	  {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	  }
+	  x = l;	   
+	  N = normalize(Nl);
+	  V = R;	   	   
+	}
+	
+	return float4(l,1);
+}
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection.hlsl	(revision 2054)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection.hlsl	(revision 2095)
@@ -11,8 +11,8 @@
 }
 
-#define MAX_LIN_ITERATIONCOUNT 30  //80
-#define MIN_LIN_ITERATIONCOUNT 20  //60
+#define MAX_LIN_ITERATIONCOUNT 50  //80
+#define MIN_LIN_ITERATIONCOUNT 15  //60
 #define SECANT_ITERATIONCOUNT 1
-#define MAX_RAY_DEPTH 2
+#define MAX_RAY_DEPTH 4
 
 void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
@@ -219,49 +219,13 @@
 	  V = normalize(V);
 	 
-	 float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);	 
-	
-	 float3 l;
-	 float4 Irefl;
+	 float F;
 	 int depth = 0;
-	
-	 while(depth < MAX_RAY_DEPTH)
-	 {
-	    float3 R;  
-	   R = normalize(reflect( V, N));	  
-	  	
-	   float3 Nl;
-	   float4 Il;
-	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
-	   if(Il.a == 0)
-	   {
-		   depth += 1;		 
-	   }
-	   else
-	   {
-		   I = Il;
-		   depth = MAX_RAY_DEPTH;
-	   }
-	   x = l;	   
-	   N = Nl;
-	   V = R;   
-	   
-	}
-	if(I.a == 0)
-	   I = readCubeMap(CubeMap, l);
-	Irefl = I;
-	
-	{
-	float4 Irefr;
-	N = normalize(IN.wNormal.xyz);
-	x = IN.wPos.xyz - lastCenter;
-	V  = (IN.wPos.xyz - cameraPos);
-	depth = 0;
+	F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);	 
 	
 	while(depth < MAX_RAY_DEPTH)
 	{
 	  float3 R;  
-	  
-	  float ri = refIndex;
-	 
+	  	 
+	  float ri = refIndex;	 
 	  if(dot(V,N) > 0)
 	  {
@@ -270,6 +234,60 @@
 	  }
 	  R = refract( V, N, ri);
-	  if(dot(R,R) == 0) R = reflect( V, N); 
-					
+	  if(dot(R,R) == 0) R = reflect( V, N);
+	  					
+	  float3 Nl;
+	  float4 Il;
+	  float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
+	  if(Il.a == 0)
+	  {
+		  //I = readCubeMap(CubeMap, l);
+		   depth += 1;		 
+	  }
+	  else
+	  {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	  }
+	  x = l;	   
+	  N = normalize(Nl);
+	  V = R;	   	   
+	}  
+	    
+	I *= (1.0 - F);	
+    
+	return I;
+}
+
+float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
+									uniform samplerCUBE DistanceMap  : register(s0),
+									uniform samplerCUBE NormDistMap1 : register(s1),
+									uniform samplerCUBE NormDistMap2 : register(s2),
+									uniform samplerCUBE CubeMap      : register(s3), //NOT USED
+									uniform float3 cameraPos,
+									uniform float3 lastCenter,
+									uniform float refIndex) : COLOR0
+{
+	 float4 I = 0;		
+	 float3 N = normalize(IN.wNormal.xyz);
+	 float3 x = IN.wPos.xyz - lastCenter;
+	 float3 V  = (IN.wPos.xyz - cameraPos);
+	 V = normalize(V);
+	 
+	int depth = 0;
+	float3 l;
+	
+	while(depth < MAX_RAY_DEPTH)
+	{
+	  float3 R;  
+	  	 
+	  float ri = refIndex;	 
+	  if(dot(V,N) > 0)
+	  {
+		ri = 1.0 / ri;
+		N = -N;	    
+	  }
+	  R = refract( V, N, ri);
+	  if(dot(R,R) == 0) R = reflect( V, N);
+	  					
 	  float3 Nl;
 	  float4 Il;
@@ -277,73 +295,20 @@
 	  if(Il.a == 0)
 	  {
-		   depth += 1;		 
+		  depth += 1;		 
 	  }
 	  else
 	  {
-		   I = Il;
-		   depth = MAX_RAY_DEPTH;
+		  I = Il;
+		  depth = MAX_RAY_DEPTH;
 	  }
 	  x = l;	   
 	  N = normalize(Nl);
 	  V = R;	   	   
-	}
-	
+	}  
 	if(I.a == 0)
-	   I = readCubeMap(CubeMap, l);
-	Irefr = I;
-	    
-	I = Irefl * F + (1.0 - F) * Irefr;	
-    }
- 	return I;
-}
-
-float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
-									uniform samplerCUBE DistanceMap : register(s0),
-									uniform samplerCUBE NormDistMap1 : register(s1),
-									uniform samplerCUBE NormDistMap2 : register(s2),
-									uniform float3 cameraPos,
-									uniform float3 lastCenter,
-									uniform float refIndex) : COLOR0
-{
-	float4 I = float4(0,0,0,0);
-		 
-	float3 N = normalize(IN.wNormal.xyz);
-	float3 x = IN.wPos.xyz - lastCenter;
-	float3 V  = (IN.wPos.xyz - cameraPos);
-	V = normalize(V);
-	float3 l;
-	int depth = 0;
-		
-	while(depth < MAX_RAY_DEPTH)
-	{
-	  float3 R;  
-	  
-	  float ri = refIndex;
-	 
-	  if(dot(V,N) > 0)
-	  {
-		ri = 1.0 / ri;
-		N = -N;	    
-	  }
-	  R = refract( V, N, ri);
-	  if(dot(R,R) == 0) R = reflect( V, N); 
-					
-	  float3 Nl;
-	  float4 Il;
-	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, Il, Nl);
-	  if(Il.a == 0)
-	  {
-		   depth += 1;		 
-	  }
-	  else
-	  {
-		   I = Il;
-		   depth = MAX_RAY_DEPTH;
-	  }
-	  x = l;	   
-	  N = normalize(Nl);
-	  V = R;	   	   
-	}
-	
-	return float4(l,1);
-}
+		I = 0;
+	else
+		I = float4(l,1);
+	
+	return I;
+}
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleRefractionMinMax/GTPMultipleRefractionMinMax.material
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleRefractionMinMax/GTPMultipleRefractionMinMax.material	(revision 2095)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/multipleRefractionMinMax/GTPMultipleRefractionMinMax.material	(revision 2095)
@@ -0,0 +1,106 @@
+fragment_program GTP/MultiBounce/Refraction_MinMax_PS hlsl
+{
+	
+	source GTPMultipleReflection_MinMax.hlsl
+    entry_point MultipleRefractionPS
+	target ps_3_0
+	flow_control prefer
+}
+
+material GTP/MultiBounce/Refractor_MinMax
+{ 
+   technique 
+   { 
+      pass 
+      { 
+        //cull_hardware none
+		IllumTechniques
+		{
+			RenderTechnique ColorCubeMap
+			{
+				resolution 1024
+				update_interval		0
+				distance_calc false
+				face_angle_calc false
+				update_all_face true
+								
+			}
+			RenderTechnique DistanceCubeMap
+			{
+				resolution 1024
+				update_interval		0
+				distance_calc false
+				face_angle_calc false
+				update_all_face true
+				get_minmax true
+				min_var_name min
+				max_var_name Max				
+			}
+			RenderTechnique ColorCubeMap
+			{
+				resolution 1024
+				layer 1
+				texture_unit_id 2
+				update_interval		0
+				distance_calc false
+				face_angle_calc false
+				update_all_face true
+				render_env false
+				render_self true
+				self_material GTP/MultiBounce/NormalDistanceCCW
+				get_minmax true
+				min_var_name min1
+				max_var_name max1			
+			}
+			RenderTechnique ColorCubeMap
+			{
+				resolution 1024
+				layer 2
+				texture_unit_id 3
+				update_interval		0
+				distance_calc false
+				face_angle_calc false
+				update_all_face true
+				render_env false
+				render_self true
+				self_material GTP/MultiBounce/NormalDistanceCW
+				get_minmax true
+				min_var_name min2
+				max_var_name max2
+			}				
+		 }
+		 vertex_program_ref GTP/Basic/Shaded_VS
+         {       
+            param_named_auto WorldViewProj worldviewproj_matrix 
+    	    param_named_auto World world_matrix
+    	    param_named_auto WorldInv inverse_world_matrix	    
+         } 
+		 fragment_program_ref GTP/MultiBounce/Refraction_MinMax_PS
+         { 
+			param_named_auto cameraPos camera_position						
+		 } 
+		
+		//Cube map of environment
+		texture_unit
+		{
+			//filtering none
+		}
+		//Cube map of environment distances
+		texture_unit
+		{
+			filtering none
+		}
+		
+		//Cube map of reflective object's normals and distances CCW
+		texture_unit
+		{
+			filtering none
+		}		
+		//Cube map of reflective object's normals and distances CW
+		texture_unit
+		{
+			filtering none
+		}
+	  }
+    }
+}
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection_MinMax.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection_MinMax.hlsl	(revision 2095)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection_MinMax.hlsl	(revision 2095)
@@ -0,0 +1,480 @@
+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 80  //80
+#define MIN_LIN_ITERATIONCOUNT 60  //60
+#define SECANT_ITERATIONCOUNT 1
+#define MAX_RAY_DEPTH 2
+
+//#define METHOD1
+
+void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
+					float2 minMax,					
+                    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;
+ 
+ int shootL = 0, shootP = 0;          
+ bool found = false; 
+ 
+ float min = minMax.x;
+ float maximum = minMax.y;
+ 
+ float minD = 0;
+ float maxD = 0;
+ {
+  	float a = dot(R,R);
+	float b = 2 * dot(R, x);
+	float c = dot(x,x) - min * min; 
+	float c2 = dot(x,x) - maximum * maximum; 
+	
+	float dis = b*b - 4*a*c;
+	float dis2 = b*b - 4*a*c2;
+	
+	float t1 = (-b + sqrt(dis))/ 2.0 * a;
+	float t2 = (-b - sqrt(dis))/ 2.0 * a;
+    float t3 = (-b + sqrt(dis2))/ 2.0 * a;
+	float t4 = (-b - sqrt(dis2))/ 2.0 * a;
+	
+	int numvalids = 0;
+	if(t1 > 0)
+	{
+	 numvalids++;
+	 if(t1 > maxD)maxD = t1;
+	 if(t1 < minD || minD == 0)minD = t1;
+	}
+	if(t2 > 0)
+	{
+	 numvalids++;
+	 if(t2 > maxD)maxD = t2;
+	 if(t2 < minD || minD == 0)minD = t2;
+	}
+	if(t3 > 0)
+	{
+	 numvalids++;
+	 if(t3 > maxD)maxD = t3;
+	 if(t3 < minD || minD == 0)minD = t3;
+	}
+	if(t4 > 0)
+	{
+	 numvalids++;
+	 if(t4 > maxD)maxD = t4;
+	 if(t4 < minD || minD == 0)minD = t4;
+	}
+	
+	if(numvalids % 2 == 1)
+	 minD = 0.01;
+	if(numvalids == 0)
+	 minD = maxD + 1.0;	
+ }
+ 
+#ifdef METHOD1
+ int iterationNeeded = MAX_LIN_ITERATIONCOUNT;// + (dot(normalize(x), R) + 1.0) / 2.0 * (MAX_LIN_ITERATIONCOUNT - MIN_LIN_ITERATIONCOUNT);
+ float pa;
+ float dD = (maxD - minD) / (float) iterationNeeded ;
+ dp = minD; 
+ 
+ //Linear iteration
+ while(dp <= maxD && !found)
+ {
+	 
+#else
+ float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
+ dt = max(dt, MIN_LIN_ITERATIONCOUNT);
+ dt = 1.0 / dt;
+ 
+ float minT = minD / (a + minD);
+ float maxT = maxD / (a + maxD);
+ 
+ float t = minT;//dt;
+ float pa;
+ 
+ while(t <= maxT && !found)
+ {
+	 dp = a * t / (1 - t);
+#endif
+
+   p = x + R * dp;
+   pa = readDistanceCubeMap(mp, p);
+      
+   if(pa > 0)
+   {
+    ppp = length(p) / pa;
+    if(ppp < 1)
+      shootP = -1;
+    else 
+      shootP = 1;      
+    if(shootL * shootP == -1)
+      found = true;
+    else
+    {
+      shootL = shootP;
+      dl = dp;
+      llp = ppp;
+    }
+   }
+   else
+     shootL = 0;
+ 
+ #ifdef METHOD1     
+   dp += dD; 
+ #else 
+   t += dt;
+ #endif
+ }
+
+ if(!found)
+  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,
+           float2 minMax,
+           float2 minMax1,
+		   float2 minMax2,		   
+           out float4 Il, out float3 Nl)
+{
+ float dl1 = 0, dp1, llp1, ppp1;
+ float3 p1;
+ linearSearch(x, R, N, mp1, minMax1, p1, dl1, dp1, llp1, ppp1);
+ float dl2 = 0, dp2, llp2, ppp2;
+ float3 p2;
+ linearSearch(x, R, N, mp2, minMax2, 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, minMax, p, dl, dp, llp, ppp);
+    if(dot(p,p) != 0)
+    {
+     Il.a = 1;    
+     secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
+     Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb;  
+    }
+    else
+     Il = float4(0,0,0,0);
+ }
+ 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;
+    }    
+ } 
+ return p;
+}
+
+struct Shaded_OUT
+{
+ float4 vPos : POSITION;
+ float4 wNormal : TEXCOORD0;
+ float4 wPos    : TEXCOORD1; 
+};
+
+
+float4 MultipleReflectionPS(Shaded_OUT IN,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 cameraPos,
+							uniform float3 lastCenter,
+							uniform float4 min,
+							uniform float4 min1,
+							uniform float4 min2,
+							uniform float4 Max,
+							uniform float4 max1,
+							uniform float4 max2) : COLOR0
+{
+	float2 miniMaxi1;
+    miniMaxi1.x = min.a;
+    miniMaxi1.y = Max.a;
+   
+    float2 miniMaxi2;
+    miniMaxi2.x = min1.a;
+    miniMaxi2.y = max1.a;
+   
+    float2 miniMaxi3;
+    miniMaxi3.x = min2.a;
+    miniMaxi3.y = max2.a;
+	 		
+	 float3 N = normalize(IN.wNormal.xyz);
+	 float3 x = IN.wPos.xyz - lastCenter;
+	 float3 V  = (IN.wPos.xyz - cameraPos);
+		 
+	 float4 I = float4(0,0,0,0);
+	 V = normalize(V);
+	 float3 l;
+	 int depth = 0;
+	
+	 while(depth < MAX_RAY_DEPTH)
+	 {
+	   float3 R;  
+	   R = normalize(reflect( V, N));	  
+	  	
+	   float3 Nl;
+	   float4 Il;
+	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
+	   if(Il.a == 0)
+	   {
+		   depth += 1;		 
+	   }
+	   else
+	   {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	   }
+	   x = l;	   
+	   N = Nl;
+	   V = R;   	   
+	}
+	if(I.a == 0)
+	  I = readCubeMap(CubeMap, l);
+	
+	return I;
+}
+
+float4 MultipleRefractionPS(Shaded_OUT IN,
+							uniform samplerCUBE CubeMap : register(s0),
+							uniform samplerCUBE DistanceMap : register(s1),
+							uniform samplerCUBE NormDistMap1 : register(s2),
+							uniform samplerCUBE NormDistMap2 : register(s3),
+							uniform float3 cameraPos,
+							uniform float3 lastCenter,
+							uniform float refIndex,
+							//uniform float sFresnel, //0.04 
+							uniform float4 min,
+							uniform float4 min1,
+							uniform float4 min2,
+							uniform float4 Max,
+							uniform float4 max1,
+							uniform float4 max2) : COLOR0
+{
+	float2 miniMaxi1;
+    miniMaxi1.x = min.a;
+    miniMaxi1.y = Max.a;
+   
+    float2 miniMaxi2;
+    miniMaxi2.x = min1.a;
+    miniMaxi2.y = max1.a;
+   
+    float2 miniMaxi3;
+    miniMaxi3.x = min2.a;
+    miniMaxi3.y = max2.a;
+
+	 float4 I = float4(0,0,0,0);
+			
+	 float3 N = normalize(IN.wNormal.xyz);
+	 float3 x = IN.wPos.xyz - lastCenter;
+	 float3 V  = (IN.wPos.xyz - cameraPos);
+	 
+	 float sFresnel = 0.04;
+	 float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);
+	 
+	 V = normalize(V);
+	 float3 l;
+	 float4 Irefl;
+	 int depth = 0;
+	
+	 while(depth < MAX_RAY_DEPTH)
+	 {
+	    float3 R;  
+	   R = normalize(reflect( V, N));	  
+	  	
+	   float3 Nl;
+	   float4 Il;
+	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
+	   if(Il.a == 0)
+	   {
+		   depth += 1;		 
+	   }
+	   else
+	   {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	   }
+	   x = l;	   
+	   N = Nl;
+	   V = R;   
+	   
+	}
+	if(I.a == 0)
+	   I = readCubeMap(CubeMap, l);
+	Irefl = I;
+	
+	{
+	float4 Irefr;
+	N = normalize(IN.wNormal.xyz);
+	x = IN.wPos.xyz - lastCenter;
+	V  = (IN.wPos.xyz - cameraPos);
+	V = normalize(V);
+	depth = 0;
+	
+	while(depth < MAX_RAY_DEPTH)
+	{
+	  float3 R;  
+	  
+	  float ri = refIndex;
+	 
+	  if(dot(V,N) > 0)
+	  {
+		ri = 1.0 / ri;
+		N = -N;	    
+	  }
+	  R = refract( V, N, ri);
+	  if(dot(R,R) == 0) R = reflect( V, N); 
+					
+	  float3 Nl;
+	  float4 Il;
+	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
+	  if(Il.a == 0)
+	  {
+		   depth += 1;		 
+	  }
+	  else
+	  {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	  }
+	  x = l;	   
+	  N = normalize(Nl);
+	  V = R;	   	   
+	}
+	
+	if(I.a == 0)
+	   I = readCubeMap(CubeMap, l);
+	Irefr = I;
+	    
+	I = Irefl * F + (1.0 - F) * Irefr;
+    }
+ 	return I;
+}
+
+float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
+									uniform samplerCUBE DistanceMap : register(s0),
+									uniform samplerCUBE NormDistMap1 : register(s1),
+									uniform samplerCUBE NormDistMap2 : register(s2),
+									uniform float3 cameraPos,
+									uniform float3 lastCenter,
+									uniform float refIndex,
+									uniform float4 min,
+									uniform float4 min1,
+									uniform float4 min2,
+									uniform float4 max,
+									uniform float4 max1,
+									uniform float4 max2) : COLOR0
+{
+	float2 miniMaxi1;
+    miniMaxi1.x = min.a;
+    miniMaxi1.y = max.a;
+   
+    float2 miniMaxi2;
+    miniMaxi2.x = min1.a;
+    miniMaxi2.y = max1.a;
+   
+    float2 miniMaxi3;
+    miniMaxi3.x = min2.a;
+    miniMaxi3.y = max2.a;
+
+	float4 I = float4(0,0,0,0);
+		 
+	float3 N = normalize(IN.wNormal.xyz);
+	float3 V  = (IN.wPos.xyz - cameraPos);
+	float3 x = IN.wPos.xyz - lastCenter;
+	V = normalize(V);
+	float3 l;
+	int depth = 0;
+	
+	while(depth < MAX_RAY_DEPTH)
+	{
+	  float3 R;  
+	  
+	  float ri = refIndex;
+	 
+	  if(dot(V,N) > 0)
+	  {
+		ri = 1.0 / ri;
+		N = -N;	    
+	  }
+	  R = refract( V, N, ri);
+	  if(dot(R,R) == 0) R = reflect( V, N); 
+					
+	  float3 Nl;
+	  float4 Il;
+	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
+	  if(Il.a == 0)
+	  {
+		   depth += 1;		 
+	  }
+	  else
+	  {
+		   I = Il;
+		   depth = MAX_RAY_DEPTH;
+	  }
+	  x = l;	   
+	  N = normalize(Nl);
+	  V = R;	   	   
+	}
+	
+	return float4(l,1);
+}
Index: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection_MinMax.hlsl
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection_MinMax.hlsl	(revision 2054)
+++ GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection_MinMax.hlsl	(revision 2095)
@@ -11,8 +11,10 @@
 }
 
-#define MAX_LIN_ITERATIONCOUNT 30  //80
-#define MIN_LIN_ITERATIONCOUNT 25  //60
+#define MAX_LIN_ITERATIONCOUNT 80  //80
+#define MIN_LIN_ITERATIONCOUNT 60  //60
 #define SECANT_ITERATIONCOUNT 1
-#define MAX_RAY_DEPTH 2
+#define MAX_RAY_DEPTH 4
+
+//#define METHOD1
 
 void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
@@ -24,4 +26,8 @@
                     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;
  
  int shootL = 0, shootP = 0;          
@@ -29,13 +35,13 @@
  
  float min = minMax.x;
- float max = minMax.y;
- 
- float minT = 0;
- float maxT = 0;
+ float maximum = minMax.y;
+ 
+ float minD = 0;
+ float maxD = 0;
  {
   	float a = dot(R,R);
 	float b = 2 * dot(R, x);
 	float c = dot(x,x) - min * min; 
-	float c2 = dot(x,x) - max * max; 
+	float c2 = dot(x,x) - maximum * maximum; 
 	
 	float dis = b*b - 4*a*c;
@@ -51,39 +57,58 @@
 	{
 	 numvalids++;
-	 if(t1 > maxT)maxT = t1;
-	 if(t1 < minT || minT == 0)minT = t1;
+	 if(t1 > maxD)maxD = t1;
+	 if(t1 < minD || minD == 0)minD = t1;
 	}
 	if(t2 > 0)
 	{
 	 numvalids++;
-	 if(t2 > maxT)maxT = t2;
-	 if(t2 < minT || minT == 0)minT = t2;
+	 if(t2 > maxD)maxD = t2;
+	 if(t2 < minD || minD == 0)minD = t2;
 	}
 	if(t3 > 0)
 	{
 	 numvalids++;
-	 if(t3 > maxT)maxT = t3;
-	 if(t3 < minT || minT == 0)minT = t3;
+	 if(t3 > maxD)maxD = t3;
+	 if(t3 < minD || minD == 0)minD = t3;
 	}
 	if(t4 > 0)
 	{
 	 numvalids++;
-	 if(t4 > maxT)maxT = t4;
-	 if(t4 < minT || minT == 0)minT = t4;
+	 if(t4 > maxD)maxD = t4;
+	 if(t4 < minD || minD == 0)minD = t4;
 	}
 	
 	if(numvalids % 2 == 1)
-	 minT = 0.01;
+	 minD = 0.01;
 	if(numvalids == 0)
-	 minT = maxT + 1.0;	
+	 minD = maxD + 1.0;	
  }
  
+#ifdef METHOD1
  int iterationNeeded = MAX_LIN_ITERATIONCOUNT;// + (dot(normalize(x), R) + 1.0) / 2.0 * (MAX_LIN_ITERATIONCOUNT - MIN_LIN_ITERATIONCOUNT);
  float pa;
- float dt = (maxT - minT) / (float) iterationNeeded ;
- dp = minT;
+ float dD = (maxD - minD) / (float) iterationNeeded ;
+ dp = minD; 
+ 
  //Linear iteration
- while(dp <= maxT && !found)
+ while(dp <= maxD && !found)
  {
+	 
+#else
+ float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
+ dt = max(dt, MIN_LIN_ITERATIONCOUNT);
+ dt = 1.0 / dt;
+ 
+ float minT = max(minD / (a + minD) - dt, dt);
+ float maxT = maxD / (a + maxD) + dt;
+ 
+ float t = minT;//dt;
+ float pa;
+ 
+ while(t <= maxT && !found)
+ {
+	 dp = a * t / (1 - t);
+#endif
+
    p = x + R * dp;
    pa = readDistanceCubeMap(mp, p);
@@ -107,6 +132,10 @@
    else
      shootL = 0;
-      
-   dp += dt;  
+ 
+ #ifdef METHOD1     
+   dp += dD; 
+ #else 
+   t += dt;
+ #endif
  }
 
@@ -214,5 +243,5 @@
 							uniform float4 min1,
 							uniform float4 min2,
-							uniform float4 max,
+							uniform float4 Max,
 							uniform float4 max1,
 							uniform float4 max2) : COLOR0
@@ -220,5 +249,5 @@
 	float2 miniMaxi1;
     miniMaxi1.x = min.a;
-    miniMaxi1.y = max.a;
+    miniMaxi1.y = Max.a;
    
     float2 miniMaxi2;
@@ -258,9 +287,8 @@
 	   x = l;	   
 	   N = Nl;
-	   V = R;   
-	   
+	   V = R;   	   
 	}
 	if(I.a == 0)
-	   I = readCubeMap(CubeMap, l);
+	  I = readCubeMap(CubeMap, l);
 	
 	return I;
@@ -275,9 +303,9 @@
 							uniform float3 lastCenter,
 							uniform float refIndex,
-							//uniform float sFresnel, //0.04 
+							uniform float sFresnel, //0.04 
 							uniform float4 min,
 							uniform float4 min1,
 							uniform float4 min2,
-							uniform float4 max,
+							uniform float4 Max,
 							uniform float4 max1,
 							uniform float4 max2) : COLOR0
@@ -285,5 +313,5 @@
 	float2 miniMaxi1;
     miniMaxi1.x = min.a;
-    miniMaxi1.y = max.a;
+    miniMaxi1.y = Max.a;
    
     float2 miniMaxi2;
@@ -295,58 +323,20 @@
     miniMaxi3.y = max2.a;
 
-	 float4 I = float4(0,0,0,0);
+	float4 I = float4(0,0,0,0);
 			
 	 float3 N = normalize(IN.wNormal.xyz);
 	 float3 x = IN.wPos.xyz - lastCenter;
 	 float3 V  = (IN.wPos.xyz - cameraPos);
+	  V = normalize(V);
 	 
-	 float sFresnel = 0.04;
-	 float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);
-	 
-	 V = normalize(V);
-	 float3 l;
-	 float4 Irefl;
+	 float F;
 	 int depth = 0;
-	
-	 while(depth < MAX_RAY_DEPTH)
-	 {
-	    float3 R;  
-	   R = normalize(reflect( V, N));	  
-	  	
-	   float3 Nl;
-	   float4 Il;
-	   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
-	   if(Il.a == 0)
-	   {
-		   depth += 1;		 
-	   }
-	   else
-	   {
-		   I = Il;
-		   depth = MAX_RAY_DEPTH;
-	   }
-	   x = l;	   
-	   N = Nl;
-	   V = R;   
-	   
-	}
-	if(I.a == 0)
-	   I = readCubeMap(CubeMap, l);
-	Irefl = I;
-	
-	{
-	float4 Irefr;
-	N = normalize(IN.wNormal.xyz);
-	x = IN.wPos.xyz - lastCenter;
-	V  = (IN.wPos.xyz - cameraPos);
-	V = normalize(V);
-	depth = 0;
+	F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);	 
 	
 	while(depth < MAX_RAY_DEPTH)
 	{
 	  float3 R;  
-	  
-	  float ri = refIndex;
-	 
+	  	 
+	  float ri = refIndex;	 
 	  if(dot(V,N) > 0)
 	  {
@@ -355,11 +345,12 @@
 	  }
 	  R = refract( V, N, ri);
-	  if(dot(R,R) == 0) R = reflect( V, N); 
-					
+	  if(dot(R,R) == 0) R = reflect( V, N);
+	  					
 	  float3 Nl;
 	  float4 Il;
-	  l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
+	  float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
 	  if(Il.a == 0)
 	  {
+		  //I = readCubeMap(CubeMap, l);
 		   depth += 1;		 
 	  }
@@ -372,13 +363,9 @@
 	  N = normalize(Nl);
 	  V = R;	   	   
-	}
-	
-	if(I.a == 0)
-	   I = readCubeMap(CubeMap, l);
-	Irefr = I;
+	}  
 	    
-	I = Irefl * F + (1.0 - F) * Irefr;
-    }
- 	return I;
+	I *= (1.0 - F);	
+    
+	return I;
 }
 
