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

Revision 3255, 7.3 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 100  //80
14#define MIN_LIN_ITERATIONCOUNT 80  //60
15#define SECANT_ITERATIONCOUNT 1
16#define MAX_RAY_DEPTH 2
17
18void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
19                    out float3 p,
20                    out float dl,
21                    out float dp,
22                    out float llp,
23                    out float ppp)
24{
25 float3 Ra = abs(R), xa = abs(x);
26 float xm =  max(max(xa.x,xa.y),xa.z);
27 float Rm = max(max(Ra.x,Ra.y),Ra.z);
28 float a = xm / Rm;
29 
30 int shootL = 0, shootP = 0;         
31 bool found = false;
32 
33 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
34 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
35 dt = 1.0 / dt;
36   
37 float t = 0.01;//dt;
38 float pa;
39 
40 //Linear iteration
41 while(t <= 1.0 && !found)
42 {
43   dp = a * t / (1 - t);
44   p = x + R * dp;
45   pa = readDistanceCubeMap(mp, p);
46     
47   if(pa > 0)
48   {
49    ppp = length(p) / pa;
50    if(ppp < 1)
51      shootP = -1;
52    else
53      shootP = 1;     
54    if(shootL * shootP == -1)
55      found = true;
56    else
57    {
58      shootL = shootP;
59      dl = dp;
60      llp = ppp;
61    }
62   }
63   else
64     shootL = 0;
65     
66   t += dt; 
67 }
68
69 if(!found)
70  p = float3(0,0,0);
71}
72
73
74void secantSearch(float3 x, float3 R, samplerCUBE mp,
75                       float dl,
76                       float dp,
77                       float llp,
78                       float ppp,
79                       out float3 p)
80{
81  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
82  {
83   float dnew;
84   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
85   p = x + R * dnew;
86   half pppnew = length(p) / readDistanceCubeMap(mp, p);
87   if(pppnew < 1)
88   {
89    llp = pppnew;
90    dl = dnew;
91   }
92   else
93   {
94    ppp = pppnew;
95    dp = dnew;
96   }
97  }
98}
99
100float3 Hit(float3 x, float3 R, float3 N,
101           samplerCUBE mp1,
102           samplerCUBE mp2,
103           samplerCUBE mp3Color,
104           samplerCUBE mp3Dist,
105           out float4 Il, out float3 Nl)
106{
107 float dl1 = 0, dp1, llp1, ppp1;
108 float3 p1;
109 linearSearch(x, R, N, mp1, p1, dl1, dp1, llp1, ppp1);
110 float dl2 = 0, dp2, llp2, ppp2;
111 float3 p2;
112 linearSearch(x, R, N, mp2, p2, dl2, dp2, llp2, ppp2);
113 
114 bool valid1 = dot(p1,p1) != 0;
115 bool valid2 = dot(p2,p2) != 0;
116               
117 float dl, dp, llp, ppp;
118 float3 p;
119 
120 if(!valid1 && ! valid2)
121 {
122    linearSearch(x, R, N, mp3Dist, p, dl, dp, llp, ppp);
123    Il.a = 1;
124    secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
125    Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb; 
126 }
127 else
128 {
129    if( !valid2 || (valid1 && dp1 < dp2))
130    {
131     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
132     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
133     p = p1;
134    }
135    else
136    {
137     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
138     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
139     p = p2;
140    }
141    Il.a = 0;   
142 }
143 
144 return p;
145}
146
147struct Shaded_OUT
148{
149 float4 vPos : POSITION;
150 float4 wNormal : TEXCOORD0;
151 float4 wPos    : TEXCOORD1;
152};
153
154float4 MultipleReflectionPS(Shaded_OUT IN,
155                                                        uniform samplerCUBE CubeMap : register(s0),
156                                                        uniform samplerCUBE DistanceMap : register(s1),
157                                                        uniform samplerCUBE NormDistMap1 : register(s2),
158                                                        uniform samplerCUBE NormDistMap2 : register(s3),
159                                                        uniform float3 cameraPos,
160                                                        uniform float3 lastCenter) : COLOR0
161{       
162         float4 I = float4(0,0,0,0);
163                       
164         float3 N = normalize(IN.wNormal.xyz);
165         float3 x = IN.wPos.xyz - lastCenter;
166         float3 V  = (IN.wPos.xyz - cameraPos);
167         
168         V = normalize(V);
169         float3 l;
170
171               
172        //return readCubeMap(NormDistMap2, x).a /2.0 + 0.000000000001 * x.x;
173         
174         int depth = 0;
175       
176         while(depth < MAX_RAY_DEPTH)
177         {
178           float3 R; 
179           R = normalize(reflect( V, N));         
180               
181           float3 Nl;
182           float4 Il = 0;
183           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
184           if(Il.a == 0)
185           {       
186                  depth += 1;           
187           }
188           else
189           {
190                   I = Il;
191                   depth = MAX_RAY_DEPTH;
192           }
193           x = l;         
194           N = Nl;
195           V = R;   
196           
197        }
198        if(I.a == 0)
199           I = readCubeMap(CubeMap, l);
200       
201        return I;
202}
203
204float4 MultipleRefractionPS(Shaded_OUT IN,
205                                                        uniform samplerCUBE CubeMap : register(s0),
206                                                        uniform samplerCUBE DistanceMap : register(s1),
207                                                        uniform samplerCUBE NormDistMap1 : register(s2),
208                                                        uniform samplerCUBE NormDistMap2 : register(s3),
209                                                        uniform float3 cameraPos,
210                                                        uniform float3 lastCenter,
211                                                        uniform float sFresnel,
212                                                        uniform float refIndex ) : COLOR0
213{
214         float4 I = float4(0,0,0,0);
215                       
216         float3 N = normalize(IN.wNormal.xyz);
217         float3 x = IN.wPos.xyz - lastCenter;
218         float3 V  = (IN.wPos.xyz - cameraPos);
219          V = normalize(V);
220         
221         float F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel);   
222       
223         float3 l;
224         float4 Irefl;
225         int depth = 0;
226       
227         while(depth < MAX_RAY_DEPTH)
228         {
229           float3 R;
230           R = normalize(reflect( V, N));
231               
232           float3 Nl;
233           float4 Il;
234           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
235           if(Il.a == 0)
236           {
237                   depth += 1;           
238           }
239           else
240           {
241                   I = Il;
242                   depth = MAX_RAY_DEPTH;
243           }
244           x = l;         
245           N = Nl;
246           V = R;
247        }
248        if(I.a == 0)
249           I = readCubeMap(CubeMap, l);
250        Irefl = I;
251       
252        {
253        float4 Irefr;
254        N = normalize(IN.wNormal.xyz);
255        x = IN.wPos.xyz - lastCenter;
256        V  = (IN.wPos.xyz - cameraPos);
257        depth = 0;
258       
259        while(depth < MAX_RAY_DEPTH)
260        {
261          float3 R; 
262         
263          float ri = refIndex;
264         
265          if(dot(V,N) > 0)
266          {
267                ri = 1.0 / ri;
268                N = -N;     
269          }
270          R = refract( V, N, ri);
271          if(dot(R,R) == 0) R = reflect( V, N);
272                                       
273          float3 Nl;
274          float4 Il;
275          l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
276          if(Il.a == 0)
277          {
278                   depth += 1;           
279          }
280          else
281          {
282                   I = Il;
283                   depth = MAX_RAY_DEPTH;
284          }
285          x = l;           
286          N = normalize(Nl);
287          V = R;                   
288        }
289       
290        if(I.a == 0)
291           I = readCubeMap(CubeMap, l);
292        Irefr = I;
293           
294        I = Irefl * F + (1.0 - F) * Irefr;     
295    }
296        return I;
297}
298
299float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
300                                                                        uniform samplerCUBE DistanceMap : register(s0),
301                                                                        uniform samplerCUBE NormDistMap1 : register(s1),
302                                                                        uniform samplerCUBE NormDistMap2 : register(s2),
303                                                                        uniform float3 cameraPos,
304                                                                        uniform float3 lastCenter,
305                                                                        uniform float refIndex) : COLOR0
306{
307        float4 I = float4(0,0,0,0);
308                 
309        float3 N = normalize(IN.wNormal.xyz);
310        float3 x = IN.wPos.xyz - lastCenter;
311        float3 V  = (IN.wPos.xyz - cameraPos);
312        V = normalize(V);
313        float3 l;
314        int depth = 0;
315               
316        while(depth < MAX_RAY_DEPTH)
317        {
318          float3 R; 
319         
320          float ri = refIndex;
321         
322          if(dot(V,N) > 0)
323          {
324                ri = 1.0 / ri;
325                N = -N;     
326          }
327          R = refract( V, N, ri);
328          if(dot(R,R) == 0) R = reflect( V, N);
329                                       
330          float3 Nl;
331          float4 Il;
332          l = Hit(x, R, N, NormDistMap1, NormDistMap2, DistanceMap, DistanceMap, Il, Nl);
333          if(Il.a == 0)
334          {
335                   depth += 1;           
336          }
337          else
338          {
339                   I = Il;
340                   depth = MAX_RAY_DEPTH;
341          }
342          x = l;           
343          N = normalize(Nl);
344          V = R;                   
345        }
346       
347        return float4(l,1);
348}
Note: See TracBrowser for help on using the repository browser.