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

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