source: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapotNew.hlsl @ 1897

Revision 1897, 9.3 KB checked in by szirmay, 18 years ago (diff)
Line 
1float3 F0;
2
3float4 readCubeMap(samplerCUBE cm, float3 coord)               
4{
5        float4 color = texCUBElod( cm, float4(coord.xy, - coord.z,0) );
6        return color;
7}
8
9float readDistanceCubeMap(samplerCUBE dcm, float3 coord)               
10{
11        float dist = texCUBElod(dcm, float4(coord.xy, - coord.z,0)).a;
12        return dist;
13}
14
15#define MAX_LIN_ITERATIONCOUNT 80  //80
16#define MIN_LIN_ITERATIONCOUNT 60  //60
17#define SECANT_ITERATIONCOUNT 2
18#define MAX_RAY_DEPTH 2
19
20/*
21void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
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 bool undershoot = false, overshoot = false;
34 
35 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
36 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
37 dt = 1.0 / dt;
38   
39 float t = 0.01;//dt;
40 float pa;
41 bool first = true;
42 //Linear iteration
43 while(t <= 1.0 && !overshoot)
44 {
45   dp = a * t / (1 - t);
46   p = x + R * dp;
47   pa = readDistanceCubeMap(mp, p);
48   if(pa > 0)
49   {
50    ppp = length(p) / pa;
51    if(ppp < 1)
52    {
53      dl = dp;
54      llp = ppp;
55      undershoot = true;
56    }
57    else if(undershoot)
58      overshoot = true;
59   }
60   else
61     undershoot = false;
62   t += dt; 
63 }
64
65 if(!overshoot)
66  p = float3(0,0,0);
67}
68*/
69
70
71void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
72                                        float min,                                     
73                    out float3 p,
74                    out float dl,
75                    out float dp,
76                    out float llp,
77                    out float ppp)
78{
79 float3 Ra = abs(R), xa = abs(x);
80 float xm =  max(max(xa.x,xa.y),xa.z);
81 float Rm = max(max(Ra.x,Ra.y),Ra.z);
82 float a = xm / Rm;
83 
84 int shootL = 0, shootP = 0;         
85 bool found = false;
86 
87 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
88 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
89 dt = 1.0 / dt;
90 
91 float t = 0.01;
92 if(min > length(x))
93 {
94 
95        float a = 1;
96        float b = 2 * dot(R, x);
97        float c = dot(x,x) - min * min;
98       
99        float dis = b*b - 4*a*c;
100        float t1 = (-b + sqrt(dis))/ 2.0 * a;
101        float t2 = (-b - sqrt(dis))/ 2.0 * a;
102       
103        if(t1 > 0 && (t2 < 0 || t1 < t2))
104         t =  1.0;//t1 / ( a + t1);
105        else if(t2 > 0)
106         t =  1.0;//t2 / ( a + t2);
107         //t = 0.011;
108  }
109 
110 float pa;
111 
112 //Linear iteration
113 while(t <= 1.0 && !found)
114 {
115   dp = a * t / (1 - t);
116   p = x + R * dp;
117   pa = readDistanceCubeMap(mp, p);
118     
119   if(pa > 0)
120   {
121    ppp = length(p) / pa;
122    if(ppp < 1)
123      shootP = -1;
124    else
125      shootP = 1;     
126    if(shootL * shootP == -1)
127      found = true;
128    else
129    {
130      shootL = shootP;
131      dl = dp;
132      llp = ppp;
133    }
134   }
135   else
136     shootL = 0;
137     
138   t += dt; 
139 }
140
141 if(!found)
142  p = float3(0,0,0);
143}
144
145
146void secantSearch(float3 x, float3 R, samplerCUBE mp,
147                       float dl,
148                       float dp,
149                       float llp,
150                       float ppp,
151                       out float3 p)
152{
153  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
154  {
155   float dnew;
156   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
157   p = x + R * dnew;
158   half pppnew = length(p) / readDistanceCubeMap(mp, p);
159   if(pppnew < 1)
160   {
161    llp = pppnew;
162    dl = dnew;
163   }
164   else
165   {
166    ppp = pppnew;
167    dp = dnew;
168   }
169  }
170}
171
172float3 Hit(float3 x, float3 R, float3 N,
173           samplerCUBE mp1,
174           samplerCUBE mp2,
175           samplerCUBE mp3Color,
176           samplerCUBE mp3Dist,
177           float min,
178           float min1,
179                   float min2,             
180           out float4 Il, out float3 Nl)
181{
182 float dl1 = 0, dp1, llp1, ppp1;
183 float3 p1;
184 linearSearch(x, R, N, mp1, min1, p1, dl1, dp1, llp1, ppp1);
185 float dl2 = 0, dp2, llp2, ppp2;
186 float3 p2;
187 linearSearch(x, R, N, mp2, min2, p2, dl2, dp2, llp2, ppp2);
188 
189 bool valid1 = dot(p1,p1) != 0;
190 bool valid2 = dot(p2,p2) != 0;
191               
192 float dl, dp, llp, ppp;
193 float3 p;
194 
195 if(!valid1 && ! valid2)
196 {
197    linearSearch(x, R, N, mp3Dist, min, p, dl, dp, llp, ppp);
198    Il.a = 1;
199    secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
200    Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb; 
201 }
202 else
203 {
204    if( !valid2 || (valid1 && dp1 < dp2))
205    {
206     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
207     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
208     p = p1;
209    }
210    else
211    {
212     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
213     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
214     p = p2;
215    }
216    Il.a = 0;   
217 }
218 
219 return p;
220}
221
222struct VertOut
223{
224        float3 wPos     : TEXCOORD1;
225        float3 cPos     : TEXCOORD3;
226        float2 texCoord : TEXCOORD0;
227        float3 mNormal  : TEXCOORD2;
228        float4 hPos : POSITION;                 
229};
230
231VertOut DefaultVS(float4 position : POSITION,                                           
232                                float2 texCoord : TEXCOORD0,
233                                float3 normal   : NORMAL,
234                                uniform float4x4 worldViewProj,
235                                uniform float4x4 world,
236                                uniform float4x4 worldview,
237                                uniform float4x4 worldI )
238{
239  VertOut OUT;
240  OUT.hPos = mul(worldViewProj, position);
241  OUT.wPos = mul(world, position).xyz; 
242  OUT.cPos = mul(worldview, position).xyz; 
243  OUT.mNormal = mul(normal, worldI); 
244  //OUT.mNormal = normal;
245  OUT.texCoord = texCoord;
246  return OUT;
247}
248
249float4 SingleReflectionPS(VertOut IN,
250                                                        uniform float3 cameraPos,
251                                                        uniform samplerCUBE CubeMap : register(s0),
252                                                        uniform samplerCUBE DistanceMap : register(s1),
253                                                        uniform samplerCUBE NormDistMap1 : register(s2),
254                                                        uniform samplerCUBE NormDistMap2 : register(s3),
255                                                        uniform float3 lastCenter,
256                                                        uniform float refIndex,
257                                                        float min,
258                                                        float min1,
259                                                        float min2
260                                                        )
261{
262 float4 Color = float4(1,1,1,1);
263               
264 float3 N = normalize(IN.mNormal);
265 float3 newTexCoord;   
266 float3 x = IN.wPos - lastCenter;
267 float3 V  = (IN.wPos - cameraPos);
268 
269 V = normalize(V);
270
271float3 R;         
272//if(refIndex > 100.0)
273    R = normalize(reflect( V, N));
274//else
275//{
276//      refIndex = 1.0 / refIndex;
277//    R = normalize(refract( V, N, refIndex));
278//}
279                       
280 float3 Nl;
281 float4 Il;
282 float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, min, min1, min2, Il, Nl);
283 if(Il.a == 0)
284  Il = readCubeMap(CubeMap, l);
285 
286 return Il;
287}
288
289#define REFRACTION 0
290
291float4 MultipleReflectionPS(VertOut IN,
292                                                        uniform float3 cameraPos,
293                                                        uniform samplerCUBE CubeMap : register(s0),
294                                                        uniform samplerCUBE DistanceMap : register(s1),
295                                                        uniform samplerCUBE NormDistMap1 : register(s2),
296                                                        uniform samplerCUBE NormDistMap2 : register(s3),
297                                                        uniform float3 lastCenter,
298                                                        uniform float refIndex,
299                                                        float min,
300                                                        float min1,
301                                                        float min2)
302{
303         float4 I = float4(0,0,0,0);
304                       
305         float3 N = normalize(IN.mNormal);
306         float3 x = IN.wPos - lastCenter;
307         float3 V  = (IN.wPos - cameraPos);
308         
309         float Fp = 0.04;
310         float F = Fp + pow(1 - dot(N, -V), 5) * (1 - Fp);
311         
312         V = normalize(V);
313         float3 l;
314         float4 Irefl;
315         int depth = 0;
316       
317       
318         while(depth < MAX_RAY_DEPTH)
319         {
320            float3 R; 
321           R = normalize(reflect( V, N));         
322               
323           float3 Nl;
324           float4 Il;
325           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, min, min1, min2, Il, Nl);
326           if(Il.a == 0)
327           {
328                   depth += 1;           
329           }
330           else
331           {
332                   I = Il;
333                   depth = MAX_RAY_DEPTH;
334           }
335           x = l;         
336           N = Nl;
337           V = R;   
338           
339        }
340/*      if(I.a == 0)
341           I = readCubeMap(CubeMap, l);*/
342        Irefl = I;
343       
344        if(REFRACTION)
345        {
346                float4 Irefr;
347                N = normalize(IN.mNormal);
348                x = IN.wPos - lastCenter;
349                V  = (IN.wPos - cameraPos);
350                depth = 0;
351                while(depth < MAX_RAY_DEPTH)
352                {
353                  float3 R; 
354                   //R = normalize(reflect( V, N));
355                     
356                 
357                  float ri = refIndex;
358                 
359                  if(dot(V,N) > 0)
360                  {
361                        ri = 1.0 / ri;
362                        N = -N;     
363                  }
364                  R = refract( V, N, ri);
365                  if(dot(R,R) == 0) R = reflect( V, N);
366                 
367                                       
368                   float3 Nl;
369                   float4 Il;
370                   l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, min, min1, min2, Il, Nl);
371                   if(Il.a == 0)
372                   {
373                           depth += 1;           
374                   }
375                   else
376                   {
377                           I = Il;
378                           depth = MAX_RAY_DEPTH;
379                   }
380                   x = l;         
381                   N = normalize(Nl);
382                   V = R;                 
383                }
384               
385                if(I.a == 0)
386                   I = readCubeMap(CubeMap, l);
387                Irefr = I;
388           
389                I = Irefl * F + (1.0 - F) * Irefr;
390    }
391        return I;
392}
393
394float4 mainPS(VertOut IN,
395                                                        uniform float3 cameraPos,
396                                                        uniform samplerCUBE CubeMap : register(s0),
397                                                        uniform samplerCUBE DistanceMap : register(s1),
398                                                        uniform samplerCUBE NormDistMap1 : register(s2),
399                                                        uniform samplerCUBE NormDistMap2 : register(s3),
400                                                        uniform float3 lastCenter,
401                                                        uniform float SingleBounce,
402                                                        uniform float refIndex,
403                                                        uniform float4 min,
404                                                        uniform float4 min1,
405                                                        uniform float4 min2
406                                                        ):COLOR
407{
408   // min1.x = 1.0 / min1.x;
409   // min2.x = 1.0 / min2.x;
410        float4 Color = 1.0;
411        if(SingleBounce == 1)
412         Color = SingleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter,refIndex, min.w, min1.w, min2.w);
413        else
414         Color = MultipleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter,refIndex, min.w, min1.w, min2.w);
415         
416        return Color;
417}
Note: See TracBrowser for help on using the repository browser.