source: GTP/trunk/App/Demos/Illum/EnvMap/EnvMap.fx @ 1672

Revision 1672, 33.4 KB checked in by szirmay, 18 years ago (diff)
Line 
1//--------------------------------------------------------------------------------------
2// File: EnvMap.fx
3//
4// The effect file for the OptimizedMesh sample. 
5//
6// Copyright (c) Microsoft Corporation. All rights reserved.
7//--------------------------------------------------------------------------------------
8
9
10/// size of the cube map taken from the reference point of the object
11#define CUBEMAP_SIZE    128
12/// size of the cube map for diffuse/glossy reflections
13int LR_CUBEMAP_SIZE;
14#define PI 3.14159f
15
16
17//--------------------------------------------------------------------------------------
18// Global variables
19//--------------------------------------------------------------------------------------
20
21
22float4x4 World;                                 ///< World matrix for the current object
23float4x4 WorldIT;                               ///< World matrix IT (inverse transposed) to transform surface normals of the current object
24float4x4 WorldView;                             ///< World * View matrix
25//float4x4 WorldViewIT;                 ///< World * View IT (inverse transposed) to transform surface normals of the current object
26float4x4 WorldViewProjection;   ///< World * View * Projection matrix
27
28float texel_size;                               ///< upload this constant every time the viewport changes
29
30float4 eyePos;                                  ///< current eye (camera) position
31float4 reference_pos;                   ///< Reference point for the last cube map generation.
32
33int nFace;                                              ///<
34int iShowCubeMap;                               ///<
35float4 objColor;
36
37float intensity, shininess, brightness;
38
39
40//--------------------------------------------------------------------------------------
41// Textures & texture samplers
42//--------------------------------------------------------------------------------------
43
44
45texture EnvironmentMap, SmallEnvironmentMap, PreconvolvedEnvironmentMap, Decoration;
46
47sampler EnvironmentMapSampler = sampler_state
48{
49    /*MinFilter = LINEAR;
50    MagFilter = LINEAR;
51    MipFilter = LINEAR;*/
52    Texture   = <EnvironmentMap>;
53    AddressU  = WRAP;
54    AddressV  = WRAP;
55};
56
57sampler PreconvolvedEnvironmentMapSampler = sampler_state
58{
59    MinFilter = LINEAR;
60    MagFilter = LINEAR;
61    //MipFilter = LINEAR;
62    Texture   = <PreconvolvedEnvironmentMap>;
63    AddressU  = WRAP;
64    AddressV  = WRAP;
65};
66
67sampler SmallEnvironmentMapSampler = sampler_state
68{
69//    MinFilter = Point;
70//    MagFilter = Point;
71
72    MinFilter = LINEAR;
73    MagFilter = LINEAR;
74
75    //MipFilter = Point;
76    Texture   = <SmallEnvironmentMap>;
77    AddressU  = WRAP;
78    AddressV  = WRAP;
79};
80
81sampler DecorationSampler = sampler_state
82{
83    Texture   = <Decoration>;
84    MinFilter = LINEAR;
85    MagFilter = LINEAR;
86    //MipFilter = LINEAR;
87    AddressU  = CLAMP; //WRAP;
88    AddressV  = CLAMP; //WRAP;
89};
90
91
92
93//--------------------------------------------------------------------------------------
94// Shader programs
95//--------------------------------------------------------------------------------------
96
97
98
99void ReduceTextureVS( float4 position : POSITION,
100                float4 color0 : COLOR0,
101                float3 Normal : NORMAL,
102                float2 Tex : TEXCOORD0,
103                out float4 hposition : POSITION,
104                out float4 color : COLOR0,
105                out float2 oTex : TEXCOORD0,
106                out float4 pos : TEXCOORD1 )
107{
108    pos = position;
109    hposition = pos;
110    color = color0;
111    oTex = Tex;
112}
113
114/**
115        \brief Downsamples a cube map face.
116*/
117#define _ReduceTexturePS( M )                                                                                                           \
118        float4 ReduceTexture##M##PS( float2 Tex : TEXCOORD0,                                                    \
119                                  float4 pos : TEXCOORD1,                                                                                       \
120                                  float4 color0 : COLOR0 ) : COLOR0                                                                     \
121{                                                                                                                                                                       \
122        /* offset to texel center */                                                                                                    \
123        pos.xy += float2(1/(float)CUBEMAP_SIZE, -1/(float)CUBEMAP_SIZE);                                \
124        /* transform position into texture coord */                                                                             \
125    float2 tpos = pos.xy/2+0.5;         /* rescale from -1..1 into range 0..1 */                \
126    tpos.y = 1-tpos.y;                                                                                                                          \
127                                                                                                                                                                        \
128    float2 t;                                                                                                                                           \
129    float4 color = 0;                                                                                                                           \
130        const int RATE = CUBEMAP_SIZE / M;                                                                                              \
131                                                                                                                                                                        \
132    for (int i = 0; i < RATE; i++)                                                                                                      \
133     for (int j = 0; j < RATE; j++)                                                                                                     \
134    {                                                                                                                                                           \
135                t.x = tpos.x + i/(float)CUBEMAP_SIZE;                                                                           \
136                t.y = tpos.y + j/(float)CUBEMAP_SIZE;                                                                           \
137                color += tex2D(DecorationSampler, t) / (RATE * RATE);                                           \
138    }                                                                                                                                                           \
139        return color;                                                                                                                                   \
140} // end of macro definition
141
142_ReduceTexturePS( 2 );
143_ReduceTexturePS( 4 );
144_ReduceTexturePS( 8 );
145_ReduceTexturePS( 16 );
146
147
148
149//--------------------------------------------------------------------------------------
150// Method #0: CLASSIC (pre-convolved)
151//--------------------------------------------------------------------------------------
152
153
154
155/// \brief Returns the precalculated contribution of a texel with regard to the specified query direction.
156///
157/// \param q <b>query direction</b> (i.e. surface normal in diffuse case, ideal reflection direction in specular case).
158/// \param L vector pointing to the texel center
159float4 GetContr(float3 q, float3 L)
160// Lin * a * ( dw )
161// -- actually, dw is calculated by the caller --
162{
163        //float shininess = 1;
164        float fcos = max(dot(L, q), 0);
165        // diffuse
166        if (shininess <= 0)     
167                return 0.2 * fcos * texCUBE( SmallEnvironmentMapSampler, L);
168        else
169        {
170                // some ad-hoc formula to avoid darkening
171                float brightness = (pow(shininess,0.8)*0.2);
172                return brightness * pow(fcos, shininess) * texCUBE( SmallEnvironmentMapSampler, L);
173        }
174}
175
176/// \brief Input for vertex shader ConvolutionVS().
177struct _ConvolutionVS_input {
178    float4 Position : POSITION;
179};
180
181/// \brief Input for pixel shader ::_ConvolutionPS().
182struct _ConvolutionVS_output {
183    float4 hPosition : POSITION;
184    float3 Position  : TEXCOORD0;
185};
186
187_ConvolutionVS_output ConvolutionVS(_ConvolutionVS_input IN) {
188    _ConvolutionVS_output OUT;
189    OUT.hPosition = IN.Position;
190   
191        float2 pos = IN.Position.xy;    // -1..1
192
193        pos.x += 0.5f / LR_CUBEMAP_SIZE;
194        pos.y -= 0.5f / LR_CUBEMAP_SIZE;       
195   
196        if (nFace == 0) OUT.Position = float3(1, pos.y, -pos.x);
197        if (nFace == 1) OUT.Position = float3(-1, pos.y, pos.x);
198        if (nFace == 2) OUT.Position = float3(pos.x, 1, -pos.y);
199        if (nFace == 3) OUT.Position = float3(pos.x,-1, pos.y);
200        if (nFace == 4) OUT.Position = float3(pos.xy, 1);
201        if (nFace == 5) OUT.Position = float3(-pos.x, pos.y,-1);
202       
203    return OUT;
204}
205
206/**
207        \brief Convolves the values of a cube map of resoultion MxM.
208
209        Calculates the diffuse/specular irradiance map of resolution #LR_CUBEMAP_SIZE by summing up the contributions of all cube map texels
210        with regard to the current query direction.
211*/
212
213#define _ConvolutionPS( M )                                                                                                     \
214        float4 Convolution##M##PS( _ConvolutionVS_output IN ) : COLOR                   \
215{                                                                                                                                                       \
216        /* input position = query direction for the result */                                   \
217    float3 q = normalize( IN.Position );                                                                        \
218    float4 color = 0;                                                                                                           \
219                                                                                                                                                        \
220    for (int i = 0; i < M; i++)                                                                                         \
221     for (int j = 0; j < M; j++)                                                                                        \
222    {                                                                                                                                           \
223        float u = (i+0.5) / (float)M;                                                                           \
224        float v = (j+0.5) / (float)M;                                                                           \
225        float3 pos = float3( 2*u-1, 1-2*v, 1 );                                                         \
226                                                                                                                                                        \
227                float r = length(pos);                                                                                          \
228                pos /= r;                                                                                                                       \
229                                                                                                                                                        \
230                float4 dcolor = 0;                                                                                                      \
231            float3 L;                                                                                                                   \
232                L = float3(pos.z, pos.y, -pos.x);       dcolor += GetContr( q, L );             \
233                L = float3(-pos.z, pos.y, pos.x);       dcolor += GetContr( q, L );             \
234                L = float3(pos.x, pos.z, -pos.y);       dcolor += GetContr( q, L );             \
235                L = float3(pos.x, -pos.z, pos.y);       dcolor += GetContr( q, L );             \
236                L = float3(pos.x, pos.y, pos.z);        dcolor += GetContr( q, L );             \
237                L = float3(-pos.x, pos.y, -pos.z);      dcolor += GetContr( q, L );             \
238                                                                                                                                                        \
239                float dw = 4 / (r*r*r);                                                                                         \
240                color += dcolor * dw;                                                                                           \
241    }                                                                                                                                           \
242                                                                                                                                                        \
243        return color / (M * M);                                                                                                 \
244} /* end of macro definition */
245
246_ConvolutionPS( 2 );
247_ConvolutionPS( 4 );
248_ConvolutionPS( 8 );
249_ConvolutionPS( 16 );
250
251/// \brief Input for vertex shader EnvMapVS().
252struct _EnvMapVS_input
253{
254    float4 Position                     : POSITION;
255    float3 Normal                       : NORMAL;
256    float2 TexCoord                     : TEXCOORD0;
257};
258
259/// \brief Input for pixel shaders EnvMapDiffuseClassicPS(), ::_EnvMapDiffuseLocalizedPS(), EnvMapDiffuseLocalized5TexPS().
260struct _EnvMapVS_output
261{
262    float4 hPosition            : POSITION;
263    float2 TexCoord                     : TEXCOORD0;
264    float3 Normal                       : TEXCOORD1;
265    float3 View                         : TEXCOORD2;
266    float3 Position                     : TEXCOORD3;
267};
268
269_EnvMapVS_output EnvMapVS( _EnvMapVS_input IN )
270{
271        _EnvMapVS_output OUT;
272 
273    OUT.Position = mul( IN.Position, World ).xyz;               // scale & offset
274    OUT.View = normalize( OUT.Position - eyePos );
275        //OUT.Normal = IN.Normal;                                                               
276    OUT.Normal = mul( IN.Normal, WorldIT ).xyz;                 // allow distortion/rotation
277           
278    OUT.TexCoord = IN.TexCoord;
279   
280    OUT.hPosition = mul( IN.Position, WorldViewProjection );
281    return OUT;
282}
283
284/// \brief Determines diffuse or specular illumination with a single lookup into #PreconvolvedEnvironmentMap.
285/// PreconvolvedEnvironmentMap is bound to EnvMap::pCubeTexturePreConvolved (cube map of resolution #LR_CUBEMAP_SIZE).
286float4 EnvMapDiffuseClassicPS( _EnvMapVS_output IN ) : COLOR
287{
288        IN.View = normalize( IN.View );
289        IN.Normal = normalize( IN.Normal );
290       
291        float3 R = reflect(IN.View, IN.Normal);
292
293        if (shininess <= 0)     // diffuse
294                return intensity * texCUBE(PreconvolvedEnvironmentMapSampler, IN.Normal) *2;           
295        else                            // specular
296                return intensity * texCUBE(PreconvolvedEnvironmentMapSampler, R) *2;   
297}
298
299
300
301//--------------------------------------------------------------------------------------
302// Method #1-#2: OUR METHOD
303//--------------------------------------------------------------------------------------
304
305
306
307/// \brief Calculates the contribution of a single texel of #SmallEnvironmentMap to the illumination of the shaded point.
308/// To compute reflectivity, precalculated integral values are used.
309///
310/// \param L vector pointing to the center of the texel under examination. We assume that the largest coordinate component
311/// of L is equal to one, i.e. L points to the face of a cube of edge length of 2.
312/// \param pos is the position of the shaded point
313/// \param N is the surface normal at the shaded point
314/// \param V is the viewing direction at the shaded point
315
316
317float4 GetContr(int M, float3 L, float3 pos, float3 N, float3 V)        // Phong-Blinn
318// L is strictly non-normalized
319{
320        float l = length(L);
321        L = normalize(L);
322
323        //Lin
324        float4 Lin = texCUBE(SmallEnvironmentMapSampler, L);
325
326        //dw
327        float dw = 4 / (M*M*l*l*l + 4/2/3.1416f);
328       
329        float dws = dw;
330
331        //r
332        float doy = texCUBE(SmallEnvironmentMapSampler, L).a;
333        float dxy = length(pos - L * doy);
334
335        //dws
336        //dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/3.1416f) + doy*doy*dw/3.1416f);       // localization:
337        //dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/2/3.1416f) + doy*doy*dw/2/3.1416f);   // localization:
338       
339        float den = 1 + doy*doy / (dxy*dxy) * ( (2*3.1416f)*(2*3.1416f) / ((2*3.1416f-dw)*(2*3.1416f-dw)) - 1 );
340        dws = 2*3.1416f * (1 - 1/sqrt(den));
341
342        float3 LL = L * doy - pos;      // L should start from the object (and not from the reference point) !!!
343        LL = normalize(LL);     
344       
345        float3 H = normalize(L + V);    // halfway vector
346        float3 R = reflect(-V, N);              // reflection vector
347
348        // from texture
349
350        float4 color = 0;
351
352        float cos_value;
353        if (shininess <= 0)
354                 cos_value = dot(N,L);  // diffuse
355        else cos_value = dot(R,L);      // specular
356       
357        float2 tex;
358        tex.x = (cos_value + 1)/2;
359        tex.y = dws/2/PI;
360
361        // lookup into precalculated reflectivity values
362        cos_value = tex2D(DecorationSampler, tex).g * 3;
363        color = Lin * 0.5 * cos_value;
364       
365        return color;
366}
367
368// Method #1
369
370/// \brief Calculates diffuse or specular contributions of all texels in #SmallEnvironmentMap to the current point.
371/// For each texel of #SmallEnvironmentMap, function GetContr(int,float3,float3,float3,float3) is called.
372
373#define _EnvMapDiffuseLocalizedPS( M )                                                                  \
374        float4 EnvMapDiffuseLocalized##M##PS( _EnvMapVS_output IN ) : COLOR     \
375{                                                                                                                                                                       \
376        IN.View = -normalize( IN.View );                                                                                                \
377        IN.Normal = normalize( IN.Normal );                                                                                             \
378        IN.Position -= reference_pos.xyz;                               /* relative to the ref.point */ \
379                                                                                                                                                                        \
380        float3 R = -reflect( IN.View, IN.Normal );              /* reflection direction */              \
381                                                                                                                                                                        \
382    float4 I = 0;                                                                                                                                       \
383                                                                                                                                                                        \
384        for (int x = 0; x < M; x++)                     /* foreach texel */                                                     \
385         for (int y = 0; y < M; y++)                                                                                                    \
386         {                                                                                                                                                              \
387                /* compute intensity for 6 texels with equal solid angles */                            \
388                                                                                                                                                                        \
389                float2 tpos = float2( (x+0.5f)/M, (y+0.5f)/M ); /* texture coord (0..1) */      \
390                                                                                                                                                                        \
391            float2 p = float2(tpos.x, 1-tpos.y);                                                                                \
392            p.xy = 2*p.xy - 1;                                                          /* position (-1..1) */          \
393                                                                                                                                                                        \
394                I += GetContr( M, float3(p.x, p.y,  1), IN.Position, IN.Normal, IN.View );      \
395                I += GetContr( M, float3(p.x, p.y, -1), IN.Position, IN.Normal, IN.View );      \
396                I += GetContr( M, float3(p.x,  1, p.y), IN.Position, IN.Normal, IN.View );      \
397                I += GetContr( M, float3(p.x, -1, p.y), IN.Position, IN.Normal, IN.View );      \
398                I += GetContr( M, float3(1,  p.x, p.y), IN.Position, IN.Normal, IN.View );      \
399                I += GetContr( M, float3(-1, p.x, p.y), IN.Position, IN.Normal, IN.View );      \
400        }                                                                                                                                                               \
401                                                                                                                                                                        \
402        return intensity * I;                                                                                                                   \
403} // end of macro definition
404
405_EnvMapDiffuseLocalizedPS( 2 );
406_EnvMapDiffuseLocalizedPS( 4 );
407_EnvMapDiffuseLocalizedPS( 8 );
408_EnvMapDiffuseLocalizedPS( 16 );
409
410
411// Method #2
412
413/// \brief Calculates diffuse or specular contributions of the 5 "most important" texels of #SmallEnvironmentMap to the current point.
414/// For these texels, function GetContr(int,float3,float3,float3,float3) is called.
415
416float4 EnvMapDiffuseLocalized5TexPS( _EnvMapVS_output IN ) : COLOR
417{
418        IN.View = -normalize( IN.View );
419        IN.Normal = normalize( IN.Normal );
420        // translate reference point to the origin
421        IN.Position -= reference_pos.xyz;               
422       
423        float3 R = -reflect( IN.View, IN.Normal );              // reflection direction
424       
425    float4 I = 0;
426
427        float3 q;
428        if ( shininess <= 0 )
429                q = IN.Normal;                                  // diffuse
430        else
431                q = R;
432               
433    float rr = max( max(abs(q.x), abs(q.y)), abs(q.z) );        // select the largest component
434    q /= rr;    // scale the largest component to value +/-1
435   
436    float3 offset1 = float3(1,0,0);                                             // default: largest: z
437    float3 offset2 = float3(0,1,0);                                             // select: x,y
438   
439    if (abs(q.x) > abs(q.y) && abs(q.x) > abs(q.z)) {   // largest: x
440                offset1 = float3(0,0,1);                                                // select y,z
441        }
442    if (abs(q.y) > abs(q.x) && abs(q.y) > abs(q.z)) {   // largest: y
443                offset2 = float3(0,0,1);                                                // select x,z
444        }
445
446        I += GetContr( LR_CUBEMAP_SIZE, q, IN.Position, IN.Normal, IN.View );
447        I += GetContr( LR_CUBEMAP_SIZE, q + offset1*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View );
448        I += GetContr( LR_CUBEMAP_SIZE, q - offset1*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View );
449        I += GetContr( LR_CUBEMAP_SIZE, q + offset2*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View );
450        I += GetContr( LR_CUBEMAP_SIZE, q - offset2*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View );
451       
452        // since only 5 texels are considered, the result gets darker.
453        // LR_CUBEMAP_SIZE is present to compensate this.
454        return intensity * I * LR_CUBEMAP_SIZE / 2;             
455}
456
457// Method #3
458
459/// \brief Calculates diffuse or specular contributions of the 5 "most important" texels of #SmallEnvironmentMap to the current point.
460/// For these texels, function GetContr(int,float3,float3,float3,float3) is called.
461float4 GetContibution(float3 L, float3 L1, float3 L2, float3 L3, float3 L4, float3 pos, float3 N, samplerCUBE cubemap)
462{
463        float d;
464        //d = texCUBE(cubemap, L).a;   
465        d = texCUBE(cubemap, L1).a;     
466        L1 = d * normalize(L1);
467        d = texCUBE(cubemap, L2).a;     
468        L2 = d * normalize(L2);
469        d = texCUBE(cubemap, L3).a;     
470        L3 = d * normalize(L3);
471        d = texCUBE(cubemap, L4).a;     
472        L4 = d * normalize(L4);
473               
474       
475    float3 r1 = normalize(L1 - pos);   
476    float3 r2 = normalize(L2 - pos);
477    float3 r3 = normalize(L3 - pos);
478    float3 r4 = normalize(L4 - pos);
479  /*           
480        float tri1 = acos(dot(r1, r2)) * dot(cross(r1, r2), N);
481        float tri2 = acos(dot(r2, r3)) * dot(cross(r2, r3), N);
482        float tri3 = acos(dot(r3, r4)) * dot(cross(r3, r4), N);
483        float tri4 = acos(dot(r4, r1)) * dot(cross(r4, r1), N);
484  */
485  float3 crossP = cross(r1, r2);
486  float r = length(crossP);
487  float dd = dot(r1,r2);
488  float tri1 = acos(dd) * dot(crossP/r, N);
489 
490  crossP = cross(r2, r3);
491  r = length(crossP);
492  dd = dot(r1,r2);
493  float tri2 = acos(dd) * dot(crossP/r, N);
494 
495  crossP = cross(r3, r4);
496  r = length(crossP);
497  dd = dot(r1,r2);
498  float tri3 = acos(dd) * dot(crossP/r, N);
499 
500  crossP = cross(r4, r1);
501  r = length(crossP);
502  dd = dot(r1,r2);
503  float tri4= acos(dd) * dot(crossP/r, N);
504 
505 
506        return max(tri1 + tri2 + tri3 + tri4, 0);       
507        //return tri1 + tri2 + tri3 + tri4;     
508}
509
510
511
512
513float4 EnvMapDiffuseLocalizedNewPS( _EnvMapVS_output IN ) : COLOR                       
514{               
515        float M = 4.0;                                                                                                                                                 
516        IN.View = -normalize( IN.View );                                                                                               
517        IN.Normal = normalize( IN.Normal );                                                                                             
518        IN.Position -= reference_pos.xyz;                               
519        float3 pos = IN.Position.xyz;   
520       
521        //return        reference_pos;
522        //return  texCUBE(SmallEnvironmentMapSampler, pos);     
523                                                                                               
524        float3 N =IN.Normal;                                                                                                                                                           
525        float3 R = -reflect( IN.View, IN.Normal );             
526                                                                                                       
527    float4 I = 0;                                                                       
528        float3 L1, L2, L3, L4, L;                                               
529        float4 Le;                                                                             
530        float width = 1.0 / M;                                                 
531        float width2 = width * 2;
532        float d;
533       
534        for (float x = 0; x < M; x++)                   
535         for (float y = 0; y < M; y++)                                                                                 
536         {                                                                                                                             
537                float2 p, tpos;
538            tpos.x = x * width;
539            tpos.y = y * width;
540           
541            p = tpos.xy;   
542            p = 2.0 * p - 1.0; //-1..1
543                           
544                L1 = float3(p.x, p.y, 1);       
545                L2 = float3(p.x + width2, p.y, 1);     
546                L3 = float3(p.x + width2, p.y + width2, 1);     
547                L4 = float3(p.x, p.y + width2, 1);
548                L = float3(p.x + width, p.y + width, 1);
549                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
550               
551                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
552                       
553        }                                                                                                                                                       
554       
555        for (float x = 0; x < M; x++)                   
556         for (float y = 0; y < M; y++)                                                                                 
557         {                                                                                                                             
558                float2 p, tpos;
559            tpos.x = x * width; // 0..1
560            tpos.y = y * width; // 0..1
561           
562            p = tpos.xy;   
563            p = 2.0 * p - 1.0; //-1..1
564                           
565                L4 = float3(p.x, p.y, -1);     
566                L3 = float3(p.x + width2, p.y, -1);     
567                L2 = float3(p.x + width2, p.y + width2, -1);   
568                L1 = float3(p.x, p.y + width2, -1);
569                L = float3(p.x + width, p.y + width, -1);
570                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
571               
572                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
573         }     
574         
575        for (float x = 0; x < M; x++)                   
576         for (float y = 0; y < M; y++)                                                                                 
577         {                                                                                                                             
578                float2 p, tpos;
579            tpos.x = x * width; // 0..1
580            tpos.y = y * width; // 0..1
581           
582            p = tpos.xy;   
583            p = 2.0 * p - 1.0; //-1..1
584                           
585                L4 = float3(p.x, 1, p.y);
586                L3 = float3(p.x + width2, 1, p.y);     
587                L2 = float3(p.x + width2, 1, p.y + width2);     
588                L1 = float3(p.x, 1, p.y + width2);                     
589                L = float3(p.x + width, 1, p.y + width);
590                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
591               
592                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
593         }             
594         
595        for (float x = 0; x < M; x++)                   
596         for (float y = 0; y < M; y++)                                                                                 
597         {                                                                                                                             
598                float2 p, tpos;
599            tpos.x = x * width; // 0..1
600            tpos.y = y * width; // 0..1
601           
602            p = tpos.xy;   
603            p = 2.0 * p - 1.0; //-1..1
604                           
605                L1 = float3(p.x, -1, p.y);
606                L2 = float3(p.x + width2, -1, p.y);     
607                L3 = float3(p.x + width2, -1, p.y + width2);   
608                L4 = float3(p.x, -1, p.y + width2);                     
609                L = float3(p.x + width, -1, p.y + width);
610                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
611               
612                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
613         }
614         
615         for (float x = 0; x < M; x++)                 
616                for (float y = 0; y < M; y++)                                                                                   
617                {                                                                                                                               
618                float2 p, tpos;
619            tpos.x = x * width; // 0..1
620            tpos.y = y * width; // 0..1
621           
622            p = tpos.xy;   
623            p = 2.0 * p - 1.0; //-1..1
624                           
625                L1 = float3(1, p.x, p.y);
626                L2 = float3(1, p.x + width2, p.y);     
627                L3 = float3(1, p.x + width2, p.y + width2);     
628                L4 = float3(1, p.x, p.y + width2);     
629                L = float3(1, p.x + width, p.y + width);
630                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
631               
632                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
633        }
634         
635        for (float x = 0; x < M; x++)                   
636         for (float y = 0; y < M; y++)                                                                                 
637         {                                                                                                                             
638                float2 p, tpos;
639            tpos.x = x * width; // 0..1
640            tpos.y = y * width; // 0..1
641           
642            p = tpos.xy;   
643            p = 2.0 * p - 1.0; //-1..1
644                           
645                L4 = float3(-1, p.x, p.y);
646                L3 = float3(-1, p.x + width2, p.y);     
647                L2 = float3(-1, p.x + width2, p.y + width2);   
648                L1 = float3(-1, p.x, p.y + width2);     
649                L = float3(-1, p.x + width, p.y + width);
650                Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
651               
652                I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                         
653         }                                                                                                                                                             
654        return intensity * I;                                                                                                                   
655}
656
657float4 P2PContr(float3 N, float3 Nl, float3 pos, float3 L, samplerCUBE cubemap)
658{
659        Nl = normalize(Nl);
660        L = normalize(L);
661        float4 Le = float4(texCUBE(cubemap, L).rgb, 1);
662        float d = texCUBE(cubemap, L).a;
663        float3 Lpos = L * d;
664        float3 Ldir = Lpos - pos;
665        float dist = dot(Ldir, Ldir);
666        Ldir = normalize(Ldir);
667       
668        return Le * max(dot(N, Ldir),0) * dot(Nl, -1 * Ldir) / dist;   
669}
670
671float4 EnvMapDiffuseP2PPS( _EnvMapVS_output IN ) : COLOR                       
672{               
673        float M = 4.0;                                                                                                                                                 
674        IN.View = -normalize( IN.View );                                                                                               
675        IN.Normal = normalize( IN.Normal );                                                                                             
676        IN.Position -= reference_pos.xyz;                               
677        float3 pos = IN.Position.xyz;   
678       
679        //return        reference_pos;
680        //return  texCUBE(SmallEnvironmentMapSampler, pos);     
681                                                                                               
682        float3 N =IN.Normal;                                                                                                                                                           
683                                                                                                       
684    float4 I = 0;                                                                       
685        float3 L;                                               
686        float4 Le;                                                                             
687        float width = 1.0 / M;
688        float d;                                                       
689       
690        for (float x = 0.5; x < M; x++)                 
691         for (float y = 0.5; y < M; y++)                                                                                       
692         {                                                                                                                             
693                float2 p, tpos;
694            tpos.x = x * width;
695            tpos.y = y * width;
696           
697            p = tpos.xy;   
698            p = 2.0 * p - 1.0; //-1..1
699                           
700                I += P2PContr(N, float3(0,0,-1), pos, float3(p.x, p.y, 1), SmallEnvironmentMapSampler);
701                I += P2PContr(N, float3(0,0,1), pos, float3(-p.x, p.y, -1), SmallEnvironmentMapSampler);
702                I += P2PContr(N, float3(-1,0,0), pos, float3(1, p.y, -p.x), SmallEnvironmentMapSampler);
703                I += P2PContr(N, float3(1,0,0), pos, float3(-1, p.y, p.x), SmallEnvironmentMapSampler);
704                I += P2PContr(N, float3(0,-1,0), pos, float3(p.x, 1, -p.y), SmallEnvironmentMapSampler);
705                I += P2PContr(N, float3(0,1,0), pos, float3(p.x, -1, p.y), SmallEnvironmentMapSampler);
706        }
707                                                                                                                                               
708        return intensity * I;                                                                                                                   
709}
710
711float4 EnvMapDiffuseAdaptPS( _EnvMapVS_output IN ) : COLOR                     
712{               
713        float M = 4.0;                                                                                                                                                 
714        IN.View = -normalize( IN.View );                                                                                               
715        IN.Normal = normalize( IN.Normal );                                                                                             
716        IN.Position -= reference_pos.xyz;                               
717        float3 pos = IN.Position.xyz;   
718       
719        //return        reference_pos;
720        //return  texCUBE(SmallEnvironmentMapSampler, pos);     
721                                                                                               
722        float3 N =IN.Normal;                                                                                                                                                           
723        float3 R = -reflect( IN.View, IN.Normal );             
724                                                                                                       
725    float4 I = 0;                                                                       
726        float3 L1, L2, L3, L4, L;                                               
727        float4 Le;
728        float Ld;                                                                               
729        float width = 1.0 / M;                                                 
730        float width2 = width * 2;
731        float d;
732       
733        for (float x = 0; x < M; x++)                   
734         for (float y = 0; y < M; y++)                                                                                 
735         {                                                                                                                             
736                float2 p, tpos;
737            tpos.x = x * width;
738            tpos.y = y * width;
739           
740            p = tpos.xy;   
741            p = 2.0 * p - 1.0; //-1..1
742           
743            L = float3(p.x + width, p.y + width, 1);
744                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
745               
746                float dist = length(normalize(L) * Ld - pos);
747                if(dist < 1.0)
748                {                   
749                        L1 = float3(p.x, p.y, 1);       
750                        L2 = float3(p.x + width2, p.y, 1);     
751                        L3 = float3(p.x + width2, p.y + width2, 1);     
752                        L4 = float3(p.x, p.y + width2, 1);
753                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
754               
755                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);
756                }
757                else
758                        I += P2PContr(N, float3(0,0,-1), pos, L, SmallEnvironmentMapSampler);                           
759                       
760        }                                                                                                                                                       
761       
762        for (float x = 0; x < M; x++)                   
763         for (float y = 0; y < M; y++)                                                                                 
764         {                                                                                                                             
765                float2 p, tpos;
766            tpos.x = x * width; // 0..1
767            tpos.y = y * width; // 0..1
768           
769            p = tpos.xy;   
770            p = 2.0 * p - 1.0; //-1..1
771           
772            L = float3(p.x + width, p.y + width, -1);
773                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
774               
775                float dist = length(normalize(L) * Ld - pos);
776                if(dist < 1.0)
777                {                           
778                        L4 = float3(p.x, p.y, -1);     
779                        L3 = float3(p.x + width2, p.y, -1);     
780                        L2 = float3(p.x + width2, p.y + width2, -1);   
781                        L1 = float3(p.x, p.y + width2, -1);
782                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
783                       
784                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
785                }
786                else
787                        I += P2PContr(N, float3(0,0,1), pos, L, SmallEnvironmentMapSampler);           
788         }     
789         
790        for (float x = 0; x < M; x++)                   
791         for (float y = 0; y < M; y++)                                                                                 
792         {                                                                                                                             
793                float2 p, tpos;
794            tpos.x = x * width; // 0..1
795            tpos.y = y * width; // 0..1
796           
797            p = tpos.xy;   
798            p = 2.0 * p - 1.0; //-1..1
799           
800            L = float3(p.x + width, 1, p.y + width);
801                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
802               
803                float dist = length(normalize(L) * Ld - pos);
804                if(dist < 1.0)
805                {                           
806                        L4 = float3(p.x, 1, p.y);
807                        L3 = float3(p.x + width2, 1, p.y);     
808                        L2 = float3(p.x + width2, 1, p.y + width2);     
809                        L1 = float3(p.x, 1, p.y + width2);                     
810                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
811                       
812                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
813                }
814                else
815                        I += P2PContr(N, float3(0,-1,0), pos, L, SmallEnvironmentMapSampler);
816               
817         }             
818         
819        for (float x = 0; x < M; x++)                   
820         for (float y = 0; y < M; y++)                                                                                 
821         {                                                                                                                             
822                float2 p, tpos;
823            tpos.x = x * width; // 0..1
824            tpos.y = y * width; // 0..1
825           
826            p = tpos.xy;   
827            p = 2.0 * p - 1.0; //-1..1
828           
829            L = float3(p.x + width, -1, p.y + width);
830                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
831               
832                float dist = length(normalize(L) * Ld - pos);
833                if(dist < 1.0)
834                {                   
835                        L1 = float3(p.x, -1, p.y);
836                        L2 = float3(p.x + width2, -1, p.y);     
837                        L3 = float3(p.x + width2, -1, p.y + width2);   
838                        L4 = float3(p.x, -1, p.y + width2);                     
839                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
840                       
841                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
842                }
843                else
844                        I += P2PContr(N, float3(0,1,0), pos, L, SmallEnvironmentMapSampler);
845               
846         }
847         
848         for (float x = 0; x < M; x++)                 
849                for (float y = 0; y < M; y++)                                                                                   
850                {                                                                                                                               
851                float2 p, tpos;
852            tpos.x = x * width; // 0..1
853            tpos.y = y * width; // 0..1
854           
855            p = tpos.xy;   
856            p = 2.0 * p - 1.0; //-1..1
857           
858                L = float3(1, p.x + width, p.y + width);
859                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
860                float dist = length(normalize(L) * Ld - pos);
861                if(dist < 1.0)
862                {                           
863                        L1 = float3(1, p.x, p.y);
864                        L2 = float3(1, p.x + width2, p.y);     
865                        L3 = float3(1, p.x + width2, p.y + width2);     
866                        L4 = float3(1, p.x, p.y + width2);     
867                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
868                       
869                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                 
870                }
871                else
872                        I += P2PContr(N, float3(-1,0,0), pos, L, SmallEnvironmentMapSampler);
873               
874        }
875
876        for (float x = 0; x < M; x++)                   
877         for (float y = 0; y < M; y++)                                                                                 
878         {                                                                                                                             
879                float2 p, tpos;
880            tpos.x = x * width; // 0..1
881            tpos.y = y * width; // 0..1
882           
883            p = tpos.xy;   
884            p = 2.0 * p - 1.0; //-1..1
885           
886            L = float3(-1, p.x + width, p.y + width);
887                Ld = texCUBE(SmallEnvironmentMapSampler, L).a;
888                float dist = length(normalize(L) * Ld - pos);
889                if(dist < 1.0)
890                {                   
891                        L4 = float3(-1, p.x, p.y);
892                        L3 = float3(-1, p.x + width2, p.y);     
893                        L2 = float3(-1, p.x + width2, p.y + width2);   
894                        L1 = float3(-1, p.x, p.y + width2);     
895                        Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1);
896                       
897                        I += 0.5 * Le * GetContibution( L, L1, L2, L3, L4, pos, N, SmallEnvironmentMapSampler);                         
898                       
899                }
900                else
901                        I += P2PContr(N, float3(1,0,0), pos, L, SmallEnvironmentMapSampler);           
902         }                                                                                                                                                             
903        return intensity * I;                                                                                                                   
904}
905//--------------------------------------------------------------------------------------
906// Shading the environment
907//--------------------------------------------------------------------------------------
908
909/// \brief Input for vertex shader IlluminatedSceneVS().
910struct _IlluminatedSceneVS_input {
911    float4 Position : POSITION;
912    float3 Normal : NORMAL;
913    float2 TexCoord : TEXCOORD0;
914};
915
916/// \brief Input for pixel shader IlluminatedScenePS().
917struct _IlluminatedSceneVS_output {
918    float4 hPosition : POSITION;
919    float2 TexCoord : TEXCOORD0;
920    float3 Position : TEXCOORD1;
921};
922
923_IlluminatedSceneVS_output IlluminatedSceneVS( _IlluminatedSceneVS_input IN )
924{
925        _IlluminatedSceneVS_output OUT;
926    OUT.hPosition = mul( IN.Position, WorldViewProjection );
927   
928    // texel_size as uniform parameter
929        OUT.hPosition.x -= texel_size * OUT.hPosition.w;
930        OUT.hPosition.y += texel_size * OUT.hPosition.w;
931
932    if (iShowCubeMap > 0)
933    {
934                // if one of the cube maps is displayed on the walls,
935                // position is simply forwarded
936                OUT.Position = IN.Position;
937        }
938        else
939        {
940                // also consider camera orientation
941                OUT.Position = mul( IN.Position, WorldView );
942        }
943   
944    OUT.TexCoord = IN.TexCoord;
945    return OUT;
946}
947
948/// Displays the environment with a simple shading
949float4 IlluminatedScenePS( _IlluminatedSceneVS_output IN ) : COLOR0
950{
951    float3 color = objColor * tex2D(DecorationSampler, IN.TexCoord);
952   
953    if (iShowCubeMap > 0)
954    {
955                // if one of the cube maps should be displayed on the walls,
956                // display it
957            color = texCUBE(EnvironmentMapSampler, IN.Position) * intensity;
958    }
959    else if (brightness>0)
960    {
961                // create an exponential falloff for each face of the room
962                float3 L = float3(2*IN.TexCoord.x-1, 2*IN.TexCoord.y-1, -1);
963                L = normalize(L);
964                float3 N = float3(0,0,1);
965                color *= abs(pow(dot(L,N), 4)) * brightness;
966        }
967        else color *= 0.7;
968               
969        float dist = length( IN.Position );
970    return float4(color, dist);
971}
972
973
974
975
976//--------------------------------------------------------------------------------------
977// Techniques
978//--------------------------------------------------------------------------------------
979
980
981/// a helpful macro to define techniques with a common vertex program
982#define TechniqueUsingCommonVS(name);                                                           \
983        technique name                                                                                                  \
984        {                                                                                                                               \
985            pass p0                                                                                                             \
986            {                                                                                                                   \
987                    VertexShader = compile vs_3_0 EnvMapVS();                           \
988                    PixelShader  = compile ps_3_0 name##PS();                           \
989                }                                                                                                                       \
990        }
991       
992TechniqueUsingCommonVS( EnvMapDiffuseClassic );
993TechniqueUsingCommonVS( EnvMapDiffuseLocalized5Tex );
994
995//TechniqueUsingCommonVS( EnvMapDiffuseLocalized );
996TechniqueUsingCommonVS( EnvMapDiffuseLocalized2 );
997TechniqueUsingCommonVS( EnvMapDiffuseLocalized4 );
998TechniqueUsingCommonVS( EnvMapDiffuseLocalized8 );
999TechniqueUsingCommonVS( EnvMapDiffuseLocalized16 );
1000
1001TechniqueUsingCommonVS( EnvMapDiffuseLocalizedNew );
1002TechniqueUsingCommonVS( EnvMapDiffuseP2P );
1003TechniqueUsingCommonVS( EnvMapDiffuseAdapt );
1004
1005#define ReduceTextureTechnique(M);                                                                      \
1006        technique ReduceTexture##M                                                                              \
1007        {                                                                                                                               \
1008            pass p0                                                                                                             \
1009            {                                                                                                                   \
1010                    VertexShader = compile vs_3_0 ReduceTextureVS();            \
1011                    PixelShader  = compile ps_3_0 ReduceTexture##M##PS();       \
1012                }                                                                                                                       \
1013        }
1014
1015ReduceTextureTechnique( 2 );
1016ReduceTextureTechnique( 4 );
1017ReduceTextureTechnique( 8 );
1018ReduceTextureTechnique( 16 );
1019
1020#define ConvolutionTechnique(M);                                                                        \
1021        technique Convolution##M                                                                                \
1022        {                                                                                                                               \
1023            pass p0                                                                                                             \
1024            {                                                                                                                   \
1025                    VertexShader = compile vs_3_0 ConvolutionVS();                      \
1026                    PixelShader  = compile ps_3_0 Convolution##M##PS();         \
1027                }                                                                                                                       \
1028        }
1029
1030ConvolutionTechnique( 2 );
1031ConvolutionTechnique( 4 );
1032ConvolutionTechnique( 8 );
1033ConvolutionTechnique( 16 );
1034
1035/// a helpful macro to define techniques
1036/// where the name of EnvMapVS program is <TechniqueName>VS
1037/// and the name of PS program is <TechniqueName>PS
1038#define Technique(name);                                                                \
1039        technique name                                                                          \
1040        {                                                                                                       \
1041            pass p0                                                                                     \
1042            {                                                                                           \
1043                    VertexShader = compile vs_3_0 name##VS();   \
1044                    PixelShader  = compile ps_3_0 name##PS();   \
1045                }                                                                                               \
1046        }
1047
1048Technique( IlluminatedScene );
1049//Technique( Convolution );
1050//Technique( ReduceTexture );
Note: See TracBrowser for help on using the repository browser.