source: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/programs/MetalTeapot.hlsl @ 1882

Revision 1882, 7.6 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
16
17#define MAX_LIN_ITERATIONCOUNT 20
18#define MIN_LIN_ITERATIONCOUNT 6
19#define SECANT_ITERATIONCOUNT 1
20
21float Hit(float3 x, float3 R, samplerCUBE mp, out float3 newDir)
22{
23        R = normalize(R);
24       
25        float3 Ra = abs(R);
26        float3 xa = abs(x);
27       
28    float xm =  max(max(xa.x,xa.y),xa.z);
29    float Rm = max(max(Ra.x,Ra.y),Ra.z);
30   
31    float a = xm / Rm;
32   
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       
39        bool overshoot = false, undershoot = false;
40        float dp, dl = 0, ppp, llp;
41        float lR = readDistanceCubeMap(mp, R);
42        //float3 p = R;
43        float3 p = 0;
44               
45        //linear iteration     
46        float t;
47        float dist = 0;
48        /*
49        t = 0.9999999999999;
50        dp = a * t / (1 - t);
51        p = x + R * dp;
52        dist = readDistanceCubeMap(mp, p);
53        ppp = length(p) / dist;
54        */
55        t = 0.01;       
56               
57        while(t <= 1.0 && !overshoot)
58        {
59                dp = a * t / (1 - t);
60                p = x + R * dp;
61                float dist = readDistanceCubeMap(mp, p);
62                if(dist > 0)
63                {
64                        bool us = false;
65                       
66                        ppp = length(p) / dist;                 
67                        if(ppp < 1)
68                        us = true;
69                               
70                        us = !us;
71                       
72                        if(us)
73                        {
74                                dl = dp;
75                                llp = ppp;             
76                                undershoot = true;             
77                        }
78                        else
79                        {
80                                if (undershoot)
81                                   overshoot = true;
82                        }
83                }
84                else
85                        undershoot = false;
86       
87                t += dt;               
88        }
89       
90        //if(t >= 1.0 && undershoot && dist)
91        //      overshoot = true;       
92       
93        if(overshoot)
94        {
95                float dnew;
96                for(int i = 0; i < SECANT_ITERATIONCOUNT; i++ )
97                {
98                        dnew = dl + (dp - dl) * (1 - llp) / (ppp - llp);       
99                           
100                        p = x + R * dnew;
101                        half pppnew = length(p) / readDistanceCubeMap(mp, p);
102                        if(pppnew < 1)
103                        {
104                                llp = pppnew;
105                                dl = dnew;
106                        }
107                        else
108                        {
109                                ppp = pppnew;
110                                dp = dnew;
111                        }
112                }       
113        }
114        else
115                p = float3(0,0,0);
116       
117        newDir = p;
118        return dp;
119}
120                       
121
122float HitOld( float3 x, float3 R, samplerCUBE mp, out float3 newDir )
123{
124        //return R  + 0.00000000001 * x;
125        float rl = readDistanceCubeMap( mp, R);                         // |r|
126       
127        float ppp = length( x ) /  readDistanceCubeMap( mp, x);                 // |p|/|p’|
128        float dun = 0, pun = ppp, dov = 0, pov = 0;
129        float dl = rl * ( 1 - ppp );                                                    // eq. 2
130        float3 l = x + R * dl;                                                                  // ray equation
131
132        // iteration
133        for( int i = 0; i < SECANT_ITERATIONCOUNT; i++ )       
134        {
135                float llp = length( l ) / readDistanceCubeMap( mp, l);          // |l|/|l’|
136                if ( llp < 0.999f )                                                                     // undershooting
137                {
138                        dun = dl; pun = llp;                                                    // last undershooting
139                        dl += ( dov == 0 ) ? rl * ( 1 - llp ) :                 // eq. 2
140                                ( dl - dov ) * ( 1 - llp ) / ( llp - pov );     // eq. 3
141                } else if ( llp > 1.001f )                                                      // overshooting
142                {
143                        dov = dl; pov = llp;                                                    // last overshooting
144                        dl += ( dl -dun ) * ( 1 - llp ) / ( llp - pun );// eq. 3
145                }
146                l = x + R * dl;                                                                         // ray equation
147        }
148        newDir = l;                                                                                             // computed hit point
149       
150        return dl;
151}
152
153
154struct VertOut
155{
156        float3 wPos     : TEXCOORD1;
157        float3 cPos     : TEXCOORD3;
158        float2 texCoord : TEXCOORD0;
159        float3 mNormal  : TEXCOORD2;
160        float4 hPos : POSITION;                 
161};
162
163VertOut DefaultVS(float4 position : POSITION,                                           
164                                float2 texCoord : TEXCOORD0,
165                                float3 normal   : NORMAL,
166                                uniform float4x4 worldViewProj,
167                                uniform float4x4 world,
168                                uniform float4x4 worldview,
169                                uniform float4x4 worldI )
170{
171  VertOut OUT;
172  OUT.hPos = mul(worldViewProj, position);
173  OUT.wPos = mul(world, position).xyz; 
174  OUT.cPos = mul(worldview, position).xyz; 
175  OUT.mNormal = mul(normal, worldI); 
176  //OUT.mNormal = normal;
177  OUT.texCoord = texCoord;
178  return OUT;
179}
180
181//////////////
182//Metal
183//////////////
184float4 Metal1BouncePS(  VertOut IN,
185                uniform float3 cameraPos,
186                uniform samplerCUBE CubeMap : register(s0),
187                uniform samplerCUBE DistanceMap : register(s1),
188                uniform float3 lastCenter):COLOR0
189{
190       
191        float4 Color = float4(1,1,1,1);
192       
193        IN.mNormal = normalize(IN.mNormal);
194        float3 newTexCoord;     
195        float3 mPos = IN.wPos - lastCenter;
196        float3 V  = (IN.wPos - cameraPos);
197        float cameraDistace = length(V);
198        V = normalize(V);
199        float3 R = normalize(reflect( V, IN.mNormal));
200               
201        newTexCoord = R;       
202        HitOld(mPos, R, DistanceMap, newTexCoord);
203        Color = readCubeMap(CubeMap, newTexCoord );     
204       
205        float ctheta_in = dot(IN.mNormal,R);
206        float ctheta_out = dot(IN.mNormal,-V);
207
208        float3 F = 0;
209       
210        // F,P,G számítása
211        if ( ctheta_in > 0 && ctheta_out > 0 )
212        {
213                float3 H = normalize(R - V);    // felezõvektor
214                float cbeta  = dot(H,R);               
215                F = F0 + (1-F0)*pow(1-cbeta,5);
216        }       
217       
218        Color = Color * float4(F,1);
219       
220        return Color;   
221}
222
223
224void MetalMultipleBouncePS(  VertOut IN,
225                uniform float3 cameraPos,
226                uniform samplerCUBE CubeMap : register(s0),
227                uniform samplerCUBE DistanceMap : register(s1),
228                uniform samplerCUBE NormDistMap1 : register(s2),
229                uniform samplerCUBE NormDistMap2 : register(s3),
230                uniform float3 lastCenter,
231                uniform float SingleBounce,
232                out float4 Color :COLOR0)
233{
234        //if(SingleBounce == 1)
235        // Color = Metal1BouncePS(IN,cameraPos,CubeMap,DistanceMap,lastCenter);
236        //else
237        //{
238                Color = float4(1,1,1,1);
239               
240                IN.mNormal = normalize(IN.mNormal);
241                float3 newTexCoord;     
242                float3 mPos = IN.wPos - lastCenter;
243                float3 V  = (IN.wPos - cameraPos);
244                float cameraDistace = length(V);
245                V = normalize(V);
246                float3 R = normalize(reflect( V, IN.mNormal));
247                //float3 R = normalize(refract( V, IN.mNormal, 0.98));
248                       
249                newTexCoord = R;
250               
251                //Color = readCubeMap(NormDistMap2, mPos );
252                //return;
253               
254
255                float3 newDir1;
256                float d1 = Hit(mPos, R, NormDistMap1, newDir1);
257                float3 normal1 = readCubeMap(NormDistMap1, newDir1).rgb;
258                bool valid1 = /*dot(normal1, R) < 0 &&*/ dot(newDir1,newDir1) != 0;
259                if(valid1)
260                        newDir1 = 0;
261                float3 newDir2;
262                float d2 = Hit(mPos, R, NormDistMap2, newDir2);
263                float3 normal2 =  readCubeMap(NormDistMap2, newDir2).rgb;
264                bool valid2 = /*dot(normal2, R) < 0 &&*/ dot(newDir2,newDir2) != 0;
265                if(valid2)
266                        newDir2 = 0;
267                       
268                if( !valid1 && !valid2)
269                {
270                //      Hit(mPos, R, DistanceMap, newTexCoord);
271                //      Color = readCubeMap(CubeMap, newTexCoord );
272                        //Color = 1;                   
273                }
274                else
275                {               
276                        float d;
277                        float3 newN;
278                       
279                        d = d2;
280                        newN = normal2;
281                       
282                        Color = float4(0,0,1,1);
283                        if( !valid2 || (valid1 && d1 < d2)  )
284                        {
285                                d = d1;
286                                newN = normal1;
287                                Color = float4(0,1,0,1);
288                        }
289                       
290                        float3 newV = R;
291                        float3 newX = mPos + R * d;
292                        float3 newR = normalize(reflect( newV, newN));
293                //      float3 newR = normalize(refract( newV, newN, 0.98));
294               
295                        Hit(newX, newR, DistanceMap, newTexCoord);     
296                        Color = readCubeMap(CubeMap, newTexCoord );
297                        //Color = float4(newR,1);
298                        //Color = float4(1,0,0,1);     
299                }
300               
301/*
302                return;
303               
304                float ctheta_in = dot(IN.mNormal,R);
305                float ctheta_out = dot(IN.mNormal,-V);
306
307                float3 F = 0;
308               
309                // F,P,G számítása
310                if ( ctheta_in > 0 && ctheta_out > 0 )
311                {
312                        float3 H = normalize(R - V);    // felezõvektor
313                        float cbeta  = dot(H,R);               
314                        F = F0 + (1-F0)*pow(1-cbeta,5);
315                }       
316               
317                Color = Color * float4(F,1);    */
318        //}
319}
320
321float4 NormalDistancePS( VertOut IN, uniform float refIndex):COLOR
322{
323 
324 float4 Color = float4(0, 0, 0, 0);
325 //return Color;
326 Color = float4(normalize(IN.mNormal)/* * refIndex*/, length(IN.cPos));
327 return Color;
328}
329
330
331float4 DistanceMinMaxPS( VertOut IN, uniform float refIndex):COLOR
332{
333 
334 float4 Color = float4(0, 0, 0, 0);
335 Color = float4(length(IN.cPos), 0,0,length(IN.cPos));
336 return Color;
337}
Note: See TracBrowser for help on using the repository browser.