source: GTP/trunk/App/Demos/Illum/Ogre/Media/materials/GTPAdvancedEnvMap/diffuse/GTPDiffuse.hlsl @ 2054

Revision 2054, 12.1 KB checked in by szirmay, 17 years ago (diff)
Line 
1
2#define CUBEMAP_SIZE 128
3#define REDUCED_CUBEMAP_SIZE 4
4#define RATE 32
5
6float4 readCubeMap(samplerCUBE cm, float3 coord)               
7{
8        float4 color = texCUBElod( cm, float4(coord.xy, -coord.z, 1) );
9        color.a = 1;
10        return color;
11}
12
13float readDistanceCubeMap(samplerCUBE dcm, float3 coord)               
14{
15        float dist = texCUBElod(dcm, float4(coord.xy, - coord.z, 1)).r;
16        if(dist == 0) dist = 1000000; ///sky
17        return dist;
18}
19
20////////////////////////////
21/// Reduce cube map shader
22///////////////////////////
23struct MPos_OUT
24{
25 float4 VPos : POSITION;
26 float4 MPos : TEXCOORD0;
27};
28
29float4 ReduceCubeMap_PS(MPos_OUT IN,
30                                                uniform int nFace,
31                                                uniform samplerCUBE EnvironmentMapSampler : register(s0) ) : COLOR
32
33   float4 color = 0;
34   float3 dir;
35 
36   for (int i = 0; i < RATE; i++)
37     for (int j = 0; j < RATE; j++)
38    {
39                float2 pos;
40                pos.x = IN.MPos.x + (2*i + 1)/(float)CUBEMAP_SIZE;
41                pos.y = IN.MPos.y - (2*j + 1)/(float)CUBEMAP_SIZE;      // y=-u
42
43                // "scrambling"
44                if (nFace == 0) dir = float3(1, pos.y, -pos.x);
45                if (nFace == 1) dir = float3(-1, pos.y, pos.x);
46                if (nFace == 2) dir = float3(pos.x, 1, -pos.y);
47                if (nFace == 3) dir = float3(pos.x, -1, pos.y);
48                if (nFace == 4) dir = float3(pos.x, pos.y, 1);
49                if (nFace == 5) dir = float3(-pos.x, pos.y,-1);
50
51                color += texCUBE( EnvironmentMapSampler, dir);
52    }
53 
54        return color / (RATE * RATE);           
55}
56
57
58////////////////
59/// Diffuse
60///////////////
61
62/// Polygon to point form factor
63
64float4 Poly2Point_Contr(float3 L, float3 L1, float3 L2, float3 L3, float3 L4, float3 pos, float3 N, samplerCUBE cubemap)
65{
66        float d;
67        //d = texCUBE(cubemap, L).a;   
68        d = readDistanceCubeMap(cubemap, L1).r;
69        L1 = d * normalize(L1);
70        d = readDistanceCubeMap(cubemap, L2).r;
71        L2 = d * normalize(L2);
72        d = readDistanceCubeMap(cubemap, L3).r;
73        L3 = d * normalize(L3);
74        d = readDistanceCubeMap(cubemap, L4).r;
75        L4 = d * normalize(L4);
76               
77       
78    float3 r1 = normalize(L1 - pos);   
79    float3 r2 = normalize(L2 - pos);
80    float3 r3 = normalize(L3 - pos);
81    float3 r4 = normalize(L4 - pos);
82  /*           
83        float tri1 = acos(dot(r1, r2)) * dot(cross(r1, r2), N);
84        float tri2 = acos(dot(r2, r3)) * dot(cross(r2, r3), N);
85        float tri3 = acos(dot(r3, r4)) * dot(cross(r3, r4), N);
86        float tri4 = acos(dot(r4, r1)) * dot(cross(r4, r1), N);
87  */
88  float3 crossP = cross(r1, r2);
89  float r = length(crossP);
90  float dd = dot(r1,r2);
91  float tri1 = acos(dd) * dot(crossP/r, N);
92 
93  crossP = cross(r2, r3);
94  r = length(crossP);
95  dd = dot(r1,r2);
96  float tri2 = acos(dd) * dot(crossP/r, N);
97 
98  crossP = cross(r3, r4);
99  r = length(crossP);
100  dd = dot(r1,r2);
101  float tri3 = acos(dd) * dot(crossP/r, N);
102 
103  crossP = cross(r4, r1);
104  r = length(crossP);
105  dd = dot(r1,r2);
106  float tri4= acos(dd) * dot(crossP/r, N);
107 
108 
109        return max(tri1 + tri2 + tri3 + tri4, 0);       
110        //return tri1 + tri2 + tri3 + tri4;     
111}
112
113struct Shaded_OUT
114{
115 float4 vPos : POSITION;
116 float4 wNormal : TEXCOORD0;
117 float4 wPos    : TEXCOORD1;
118};
119
120float4 Diffuse_Poly2Point_PS( Shaded_OUT IN,
121                                                        uniform float3 lastCenter,
122                                                        uniform samplerCUBE SmallEnvMapSampler : register(s0),
123                                                        uniform samplerCUBE DistanceEnvMapSampler : register(s1)
124            ) : COLOR0
125{
126    float M = REDUCED_CUBEMAP_SIZE;
127       
128        float3 N = IN.wNormal.xyz;
129    N = normalize( N );
130    float3 pos = IN.wPos.xyz - lastCenter;
131   
132    float4 I = 0;                                                                       
133        float3 L1, L2, L3, L4, L;                                               
134        float4 Le;                                                                             
135        float width = 1.0 / M;                                                 
136        float width2 = width * 2;
137        float d;
138       
139        for (float x = 1; x < M; x++)                   
140         for (float y = 1; y < M; y++)                                                                         
141         {                                                                                                                             
142                float2 p, tpos;
143            tpos.x = x * width;
144            tpos.y = y * width;
145           
146            p = tpos.xy;   
147            p = 2.0 * p - 1.0; //-1..1
148                           
149                L1 = float3(p.x - width, p.y - width, 1);       
150                L2 = float3(p.x + width, p.y - width, 1);       
151                L3 = float3(p.x + width, p.y + width, 1);       
152                L4 = float3(p.x - width, p.y + width, 1);
153                L = float3(p.x, p.y, 1);
154                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
155               
156                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                   
157                       
158        }                                                                                                                                                       
159       
160        for (float x = 1; x < M; x++)                   
161         for (float y = 1; y < M; y++)                                                                                 
162         {                                                                                                                             
163                float2 p, tpos;
164            tpos.x = x * width; // 0..1
165            tpos.y = y * width; // 0..1
166           
167            p = tpos.xy;   
168            p = 2.0 * p - 1.0; //-1..1
169                           
170                L4 = float3(p.x - width, p.y - width, -1);     
171                L3 = float3(p.x + width, p.y - width, -1);     
172                L2 = float3(p.x + width, p.y + width, -1);     
173                L1 = float3(p.x - width, p.y + width, -1);
174                L = float3(p.x, p.y, -1);
175                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
176               
177                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                   
178         }     
179         
180        for (float x = 1; x < M; x++)                   
181         for (float y = 1; y < M; y++)                                                                                 
182         {                                                                                                                             
183                float2 p, tpos;
184            tpos.x = x * width; // 0..1
185            tpos.y = y * width; // 0..1
186           
187            p = tpos.xy;   
188            p = 2.0 * p - 1.0; //-1..1
189                           
190                L4 = float3(p.x - width, 1, p.y - width);
191                L3 = float3(p.x + width, 1, p.y - width);       
192                L2 = float3(p.x + width, 1, p.y + width);       
193                L1 = float3(p.x - width, 1, p.y + width);                       
194                L = float3(p.x, 1, p.y);
195                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
196               
197                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                   
198         }             
199         
200        for (float x = 1; x < M; x++)                   
201         for (float y = 1; y < M; y++)                                                                                 
202         {                                                                                                                             
203                float2 p, tpos;
204            tpos.x = x * width; // 0..1
205            tpos.y = y * width; // 0..1
206           
207            p = tpos.xy;   
208            p = 2.0 * p - 1.0; //-1..1
209                           
210                L1 = float3(p.x - width, -1, p.y - width);
211                L2 = float3(p.x + width, -1, p.y - width);     
212                L3 = float3(p.x + width, -1, p.y + width);     
213                L4 = float3(p.x - width, -1, p.y + width);                     
214                L = float3(p.x, -1, p.y);
215                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
216               
217                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                   
218         }
219         
220         for (float x = 1; x < M; x++)                 
221         for (float y = 1; y < M; y++)                                                                         
222                {                                                                                                                               
223                float2 p, tpos;
224            tpos.x = x * width; // 0..1
225            tpos.y = y * width; // 0..1
226           
227            p = tpos.xy;   
228            p = 2.0 * p - 1.0; //-1..1
229                           
230                L1 = float3(1, p.x - width, p.y - width);
231                L2 = float3(1, p.x + width, p.y - width);       
232                L3 = float3(1, p.x + width, p.y + width);       
233                L4 = float3(1, p.x - width, p.y + width);       
234                L = float3(1, p.x, p.y);
235                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
236               
237                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                   
238        }
239         
240        for (float x = 1; x < M; x++)                   
241         for (float y = 1; y < M; y++)                                                                                 
242         {                                                                                                                             
243                float2 p, tpos;
244            tpos.x = x * width; // 0..1
245            tpos.y = y * width; // 0..1
246           
247            p = tpos.xy;   
248            p = 2.0 * p - 1.0; //-1..1
249                           
250                L4 = float3(-1, p.x - width, p.y - width);
251                L3 = float3(-1, p.x + width, p.y - width);     
252                L2 = float3(-1, p.x + width, p.y + width);     
253                L1 = float3(-1, p.x - width, p.y + width);     
254                L = float3(-1, p.x, p.y);
255                Le = float4(readCubeMap(SmallEnvMapSampler, L).rgb, 1);
256               
257                I += 0.5 * Le * Poly2Point_Contr( L, L1, L2, L3, L4, pos, N, DistanceEnvMapSampler);                           
258         }
259         float kd = 0.32;                                                                                                                                               
260        return kd * I;
261}
262
263/// Point to point form factor
264
265float4 Point2Point_Contr(float3 N, float3 Nl, float3 pos, float3 L, samplerCUBE cubemap, samplerCUBE distmap)
266{
267        Nl = normalize(Nl);
268        L = normalize(L);
269        float4 Le = readCubeMap(cubemap, L);
270        float d = readDistanceCubeMap(distmap, L);
271        float3 Lpos = L * d;
272        float3 Ldir = Lpos - pos;
273        float dist = 4 * dot(Ldir, Ldir);
274        Ldir = normalize(Ldir);
275               
276        return Le * (max(dot(N, Ldir),0) * dot(Nl, -1 * Ldir)) / dist; 
277}
278
279float4 Diffuse_Point2Point_PS( Shaded_OUT IN,
280                                                        uniform float3 lastCenter,
281                                                        uniform samplerCUBE SmallEnvMapSampler : register(s0),
282                                                        uniform samplerCUBE DistanceEnvMapSampler : register(s1)) : COLOR                       
283{               
284        float M = REDUCED_CUBEMAP_SIZE;
285       
286    float3 N = IN.wNormal.xyz;
287    N = normalize( N );
288    float3 pos = IN.wPos.xyz - lastCenter;                                                                                                                                             
289                                                                                                       
290    float4 I = 0;                                                                       
291        float3 L;                                               
292        float4 Le;                                                                             
293        float width = 1.0 / M;
294        float d;       
295       
296        float kd = 1.0;                                                                                                                                         
297               
298        for (float x = 0.5; x < M; x++)                 
299         for (float y = 0.5; y < M; y++)                                                                                       
300         {                                                                                                                             
301                float2 p, tpos;
302            tpos.x = x * width;
303            tpos.y = y * width;
304           
305            p = tpos.xy;   
306            p = 2.0 * p - 1.0; //-1..1
307                           
308                I += Point2Point_Contr(N, float3(0,0,-1), pos, float3(p.x, p.y, 1), SmallEnvMapSampler, DistanceEnvMapSampler);
309                I += Point2Point_Contr(N, float3(0,0,1), pos, float3(-p.x, p.y, -1), SmallEnvMapSampler, DistanceEnvMapSampler);
310                I += Point2Point_Contr(N, float3(-1,0,0), pos, float3(1, p.y, -p.x), SmallEnvMapSampler, DistanceEnvMapSampler);
311                I += Point2Point_Contr(N, float3(1,0,0), pos, float3(-1, p.y, p.x), SmallEnvMapSampler, DistanceEnvMapSampler);
312                I += Point2Point_Contr(N, float3(0,-1,0), pos, float3(p.x, 1, -p.y), SmallEnvMapSampler, DistanceEnvMapSampler);
313                I += Point2Point_Contr(N, float3(0,1,0), pos, float3(p.x, -1, p.y), SmallEnvMapSampler, DistanceEnvMapSampler);
314        }
315                                                                                                                                               
316        return kd * I;                                                                                                                 
317}
318
319/// Disc to point form factor
320
321float4 Disc2Point_Contr(float3 L, float3 pos, float3 N, float3 V, samplerCUBE SmallEnvMapSampler, samplerCUBE DistanceEnvMapSampler)    // Phong-Blinn
322// L: a hossza lényeges (az egységkocka faláig ér)
323{
324        float mindist = 1.0;
325   
326        float kd = 0.3; // 0.3
327        float ks = 0;   // 0.5
328        float shininess = 10;
329       
330        float l = length(L);
331        L = normalize(L);
332
333        //dw
334        float dw = 4 / (REDUCED_CUBEMAP_SIZE*REDUCED_CUBEMAP_SIZE*l*l*l + 4/3.1416f);
335        //Lin
336        float4 Lin = readCubeMap(SmallEnvMapSampler, L);
337        //r
338        float doy = readDistanceCubeMap(DistanceEnvMapSampler, L);
339        float dxy = length(L * doy - pos);
340       
341        dxy = max(mindist, dxy);
342               
343
344        //dws
345        float dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/3.1416f) + doy*doy*dw/3.1416f);   // localization:
346        //float dws = dw;
347       
348        //L = L * doy - pos;    // L: x->y, az objektumtól induljon, ne a középpontból
349        L = normalize(L);
350        float3 H = normalize(L + V);    // felezõvektor
351
352        float a = kd * max(dot(N,L),0) +
353                          ks * pow(max(dot(N,H),0), shininess); // diffuse + specular
354
355        // 1.: eddigi
356        //return Lin * a * dws;
357       
358        float ctheta_in = dot(N,L);
359        float ctheta_out = dot(N,V);   
360       
361        return Lin * a * dws;           
362}
363
364float4 Diffuse_Disc2Point_PS(Shaded_OUT IN,
365                                                        uniform float3 lastCenter,
366                                                        uniform float3 cameraPos,
367                                                        uniform samplerCUBE SmallEnvMapSampler : register(s0),
368                                                        uniform samplerCUBE DistanceEnvMapSampler : register(s1)
369                   ) : COLOR0
370{
371        float M = REDUCED_CUBEMAP_SIZE;
372       
373    float3 N = IN.wNormal.xyz;
374    N = normalize( N );
375    float3 V = normalize(IN.wPos.xyz - cameraPos);
376    float3 pos = IN.wPos.xyz - lastCenter;                                                                                                                                             
377                                                                                                       
378    float4 I = 0;                                                                       
379        float3 L;                                               
380        float4 Le;                                                                             
381        float width = 1.0 / M;
382        float d;       
383                       
384        for (float x = 0.5; x < M; x++)                 
385         for (float y = 0.5; y < M; y++)                                                                                       
386         {                                                                                                                             
387                float2 p, tpos;
388            tpos.x = x * width;
389            tpos.y = y * width;
390           
391            p = tpos.xy;   
392            p = 2.0 * p - 1.0; //-1..1
393           
394            float3 L;
395           
396                L = float3(p.x, p.y, 1);
397                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
398               
399                L = float3(p.x, p.y, -1);
400                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
401               
402                L = float3(p.x, 1, p.y);
403                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
404               
405                L = float3(p.x, -1, p.y);
406                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
407               
408                L = float3(1, p.x, p.y);
409                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
410               
411                L = float3(-1, p.x, p.y);
412                I += Disc2Point_Contr( L, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler);
413        }
414        float kd = 1.0;
415        return kd * I;
416}
Note: See TracBrowser for help on using the repository browser.