source: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/multibounce/GTPMultipleReflection_MinMax.hlsl @ 2131

Revision 2131, 9.5 KB checked in by szirmay, 17 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 50  //80
14#define MIN_LIN_ITERATIONCOUNT 30  //60
15#define SECANT_ITERATIONCOUNT 1
16#define MAX_RAY_DEPTH 4
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 = max(minD / (a + minD) - dt, dt);
103 float maxT = maxD / (a + maxD) + dt;
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          V = normalize(V);
331         
332         float F;
333         int depth = 0;
334        F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel); 
335       
336        while(depth < MAX_RAY_DEPTH)
337        {
338          float3 R; 
339                 
340          float ri = refIndex;   
341          if(dot(V,N) > 0)
342          {
343                ri = 1.0 / ri;
344                N = -N;     
345          }
346          R = refract( V, N, ri);
347          if(dot(R,R) == 0) R = reflect( V, N);
348                                               
349          float3 Nl;
350          float4 Il;
351          float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
352          if(Il.a == 0)
353          {
354                  //I = readCubeMap(CubeMap, l);
355                   depth += 1;           
356          }
357          else
358          {
359                   I = Il;
360                   depth = MAX_RAY_DEPTH;
361          }
362          x = l;           
363          N = normalize(Nl);
364          V = R;                   
365        } 
366           
367        I *= (1.0 - F);
368   
369        return I;
370}
371
372float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
373                                                                        uniform samplerCUBE DistanceMap : register(s0),
374                                                                        uniform samplerCUBE NormDistMap1 : register(s1),
375                                                                        uniform samplerCUBE NormDistMap2 : register(s2),
376                                                                        uniform float3 cameraPos,
377                                                                        uniform float3 lastCenter,
378                                                                        uniform float refIndex,
379                                                                        uniform float4 min,
380                                                                        uniform float4 min1,
381                                                                        uniform float4 min2,
382                                                                        uniform float4 max,
383                                                                        uniform float4 max1,
384                                                                        uniform float4 max2) : COLOR0
385{
386        float2 miniMaxi1;
387    miniMaxi1.x = min.a;
388    miniMaxi1.y = max.a;
389   
390    float2 miniMaxi2;
391    miniMaxi2.x = min1.a;
392    miniMaxi2.y = max1.a;
393   
394    float2 miniMaxi3;
395    miniMaxi3.x = min2.a;
396    miniMaxi3.y = max2.a;
397
398        float4 I = float4(0,0,0,0);
399                 
400        float3 N = normalize(IN.wNormal.xyz);
401        float3 V  = (IN.wPos.xyz - cameraPos);
402        float3 x = IN.wPos.xyz - lastCenter;
403        V = normalize(V);
404        float3 l;
405        int depth = 0;
406       
407        while(depth < MAX_RAY_DEPTH)
408        {
409          float3 R; 
410         
411          float ri = refIndex;
412         
413          if(dot(V,N) > 0)
414          {
415                ri = 1.0 / ri;
416                N = -N;     
417          }
418          R = refract( V, N, ri);
419          if(dot(R,R) == 0) R = reflect( V, N);
420                                       
421          float3 Nl;
422          float4 Il;
423          l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, miniMaxi1, miniMaxi2, miniMaxi3, Il, Nl);
424          if(Il.a == 0)
425          {
426                   depth += 1;           
427          }
428          else
429          {
430                   I = Il;
431                   depth = MAX_RAY_DEPTH;
432          }
433          x = l;           
434          N = normalize(Nl);
435          V = R;                   
436        }
437       
438        return float4(l,1);
439}
Note: See TracBrowser for help on using the repository browser.