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

Revision 1859, 6.4 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 20
16#define MIN_LIN_ITERATIONCOUNT 6
17#define SECANT_ITERATIONCOUNT 1
18#define MAX_RAY_DEPTH 2
19
20void linearSearch(  float3 x, float3 R, float3 N, samplerCUBE mp,
21                    out float3 p,
22                    out float dl,
23                    out float dp,
24                    out float llp,
25                    out float ppp)
26{
27 float3 Ra = abs(R), xa = abs(x);
28 float xm =  max(max(xa.x,xa.y),xa.z);
29 float Rm = max(max(Ra.x,Ra.y),Ra.z);
30 float a = xm / Rm;
31           
32 bool undershoot = true, overshoot = false;
33 
34 float dt =  length(x / xm - R / Rm) * MAX_LIN_ITERATIONCOUNT;
35 dt = max(dt, MIN_LIN_ITERATIONCOUNT);
36 dt = 1.0 / dt;
37   
38 float t = dt;
39 float pa;
40 bool first = true;
41 //Linear iteration
42 while(t <= 1.0 && !overshoot)
43 {
44   dp = a * t / (1 - t);
45   p = x + R * dp;
46   pa = readDistanceCubeMap(mp, p);
47   if(pa > 0)
48   {
49    ppp = length(p) / pa;
50    if(ppp < 1)
51    {
52      dl = dp;
53      llp = ppp;
54      undershoot = true;
55    }
56    else if(undershoot)
57      overshoot = true;
58   }
59   else
60     undershoot = false;
61   t += dt; 
62 }
63 
64 if(!overshoot)
65  p = float3(0,0,0);
66 else if(t == 2 * dt)
67 {
68         float3 hitp = pa * normalize(p);
69    if(dot(normalize(hitp - x), N) < 0.1f)
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 VertOut
148{
149        float3 wPos     : TEXCOORD1;
150        float3 cPos     : TEXCOORD3;
151        float2 texCoord : TEXCOORD0;
152        float3 mNormal  : TEXCOORD2;
153        float4 hPos : POSITION;                 
154};
155
156VertOut DefaultVS(float4 position : POSITION,                                           
157                                float2 texCoord : TEXCOORD0,
158                                float3 normal   : NORMAL,
159                                uniform float4x4 worldViewProj,
160                                uniform float4x4 world,
161                                uniform float4x4 worldview,
162                                uniform float4x4 worldI )
163{
164  VertOut OUT;
165  OUT.hPos = mul(worldViewProj, position);
166  OUT.wPos = mul(world, position).xyz; 
167  OUT.cPos = mul(worldview, position).xyz; 
168  OUT.mNormal = mul(normal, worldI); 
169  //OUT.mNormal = normal;
170  OUT.texCoord = texCoord;
171  return OUT;
172}
173
174float4 SingleReflectionPS(VertOut IN,
175                                                        uniform float3 cameraPos,
176                                                        uniform samplerCUBE CubeMap : register(s0),
177                                                        uniform samplerCUBE DistanceMap : register(s1),
178                                                        uniform samplerCUBE NormDistMap1 : register(s2),
179                                                        uniform samplerCUBE NormDistMap2 : register(s3),
180                                                        uniform float3 lastCenter)
181{
182 float4 Color = float4(1,1,1,1);
183               
184 float3 N = normalize(IN.mNormal);
185 float3 newTexCoord;   
186 float3 x = IN.wPos - lastCenter;
187 float3 V  = (IN.wPos - cameraPos);
188 
189 V = normalize(V);
190 float3 R = normalize(reflect( V, N));
191 //float3 R = normalize(refract( V, N, 0.8));
192                       
193 float3 Nl;
194 float4 Il;
195 float3 l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
196 if(Il.a == 0)
197  Il = readCubeMap(CubeMap, l);
198 
199 return Il;
200}
201
202
203float4 MultipleReflectionPS(VertOut IN,
204                                                        uniform float3 cameraPos,
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 lastCenter)
210{
211         float4 I = float4(0,0,0,0);
212                       
213         float3 N = normalize(IN.mNormal);
214         float3 newTexCoord;   
215         float3 x = IN.wPos - lastCenter;
216         float3 V  = (IN.wPos - cameraPos);
217         
218         V = normalize(V);
219         float3 l;
220         
221         int depth = 0;
222         while(depth < MAX_RAY_DEPTH)
223         {
224           float3 R = normalize(reflect( V, N));
225          // float3 R = normalize(refract( V, N, 0.8));
226                               
227           float3 Nl;
228           float4 Il;
229           l = Hit(x, R, N, NormDistMap1, NormDistMap2, CubeMap, DistanceMap, Il, Nl);
230           if(Il.a == 0)
231           {
232                   depth += 1;
233                  // I = float4(0.2,0.2,0.2,1.0);
234           }
235           else
236           {
237                   I = Il;
238                   depth = MAX_RAY_DEPTH;
239           }
240           x = l;         
241           N = normalize(Nl);
242           V = R;
243          // if(dot(N, V) > 0) N = -N;
244        }
245       
246        /*if(I.a == 0)
247       I = readCubeMap(CubeMap, l);*/
248 
249        return I;
250}
251
252float4 mainPS(VertOut IN,
253                                                        uniform float3 cameraPos,
254                                                        uniform samplerCUBE CubeMap : register(s0),
255                                                        uniform samplerCUBE DistanceMap : register(s1),
256                                                        uniform samplerCUBE NormDistMap1 : register(s2),
257                                                        uniform samplerCUBE NormDistMap2 : register(s3),
258                                                        uniform float3 lastCenter,
259                                                        uniform float SingleBounce):COLOR
260{
261        float4 Color = 1.0;
262        if(SingleBounce == 1)
263         Color = SingleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter);
264        else
265         Color = MultipleReflectionPS(IN,cameraPos, CubeMap, DistanceMap, NormDistMap1,NormDistMap2,lastCenter);
266         
267        return Color;
268}
Note: See TracBrowser for help on using the repository browser.