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

Revision 2175, 9.7 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
14
15#define MAX_LIN_ITERATIONCOUNT 50  //80
16#define MIN_LIN_ITERATIONCOUNT 30  //60
17#define SECANT_ITERATIONCOUNT 1
18#define MAX_RAY_DEPTH 4
19
20uniform samplerCUBE mp3Color : register(s0);
21uniform samplerCUBE mp3Dist : register(s1);
22uniform samplerCUBE mp1 : register(s2);
23uniform samplerCUBE mp2 : register(s3);
24                                                       
25
26void linearSearch(  float3 x, float3 R, samplerCUBE mp,
27                    out float3 p,
28                    out float dl,
29                    out float dp,
30                    out float llp,
31                    out float ppp)
32{       
33        p = 1;
34       
35        float3 Ra = abs(R), xa = abs(x);
36        float  a = max(max(xa.x, xa.y), xa.z) / max(max(Ra.x, Ra.y), Ra.z);
37        bool   undershoot = false, overshoot = false;   
38       
39        float dt =  length(x / max(max(xa.x, xa.y), xa.z) - R / max(max(Ra.x, Ra.y), Ra.z)) * MAX_LIN_ITERATIONCOUNT;
40    dt = max(dt, MIN_LIN_ITERATIONCOUNT);
41    dt = 1.0 / dt;
42 
43        float t = 0.01;
44        while( t < 1 && !(overshoot && undershoot) ) {  // iteration
45                float dr = a * t / (1 - t);     // ray parameter corresponding to t
46                float3 r = x + R * dr;          // point on the ray
47                float ra =  readDistanceCubeMap(mp, r);         // |p'|: distance direction of p
48               
49               
50                if (ra > 0) {           // valid texel, i.e. anything is visible
51                float rrp = length(r)/ra; //|r|/|r'|
52                        if (rrp < 1) {          // undershooting
53                        dl = dr;        // store last undershooting as l
54                        llp = rrp;
55                        undershoot = true;
56                } else {
57                        dp = dr;        // store last overshooting as p
58                        ppp = rrp;
59                        overshoot = true;}
60                } else {                        // nothing is visible: restart search
61                undershoot = false;     
62                overshoot = false;
63                }       
64                t += dt;                        // next texel
65        }
66
67
68        if(!(overshoot && undershoot))
69          p = float3(0,0,0);
70}
71
72
73void secantSearch(float3 x, float3 R, samplerCUBE mp,
74                       float dl,
75                       float dp,
76                       float llp,
77                       float ppp,
78                       out float3 p)
79{
80  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
81  {
82   float dnew;
83   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
84   p = x + R * dnew;
85   half pppnew = length(p) / readDistanceCubeMap(mp, p);
86   if(pppnew < 1)
87   {
88    llp = pppnew;
89    dl = dnew;
90   }
91   else
92   {
93    ppp = pppnew;
94    dp = dnew;
95   }
96  }
97}
98
99float3 Hit(float3 x, float3 R, out float4 Il, out float3 Nl)
100{
101 float dl1 = 0, dp1, llp1, ppp1;
102 float3 p1;
103 linearSearch(x, R, mp1, p1, dl1, dp1, llp1, ppp1);
104 float dl2 = 0, dp2, llp2, ppp2;
105 float3 p2;
106 linearSearch(x, R, mp2, p2, dl2, dp2, llp2, ppp2);
107 
108 bool valid1 = dot(p1,p1) != 0;
109 bool valid2 = dot(p2,p2) != 0;
110               
111 float dl, dp, llp, ppp;
112 float3 p;
113 
114 if(!valid1 && ! valid2)
115 {
116    linearSearch(x, R, mp3Dist, p, dl, dp, llp, ppp);
117    Il.a = 1;
118    secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
119    Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb; 
120 }
121 else
122 {
123    if( !valid2 || (valid1 && dp1 < dp2))
124    {
125     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
126     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
127     p = p1;
128    }
129    else
130    {
131     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
132     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
133     p = p2;
134    }
135    Il.a = 0;   
136 }
137 
138 return p;
139}
140
141
142
143void SpecularReflectionVS(     
144        in  float4 Pos  : POSITION,     // modeling space
145        in  float4 Norm : NORMAL,               // normal vector
146        out float4 hPos : POSITION,     // clipping space
147        out float3 x    : TEXCOORD1,    // cube map space
148        out float3 N    : TEXCOORD2,    // normal
149        out float3 V    : TEXCOORD3,    // view
150   uniform float4x4 WorldViewProj, 
151   uniform float4x4 World,
152   uniform float4x4 WorldIT,
153   uniform float3   eyePos    // eye position
154) {
155        hPos = mul(Pos, WorldViewProj);
156        x    = mul(Pos, World).xyz;
157        N    = mul(Norm, WorldIT).xyz;
158        V    = x - eyePos;
159}
160
161float4 SingleReflectionPS(     
162        float3 x : TEXCOORD1,           // cube map space
163        float3 N : TEXCOORD2,           // normal
164        float3 V : TEXCOORD3,           // view
165        uniform float Fp0,
166        uniform float3 lastCenter // cube map center position   
167) : COLOR
168{
169        x -= lastCenter;
170        V = normalize(V); N = normalize(N);
171        float3 R = reflect(V, N);       // reflection dir.
172        float3 Nl;                      // normal vector at the hit point
173        float3 Il;                      // radiance at the hit point
174        // ray hit l, radiance Il, normal Nl
175        float3 l = Hit(x, R, Il, Nl);
176
177        // Fresnel reflection
178        float3 F = Fp0 + pow(1-dot(N, -V), 5) * (1 - Fp0);
179        return float4(F * Il, 1);
180}
181
182float4 MultipleReflectionPS(   
183                                                        float3 x : TEXCOORD1,           // shaded point in Cube map space
184                                                        float3 N : TEXCOORD2,           // normal vector
185                                                        float3 V : TEXCOORD3,           // view direction
186                                                        uniform float3 Fp0,     // Fresnel at perpendicular direction
187                                                        uniform float3 refIndex,        // index of refraction
188                                                        uniform float3 lastCenter
189) : COLOR
190{
191        x-= lastCenter;
192        V = normalize(V); N = normalize(N);
193
194        float3 I = float3(1, 1, 1);// radiance of the path
195        float3 Fp = Fp0;           // Fresnel at 90 degrees at first hit
196        float  n = refIndex;             // index of refraction of the first hit
197        int depth = 0;          // length of the path
198        while (depth < MAX_RAY_DEPTH) {
199        float3 R;       // reflection or refraction dir
200        float3 F = Fp + pow(1-abs(dot(N, -V)), 5) * (1-Fp);  // Fresnel
201        if (n <= 0) {
202                R = reflect(V, N);  // reflection
203                I *= F;             // Fresnel reflection
204        }
205        else{                   // refraction
206                if (dot(V,N) > 0) { // coming from inside
207                                n = 1.0 / n;
208                                N = -N;
209                }
210                R = refract(V, N, n);
211                if (dot(R, R) == 0)     // no refraction direction exits
212                        R = reflect(V, N); // total reflection                         
213                        else
214                        I *= (1-F);        // Fresnel refraction
215        }
216       
217        float3 Nl;              // normal vector at the hit point
218        float4 Il;              // radiance at the hit point
219                // Trace ray x+R*d and obtain hit l, radiance Il, normal Nl
220            float3 l = Hit(x, R, Il, Nl);
221            if (Il.a == 0) {            // hit point is on specular surface
222                depth += 1;
223        } else {                // hit point is on diffuse surface
224                I *= Il.rgb;    // multiply with the radiance
225                depth = MAX_RAY_DEPTH;   // terminate
226        }
227        N = Nl; V = R; x = l; // hit point is the next shaded point
228        }
229        return float4(I, 1);
230}
231
232
233struct Shaded_OUT
234{
235 float4 vPos : POSITION;
236 float4 wNormal : TEXCOORD0;
237 float4 wPos    : TEXCOORD1;
238};
239
240float4 MultipleReflectionPS_o(Shaded_OUT IN,
241                                                        uniform float3 cameraPos,
242                                                        uniform float3 lastCenter) : COLOR0
243{       
244        return 1;
245         float4 I = float4(0,0,0,0);
246                       
247         float3 N = normalize(IN.wNormal.xyz);
248         float3 x = IN.wPos.xyz - lastCenter;
249         float3 V  = (IN.wPos.xyz - cameraPos);
250         
251         V = normalize(V);
252         float3 l;
253
254               
255        //return readCubeMap(NormDistMap2, x).a /2.0 + 0.000000000001 * x.x;
256         
257         int depth = 0;
258       
259         while(depth < MAX_RAY_DEPTH)
260         {
261           float3 R; 
262           R = normalize(reflect( V, N));         
263               
264           float3 Nl;
265           float4 Il = 0;
266           l = Hit(x, R, Il, Nl);
267           if(Il.a == 0)
268           {       
269                  depth += 1;           
270           }
271           else
272           {
273                   I = Il;
274                   depth = MAX_RAY_DEPTH;
275           }
276           x = l;         
277           N = Nl;
278           V = R;   
279           
280        }
281        if(I.a == 0)
282           I = readCubeMap(mp3Color, l);
283       
284        return I;
285}
286
287float4 MultipleRefractionPS(Shaded_OUT IN,
288                                                        uniform float3 cameraPos,
289                                                        uniform float3 lastCenter,                                                     
290                                                        uniform float sFresnel,
291                                                        uniform float refIndex ) : COLOR0
292{
293         float4 I = float4(0,0,0,0);
294                       
295         float3 N = normalize(IN.wNormal.xyz);
296         float3 x = IN.wPos.xyz - lastCenter;
297         float3 V  = (IN.wPos.xyz - cameraPos);
298          V = normalize(V);
299         
300         float F;
301         int depth = 0;
302        F = sFresnel + pow(1 - dot(N, -V), 5) * (1 - sFresnel); 
303       
304        while(depth < MAX_RAY_DEPTH)
305        {
306          float3 R; 
307                 
308          float ri = refIndex;   
309          if(dot(V,N) > 0)
310          {
311                ri = 1.0 / ri;
312                N = -N;     
313          }
314          R = refract( V, N, ri);
315          if(dot(R,R) == 0) R = reflect( V, N);
316                                               
317          float3 Nl;
318          float4 Il;
319          float3 l = Hit(x, R, Il, Nl);
320          if(Il.a == 0)
321          {               
322                   depth += 1;           
323          }
324          else
325          {
326                   I = Il;
327                   depth = MAX_RAY_DEPTH;
328          }
329          x = l;           
330          N = normalize(Nl);
331          V = R;                   
332        }
333        /*     
334        if(I.a == 0)
335        {
336         float ri = refIndex;   
337         if(dot(V,N) > 0)
338         {
339                ri = 1.0 / ri;
340                N = -N;     
341         }
342         float3 R = refract( V, N, ri);
343         if(dot(R,R) == 0) R = reflect( V, N);
344         I = readCubeMap(mp3Color, R);
345        }
346        */
347        I *= (1.0 - F);
348   
349        return I;
350}
351
352float4 MultipleRefractionPhotonMap_PS(Shaded_OUT IN,
353                                                                        uniform float3 cameraPos,
354                                                                        uniform float3 lastCenter,
355                                                                        uniform float refIndex) : COLOR0
356{
357         float4 I = 0;         
358         float3 N = normalize(IN.wNormal.xyz);
359         float3 x = IN.wPos.xyz - lastCenter;
360         float3 V  = (IN.wPos.xyz - cameraPos);
361         V = normalize(V);
362         
363        int depth = 0;
364        float3 l;
365       
366        while(depth < MAX_RAY_DEPTH)
367        {
368          float3 R; 
369                 
370          float ri = refIndex;   
371          if(dot(V,N) > 0)
372          {
373                ri = 1.0 / ri;
374                N = -N;     
375          }
376          R = refract( V, N, ri);
377          if(dot(R,R) == 0) R = reflect( V, N);
378                                               
379          float3 Nl;
380          float4 Il;
381          l = Hit(x, R, Il, Nl);
382          if(Il.a == 0)
383          {
384                  depth += 1;           
385          }
386          else
387          {
388                  I = Il;
389                  depth = MAX_RAY_DEPTH;
390          }
391          x = l;           
392          N = normalize(Nl);
393          V = R;                   
394        } 
395        if(I.a == 0)
396                I = float4(V,1);
397        else
398                I = float4(l,1);
399       
400        return I;
401}
Note: See TracBrowser for help on using the repository browser.