source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/precompiled/app/OgreIllumModule_Resources/materials/GTPAdvancedEnvMap/multibounce/Copy of GTPMultipleReflection_MinMax.hlsl @ 3255

Revision 3255, 10.2 KB checked in by szirmay, 15 years ago (diff)
Line 
1float4 readCubeMap(samplerCUBE cm, float3 coord)               
2{
3        float4 color = texCUBElod( cm, float4(coord.xy, - coord.z,0) );
4        return color;
5}
6
7float readDistanceCubeMap(samplerCUBE dcm, float3 coord)               
8{
9        float dist = texCUBElod(dcm, float4(coord.xy, - coord.z,0)).a;
10        return dist;
11}
12
13#define MAX_LIN_ITERATIONCOUNT 80  //80
14#define MIN_LIN_ITERATIONCOUNT 60  //60
15#define SECANT_ITERATIONCOUNT 1
16#define MAX_RAY_DEPTH 2
17
18//#define METHOD1
19
20void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
21                                        float2 minMax,                                 
22                    out float3 p,
23                    out float dl,
24                    out float dp,
25                    out float llp,
26                    out float ppp)
27{
28 float3 Ra = abs(R), xa = abs(x);
29 float xm =  max(max(xa.x,xa.y),xa.z);
30 float Rm = max(max(Ra.x,Ra.y),Ra.z);
31 float a = xm / Rm;
32 
33 int shootL = 0, shootP = 0;         
34 bool found = false;
35 
36 float min = minMax.x;
37 float maximum = minMax.y;
38 
39 float minD = 0;
40 float maxD = 0;
41 {
42        float a = dot(R,R);
43        float b = 2 * dot(R, x);
44        float c = dot(x,x) - min * min;
45        float c2 = dot(x,x) - maximum * maximum;
46       
47        float dis = b*b - 4*a*c;
48        float dis2 = b*b - 4*a*c2;
49       
50        float t1 = (-b + sqrt(dis))/ 2.0 * a;
51        float t2 = (-b - sqrt(dis))/ 2.0 * a;
52    float t3 = (-b + sqrt(dis2))/ 2.0 * a;
53        float t4 = (-b - sqrt(dis2))/ 2.0 * a;
54       
55        int numvalids = 0;
56        if(t1 > 0)
57        {
58         numvalids++;
59         if(t1 > maxD)maxD = t1;
60         if(t1 < minD || minD == 0)minD = t1;
61        }
62        if(t2 > 0)
63        {
64         numvalids++;
65         if(t2 > maxD)maxD = t2;
66         if(t2 < minD || minD == 0)minD = t2;
67        }
68        if(t3 > 0)
69        {
70         numvalids++;
71         if(t3 > maxD)maxD = t3;
72         if(t3 < minD || minD == 0)minD = t3;
73        }
74        if(t4 > 0)
75        {
76         numvalids++;
77         if(t4 > maxD)maxD = t4;
78         if(t4 < minD || minD == 0)minD = t4;
79        }
80       
81        if(numvalids % 2 == 1)
82         minD = 0.01;
83        if(numvalids == 0)
84         minD = maxD + 1.0;     
85 }
86 
87#ifdef METHOD1
88 int iterationNeeded = MAX_LIN_ITERATIONCOUNT;// + (dot(normalize(x), R) + 1.0) / 2.0 * (MAX_LIN_ITERATIONCOUNT - MIN_LIN_ITERATIONCOUNT);
89 float pa;
90 float dD = (maxD - minD) / (float) iterationNeeded ;
91 dp = minD;
92 
93 //Linear iteration
94 while(dp <= maxD && !found)
95 {
96         
97#else
98 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
99 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
100 dt = 1.0 / dt;
101 
102 float minT = minD / (a + minD);
103 float maxT = maxD / (a + maxD);
104 
105 float t = minT;//dt;
106 float pa;
107 
108 while(t <= maxT && !found)
109 {
110         dp = a * t / (1 - t);
111#endif
112
113   p = x + R * dp;
114   pa = readDistanceCubeMap(mp, p);
115     
116   if(pa > 0)
117   {
118    ppp = length(p) / pa;
119    if(ppp < 1)
120      shootP = -1;
121    else
122      shootP = 1;     
123    if(shootL * shootP == -1)
124      found = true;
125    else
126    {
127      shootL = shootP;
128      dl = dp;
129      llp = ppp;
130    }
131   }
132   else
133     shootL = 0;
134 
135 #ifdef METHOD1     
136   dp += dD;
137 #else
138   t += dt;
139 #endif
140 }
141
142 if(!found)
143  p = float3(0,0,0);
144}
145
146
147void secantSearch(float3 x, float3 R, samplerCUBE mp,
148                       float dl,
149                       float dp,
150                       float llp,
151                       float ppp,
152                       out float3 p)
153{
154  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
155  {
156   float dnew;
157   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
158   p = x + R * dnew;
159   half pppnew = length(p) / readDistanceCubeMap(mp, p);
160   if(pppnew < 1)
161   {
162    llp = pppnew;
163    dl = dnew;
164   }
165   else
166   {
167    ppp = pppnew;
168    dp = dnew;
169   }
170  }
171}
172
173
174float3 Hit(float3 x, float3 R, float3 N,
175           samplerCUBE mp1,
176           samplerCUBE mp2,
177           samplerCUBE mp3Color,
178           samplerCUBE mp3Dist,
179           float2 minMax,
180           float2 minMax1,
181                   float2 minMax2,                 
182           out float4 Il, out float3 Nl)
183{
184 float dl1 = 0, dp1, llp1, ppp1;
185 float3 p1;
186 linearSearch(x, R, N, mp1, minMax1, p1, dl1, dp1, llp1, ppp1);
187 float dl2 = 0, dp2, llp2, ppp2;
188 float3 p2;
189 linearSearch(x, R, N, mp2, minMax2, p2, dl2, dp2, llp2, ppp2);
190 
191 bool valid1 = dot(p1,p1) != 0;
192 bool valid2 = dot(p2,p2) != 0;
193               
194 float dl, dp, llp, ppp;
195 float3 p;
196 
197 if(!valid1 && ! valid2)
198 {
199    linearSearch(x, R, N, mp3Dist, minMax, p, dl, dp, llp, ppp);
200    if(dot(p,p) != 0)
201    {
202     Il.a = 1;   
203     secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
204     Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb; 
205    }
206    else
207     Il = float4(0,0,0,0);
208 }
209 else
210 {
211    if( !valid2 || (valid1 && dp1 < dp2))
212    {
213     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
214     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
215     p = p1;
216    }
217    else
218    {
219     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
220     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
221     p = p2;
222    }   
223 }
224 return p;
225}
226
227struct Shaded_OUT
228{
229 float4 vPos : POSITION;
230 float4 wNormal : TEXCOORD0;
231 float4 wPos    : TEXCOORD1;
232};
233
234
235float4 MultipleReflectionPS(Shaded_OUT IN,
236                                                        uniform samplerCUBE CubeMap : register(s0),
237                                                        uniform samplerCUBE DistanceMap : register(s1),
238                                                        uniform samplerCUBE NormDistMap1 : register(s2),
239                                                        uniform samplerCUBE NormDistMap2 : register(s3),
240                                                        uniform float3 cameraPos,
241                                                        uniform float3 lastCenter,
242                                                        uniform float4 min,
243                                                        uniform float4 min1,
244                                                        uniform float4 min2,
245                                                        uniform float4 Max,
246                                                        uniform float4 max1,
247                                                        uniform float4 max2) : COLOR0
248{
249        float2 miniMaxi1;
250    miniMaxi1.x = min.a;
251    miniMaxi1.y = Max.a;
252   
253    float2 miniMaxi2;
254    miniMaxi2.x = min1.a;
255    miniMaxi2.y = max1.a;
256   
257    float2 miniMaxi3;
258    miniMaxi3.x = min2.a;
259    miniMaxi3.y = max2.a;
260                       
261         float3 N = normalize(IN.wNormal.xyz);
262         float3 x = IN.wPos.xyz - lastCenter;
263         float3 V  = (IN.wPos.xyz - cameraPos);
264                 
265         float4 I = float4(0,0,0,0);
266         V = normalize(V);
267         float3 l;
268         int depth = 0;
269       
270         while(depth < MAX_RAY_DEPTH)
271         {
272           float3 R; 
273           R = normalize(reflect( V, N));         
274               
275           float3 Nl;
276           float4 Il;
277           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
278           if(Il.a == 0)
279           {
280                   depth += 1;           
281           }
282           else
283           {
284                   I = Il;
285                   depth = MAX_RAY_DEPTH;
286           }
287           x = l;         
288           N = Nl;
289           V = R;         
290        }
291        if(I.a == 0)
292          I = readCubeMap(CubeMap, l);
293       
294        return I;
295}
296
297float4 MultipleRefractionPS(Shaded_OUT IN,
298                                                        uniform samplerCUBE CubeMap : register(s0),
299                                                        uniform samplerCUBE DistanceMap : register(s1),
300                                                        uniform samplerCUBE NormDistMap1 : register(s2),
301                                                        uniform samplerCUBE NormDistMap2 : register(s3),
302                                                        uniform float3 cameraPos,
303                                                        uniform float3 lastCenter,
304                                                        uniform float refIndex,
305                                                        //uniform float sFresnel, //0.04
306                                                        uniform float4 min,
307                                                        uniform float4 min1,
308                                                        uniform float4 min2,
309                                                        uniform float4 Max,
310                                                        uniform float4 max1,
311                                                        uniform float4 max2) : COLOR0
312{
313        float2 miniMaxi1;
314    miniMaxi1.x = min.a;
315    miniMaxi1.y = Max.a;
316   
317    float2 miniMaxi2;
318    miniMaxi2.x = min1.a;
319    miniMaxi2.y = max1.a;
320   
321    float2 miniMaxi3;
322    miniMaxi3.x = min2.a;
323    miniMaxi3.y = max2.a;
324
325         float4 I = float4(0,0,0,0);
326                       
327         float3 N = normalize(IN.wNormal.xyz);
328         float3 x = IN.wPos.xyz - lastCenter;
329         float3 V  = (IN.wPos.xyz - cameraPos);
330         
331         float sFresnel = 0.04;
332         float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);
333         
334         V = normalize(V);
335         float3 l;
336         float4 Irefl;
337         int depth = 0;
338       
339         while(depth < MAX_RAY_DEPTH)
340         {
341            float3 R; 
342           R = normalize(reflect( V, N));         
343               
344           float3 Nl;
345           float4 Il;
346           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
347           if(Il.a == 0)
348           {
349                   depth += 1;           
350           }
351           else
352           {
353                   I = Il;
354                   depth = MAX_RAY_DEPTH;
355           }
356           x = l;         
357           N = Nl;
358           V = R;   
359           
360        }
361        if(I.a == 0)
362           I = readCubeMap(CubeMap, l);
363        Irefl = I;
364       
365        {
366        float4 Irefr;
367        N = normalize(IN.wNormal.xyz);
368        x = IN.wPos.xyz - lastCenter;
369        V  = (IN.wPos.xyz - cameraPos);
370        V = normalize(V);
371        depth = 0;
372       
373        while(depth < MAX_RAY_DEPTH)
374        {
375          float3 R; 
376         
377          float ri = refIndex;
378         
379          if(dot(V,N) > 0)
380          {
381                ri = 1.0 / ri;
382                N = -N;     
383          }
384          R = refract( V, N, ri);
385          if(dot(R,R) == 0) R = reflect( V, N);
386                                       
387          float3 Nl;
388          float4 Il;
389          l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
390          if(Il.a == 0)
391          {
392                   depth += 1;           
393          }
394          else
395          {
396                   I = Il;
397                   depth = MAX_RAY_DEPTH;
398          }
399          x = l;           
400          N = normalize(Nl);
401          V = R;                   
402        }
403       
404        if(I.a == 0)
405           I = readCubeMap(CubeMap, l);
406        Irefr = I;
407           
408        I = Irefl * F + (1.0 - F) * Irefr;
409    }
410        return I;
411}
412
413float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
414                                                                        uniform samplerCUBE DistanceMap : register(s0),
415                                                                        uniform samplerCUBE NormDistMap1 : register(s1),
416                                                                        uniform samplerCUBE NormDistMap2 : register(s2),
417                                                                        uniform float3 cameraPos,
418                                                                        uniform float3 lastCenter,
419                                                                        uniform float refIndex,
420                                                                        uniform float4 min,
421                                                                        uniform float4 min1,
422                                                                        uniform float4 min2,
423                                                                        uniform float4 max,
424                                                                        uniform float4 max1,
425                                                                        uniform float4 max2) : COLOR0
426{
427        float2 miniMaxi1;
428    miniMaxi1.x = min.a;
429    miniMaxi1.y = max.a;
430   
431    float2 miniMaxi2;
432    miniMaxi2.x = min1.a;
433    miniMaxi2.y = max1.a;
434   
435    float2 miniMaxi3;
436    miniMaxi3.x = min2.a;
437    miniMaxi3.y = max2.a;
438
439        float4 I = float4(0,0,0,0);
440                 
441        float3 N = normalize(IN.wNormal.xyz);
442        float3 V  = (IN.wPos.xyz - cameraPos);
443        float3 x = IN.wPos.xyz - lastCenter;
444        V = normalize(V);
445        float3 l;
446        int depth = 0;
447       
448        while(depth < MAX_RAY_DEPTH)
449        {
450          float3 R; 
451         
452          float ri = refIndex;
453         
454          if(dot(V,N) > 0)
455          {
456                ri = 1.0 / ri;
457                N = -N;     
458          }
459          R = refract( V, N, ri);
460          if(dot(R,R) == 0) R = reflect( V, N);
461                                       
462          float3 Nl;
463          float4 Il;
464          l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
465          if(Il.a == 0)
466          {
467                   depth += 1;           
468          }
469          else
470          {
471                   I = Il;
472                   depth = MAX_RAY_DEPTH;
473          }
474          x = l;           
475          N = normalize(Nl);
476          V = R;                   
477        }
478       
479        return float4(l,1);
480}
Note: See TracBrowser for help on using the repository browser.