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

Revision 1863, 8.1 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 40  //80
16#define MIN_LIN_ITERATIONCOUNT 20  //60
17#define SECANT_ITERATIONCOUNT 2
18#define MAX_RAY_DEPTH 5
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                    out float3 p,
73                    out float dl,
74                    out float dp,
75                    out float llp,
76                    out float ppp)
77{
78 float3 Ra = abs(R), xa = abs(x);
79 float xm =  max(max(xa.x,xa.y),xa.z);
80 float Rm = max(max(Ra.x,Ra.y),Ra.z);
81 float a = xm / Rm;
82 
83 int shootL = 0, shootP = 0;         
84 bool found = false;
85 
86 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
87 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
88 dt = 1.0 / dt;
89   
90 float t = 0.01;//dt;
91 float pa;
92 
93 //Linear iteration
94 while(t <= 1.0 && !found)
95 {
96   dp = a * t / (1 - t);
97   p = x + R * dp;
98   pa = readDistanceCubeMap(mp, p);
99     
100   if(pa > 0)
101   {
102    ppp = length(p) / pa;
103    if(ppp < 1)
104      shootP = -1;
105    else
106      shootP = 1;     
107    if(shootL * shootP == -1)
108      found = true;
109    else
110    {
111      shootL = shootP;
112      dl = dp;
113      llp = ppp;
114    }
115   }
116   else
117     shootL = 0;
118     
119   t += dt; 
120 }
121
122 if(!found)
123  p = float3(0,0,0);
124}
125
126
127void secantSearch(float3 x, float3 R, samplerCUBE mp,
128                       float dl,
129                       float dp,
130                       float llp,
131                       float ppp,
132                       out float3 p)
133{
134  for(int i= 0; i < SECANT_ITERATIONCOUNT; i++)
135  {
136   float dnew;
137   dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);
138   p = x + R * dnew;
139   half pppnew = length(p) / readDistanceCubeMap(mp, p);
140   if(pppnew < 1)
141   {
142    llp = pppnew;
143    dl = dnew;
144   }
145   else
146   {
147    ppp = pppnew;
148    dp = dnew;
149   }
150  }
151}
152
153float3 Hit(float3 x, float3 R, float3 N,
154           samplerCUBE mp1,
155           samplerCUBE mp2,
156           samplerCUBE mp3Color,
157           samplerCUBE mp3Dist,
158           out float4 Il, out float3 Nl)
159{
160 float dl1 = 0, dp1, llp1, ppp1;
161 float3 p1;
162 linearSearch(x, R, N, mp1, p1, dl1, dp1, llp1, ppp1);
163 float dl2 = 0, dp2, llp2, ppp2;
164 float3 p2;
165 linearSearch(x, R, N, mp2, p2, dl2, dp2, llp2, ppp2);
166 
167 bool valid1 = dot(p1,p1) != 0;
168 bool valid2 = dot(p2,p2) != 0;
169               
170 float dl, dp, llp, ppp;
171 float3 p;
172 
173 if(!valid1 && ! valid2)
174 {
175    linearSearch(x, R, N, mp3Dist, p, dl, dp, llp, ppp);
176    Il.a = 1;
177    secantSearch(x, R, mp3Dist, dl, dp, llp, ppp, p);
178    Il.rgb =  Nl.rgb = readCubeMap(mp3Color, p).rgb; 
179 }
180 else
181 {
182    if( !valid2 || (valid1 && dp1 < dp2))
183    {
184     secantSearch(x, R, mp1, dl1, dp1, llp1, ppp1, p1);
185     Il.rgb =  Nl.rgb = readCubeMap(mp1, p1).rgb;
186     p = p1;
187    }
188    else
189    {
190     secantSearch(x, R, mp2, dl2, dp2, llp2, ppp2, p2);
191     Il.rgb =  Nl.rgb = readCubeMap(mp2, p2).rgb;
192     p = p2;
193    }
194    Il.a = 0;   
195 }
196 
197 return p;
198}
199
200struct VertOut
201{
202        float3 wPos     : TEXCOORD1;
203        float3 cPos     : TEXCOORD3;
204        float2 texCoord : TEXCOORD0;
205        float3 mNormal  : TEXCOORD2;
206        float4 hPos : POSITION;                 
207};
208
209VertOut DefaultVS(float4 position : POSITION,                                           
210                                float2 texCoord : TEXCOORD0,
211                                float3 normal   : NORMAL,
212                                uniform float4x4 worldViewProj,
213                                uniform float4x4 world,
214                                uniform float4x4 worldview,
215                                uniform float4x4 worldI )
216{
217  VertOut OUT;
218  OUT.hPos = mul(worldViewProj, position);
219  OUT.wPos = mul(world, position).xyz; 
220  OUT.cPos = mul(worldview, position).xyz; 
221  OUT.mNormal = mul(normal, worldI); 
222  //OUT.mNormal = normal;
223  OUT.texCoord = texCoord;
224  return OUT;
225}
226
227float4 SingleReflectionPS(VertOut IN,
228                                                        uniform float3 cameraPos,
229                                                        uniform samplerCUBE CubeMap : register(s0),
230                                                        uniform samplerCUBE DistanceMap : register(s1),
231                                                        uniform samplerCUBE NormDistMap1 : register(s2),
232                                                        uniform samplerCUBE NormDistMap2 : register(s3),
233                                                        uniform float3 lastCenter,
234                                                        uniform float refIndex)
235{
236 float4 Color = float4(1,1,1,1);
237               
238 float3 N = normalize(IN.mNormal);
239 float3 newTexCoord;   
240 float3 x = IN.wPos - lastCenter;
241 float3 V  = (IN.wPos - cameraPos);
242 
243 V = normalize(V);
244
245float3 R;         
246//if(refIndex > 100.0)
247    R = normalize(reflect( V, N));
248//else
249//{
250//      refIndex = 1.0 / refIndex;
251//    R = normalize(refract( V, N, refIndex));
252//}
253                       
254 float3 Nl;
255 float4 Il;
256 float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
257 if(Il.a == 0)
258  Il = readCubeMap(CubeMap, l);
259 
260 return Il;
261}
262
263
264float4 MultipleReflectionPS(VertOut IN,
265                                                        uniform float3 cameraPos,
266                                                        uniform samplerCUBE CubeMap : register(s0),
267                                                        uniform samplerCUBE DistanceMap : register(s1),
268                                                        uniform samplerCUBE NormDistMap1 : register(s2),
269                                                        uniform samplerCUBE NormDistMap2 : register(s3),
270                                                        uniform float3 lastCenter,
271                                                        uniform float refIndex)
272{
273         float4 I = float4(0,0,0,0);
274                       
275         float3 N = normalize(IN.mNormal);
276         float3 x = IN.wPos - lastCenter;
277         float3 V  = (IN.wPos - cameraPos);
278         
279         V = normalize(V);
280         float3 l;
281         
282         int depth = 0;
283         while(depth < MAX_RAY_DEPTH)
284         {
285           float3 R; 
286           //  R = normalize(reflect( V, N));     
287         
288          float ri = refIndex;
289         
290          if(dot(V,N) > 0)
291          {
292            ri = 1.0 / ri;
293            N = -N;         
294          }
295          R = refract( V, N, ri);
296          if(dot(R,R) == 0) R = reflect( V, -N);
297                               
298           float3 Nl;
299           float4 Il;
300           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
301           if(Il.a == 0)
302           {
303                   depth += 1;           
304           }
305           else
306           {
307                   I = Il;
308                   depth = MAX_RAY_DEPTH;
309           }
310           x = l;         
311           N = normalize(Nl);
312           V = R;                 
313        }
314        /*
315        N = normalize(IN.mNormal);
316        x = IN.wPos - lastCenter;
317        V  = (IN.wPos - cameraPos);
318        depth = 0;
319        while(depth < MAX_RAY_DEPTH)
320         {
321           float3 R; 
322           R = normalize(reflect( V, N));         
323               
324           float3 Nl;
325           float4 Il;
326           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
327           if(Il.a == 0)
328           {
329                   depth += 1;           
330           }
331           else
332           {
333                   I = Il * 0.2 + I * 0.8;
334                   depth = MAX_RAY_DEPTH;
335           }
336           x = l;         
337           N = Nl;
338           V = R;   
339        }*/
340       
341        //if(I.a == 0)
342      // I = readCubeMap(CubeMap, l);
343 
344        return I;
345}
346
347float4 mainPS(VertOut IN,
348                                                        uniform float3 cameraPos,
349                                                        uniform samplerCUBE CubeMap : register(s0),
350                                                        uniform samplerCUBE DistanceMap : register(s1),
351                                                        uniform samplerCUBE NormDistMap1 : register(s2),
352                                                        uniform samplerCUBE NormDistMap2 : register(s3),
353                                                        uniform float3 lastCenter,
354                                                        uniform float SingleBounce,
355                                                        uniform float refIndex):COLOR
356{
357        float4 Color = 1.0;
358        if(SingleBounce == 1)
359         Color = SingleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter,refIndex);
360        else
361         Color = MultipleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter,refIndex);
362         
363        return Color;
364}
Note: See TracBrowser for help on using the repository browser.