//-------------------------------------------------------------------------------------- // File: EnvMap.fx // // The effect file for the OptimizedMesh sample. // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- /// size of the cube map taken from the reference point of the object #define CUBEMAP_SIZE 128 /// size of the cube map for diffuse/glossy reflections int LR_CUBEMAP_SIZE; #define PI 3.14159f //-------------------------------------------------------------------------------------- // Global variables //-------------------------------------------------------------------------------------- float4x4 World; ///< World matrix for the current object float4x4 WorldIT; ///< World matrix IT (inverse transposed) to transform surface normals of the current object float4x4 WorldView; ///< World * View matrix //float4x4 WorldViewIT; ///< World * View IT (inverse transposed) to transform surface normals of the current object float4x4 WorldViewProjection; ///< World * View * Projection matrix float texel_size; ///< upload this constant every time the viewport changes float4 eyePos; ///< current eye (camera) position float4 reference_pos; ///< Reference point for the last cube map generation. int nFace; ///< int iShowCubeMap; ///< float4 objColor; float intensity, shininess, brightness; //-------------------------------------------------------------------------------------- // Textures & texture samplers //-------------------------------------------------------------------------------------- texture EnvironmentMap, SmallEnvironmentMap, PreconvolvedEnvironmentMap, Decoration; sampler EnvironmentMapSampler = sampler_state { /*MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR;*/ Texture = ; AddressU = WRAP; AddressV = WRAP; }; sampler PreconvolvedEnvironmentMapSampler = sampler_state { MinFilter = LINEAR; MagFilter = LINEAR; //MipFilter = LINEAR; Texture = ; AddressU = WRAP; AddressV = WRAP; }; sampler SmallEnvironmentMapSampler = sampler_state { // MinFilter = Point; // MagFilter = Point; MinFilter = LINEAR; MagFilter = LINEAR; //MipFilter = Point; Texture = ; AddressU = WRAP; AddressV = WRAP; }; sampler DecorationSampler = sampler_state { Texture = ; MinFilter = LINEAR; MagFilter = LINEAR; //MipFilter = LINEAR; AddressU = CLAMP; //WRAP; AddressV = CLAMP; //WRAP; }; //-------------------------------------------------------------------------------------- // Shader programs //-------------------------------------------------------------------------------------- void ReduceTextureVS( float4 position : POSITION, float4 color0 : COLOR0, float3 Normal : NORMAL, float2 Tex : TEXCOORD0, out float4 hposition : POSITION, out float4 color : COLOR0, out float2 oTex : TEXCOORD0, out float4 pos : TEXCOORD1 ) { pos = position; hposition = pos; color = color0; oTex = Tex; } /** \brief Downsamples a cube map face. */ #define _ReduceTexturePS( M ) \ float4 ReduceTexture##M##PS( float2 Tex : TEXCOORD0, \ float4 pos : TEXCOORD1, \ float4 color0 : COLOR0 ) : COLOR0 \ { \ /* offset to texel center */ \ pos.xy += float2(1/(float)CUBEMAP_SIZE, -1/(float)CUBEMAP_SIZE); \ /* transform position into texture coord */ \ float2 tpos = pos.xy/2+0.5; /* rescale from -1..1 into range 0..1 */ \ tpos.y = 1-tpos.y; \ \ float2 t; \ float4 color = 0; \ const int RATE = CUBEMAP_SIZE / M; \ \ for (int i = 0; i < RATE; i++) \ for (int j = 0; j < RATE; j++) \ { \ t.x = tpos.x + i/(float)CUBEMAP_SIZE; \ t.y = tpos.y + j/(float)CUBEMAP_SIZE; \ color += tex2D(DecorationSampler, t) / (RATE * RATE); \ } \ return color; \ } // end of macro definition _ReduceTexturePS( 2 ); _ReduceTexturePS( 4 ); _ReduceTexturePS( 8 ); _ReduceTexturePS( 16 ); //-------------------------------------------------------------------------------------- // Method #0: CLASSIC (pre-convolved) //-------------------------------------------------------------------------------------- /// \brief Returns the precalculated contribution of a texel with regard to the specified query direction. /// /// \param q query direction (i.e. surface normal in diffuse case, ideal reflection direction in specular case). /// \param L vector pointing to the texel center float4 GetContr(float3 q, float3 L) // Lin * a * ( dw ) // -- actually, dw is calculated by the caller -- { //float shininess = 1; float fcos = max(dot(L, q), 0); // diffuse if (shininess <= 0) return 0.2 * fcos * texCUBE( SmallEnvironmentMapSampler, L); else { // some ad-hoc formula to avoid darkening float brightness = (pow(shininess,0.8)*0.2); return brightness * pow(fcos, shininess) * texCUBE( SmallEnvironmentMapSampler, L); } } /// \brief Input for vertex shader ConvolutionVS(). struct _ConvolutionVS_input { float4 Position : POSITION; }; /// \brief Input for pixel shader ::_ConvolutionPS(). struct _ConvolutionVS_output { float4 hPosition : POSITION; float3 Position : TEXCOORD0; }; _ConvolutionVS_output ConvolutionVS(_ConvolutionVS_input IN) { _ConvolutionVS_output OUT; OUT.hPosition = IN.Position; float2 pos = IN.Position.xy; // -1..1 pos.x += 0.5f / LR_CUBEMAP_SIZE; pos.y -= 0.5f / LR_CUBEMAP_SIZE; if (nFace == 0) OUT.Position = float3(1, pos.y, -pos.x); if (nFace == 1) OUT.Position = float3(-1, pos.y, pos.x); if (nFace == 2) OUT.Position = float3(pos.x, 1, -pos.y); if (nFace == 3) OUT.Position = float3(pos.x,-1, pos.y); if (nFace == 4) OUT.Position = float3(pos.xy, 1); if (nFace == 5) OUT.Position = float3(-pos.x, pos.y,-1); return OUT; } /** \brief Convolves the values of a cube map of resoultion MxM. Calculates the diffuse/specular irradiance map of resolution #LR_CUBEMAP_SIZE by summing up the contributions of all cube map texels with regard to the current query direction. */ #define _ConvolutionPS( M ) \ float4 Convolution##M##PS( _ConvolutionVS_output IN ) : COLOR \ { \ /* input position = query direction for the result */ \ float3 q = normalize( IN.Position ); \ float4 color = 0; \ \ for (int i = 0; i < M; i++) \ for (int j = 0; j < M; j++) \ { \ float u = (i+0.5) / (float)M; \ float v = (j+0.5) / (float)M; \ float3 pos = float3( 2*u-1, 1-2*v, 1 ); \ \ float r = length(pos); \ pos /= r; \ \ float4 dcolor = 0; \ float3 L; \ L = float3(pos.z, pos.y, -pos.x); dcolor += GetContr( q, L ); \ L = float3(-pos.z, pos.y, pos.x); dcolor += GetContr( q, L ); \ L = float3(pos.x, pos.z, -pos.y); dcolor += GetContr( q, L ); \ L = float3(pos.x, -pos.z, pos.y); dcolor += GetContr( q, L ); \ L = float3(pos.x, pos.y, pos.z); dcolor += GetContr( q, L ); \ L = float3(-pos.x, pos.y, -pos.z); dcolor += GetContr( q, L ); \ \ float dw = 4 / (r*r*r); \ color += dcolor * dw; \ } \ \ return color / (M * M); \ } /* end of macro definition */ _ConvolutionPS( 2 ); _ConvolutionPS( 4 ); _ConvolutionPS( 8 ); _ConvolutionPS( 16 ); /// \brief Input for vertex shader EnvMapVS(). struct _EnvMapVS_input { float4 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; }; /// \brief Input for pixel shaders EnvMapDiffuseClassicPS(), ::_EnvMapDiffuseLocalizedPS(), EnvMapDiffuseLocalized5TexPS(). struct _EnvMapVS_output { float4 hPosition : POSITION; float2 TexCoord : TEXCOORD0; float3 Normal : TEXCOORD1; float3 View : TEXCOORD2; float3 Position : TEXCOORD3; }; _EnvMapVS_output EnvMapVS( _EnvMapVS_input IN ) { _EnvMapVS_output OUT; OUT.Position = mul( IN.Position, World ).xyz; // scale & offset OUT.View = normalize( OUT.Position - eyePos ); //OUT.Normal = IN.Normal; OUT.Normal = mul( IN.Normal, WorldIT ).xyz; // allow distortion/rotation OUT.TexCoord = IN.TexCoord; OUT.hPosition = mul( IN.Position, WorldViewProjection ); return OUT; } /// \brief Determines diffuse or specular illumination with a single lookup into #PreconvolvedEnvironmentMap. /// PreconvolvedEnvironmentMap is bound to EnvMap::pCubeTexturePreConvolved (cube map of resolution #LR_CUBEMAP_SIZE). float4 EnvMapDiffuseClassicPS( _EnvMapVS_output IN ) : COLOR { IN.View = normalize( IN.View ); IN.Normal = normalize( IN.Normal ); float3 R = reflect(IN.View, IN.Normal); if (shininess <= 0) // diffuse return intensity * texCUBE(PreconvolvedEnvironmentMapSampler, IN.Normal) *2; else // specular return intensity * texCUBE(PreconvolvedEnvironmentMapSampler, R) *2; } //-------------------------------------------------------------------------------------- // Method #1-#2: OUR METHOD //-------------------------------------------------------------------------------------- /// \brief Calculates the contribution of a single texel of #SmallEnvironmentMap to the illumination of the shaded point. /// To compute reflectivity, precalculated integral values are used. /// /// \param L vector pointing to the center of the texel under examination. We assume that the largest coordinate component /// of L is equal to one, i.e. L points to the face of a cube of edge length of 2. /// \param pos is the position of the shaded point /// \param N is the surface normal at the shaded point /// \param V is the viewing direction at the shaded point float4 GetContr(int M, float3 L, float3 pos, float3 N, float3 V) // Phong-Blinn // L is strictly non-normalized { float l = length(L); L = normalize(L); //Lin float4 Lin = texCUBE(SmallEnvironmentMapSampler, L); //dw float dw = 4 / (M*M*l*l*l + 4/2/3.1416f); float dws = dw; //r float doy = texCUBE(SmallEnvironmentMapSampler, L).a; float dxy = length(pos - L * doy); //dws //dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/3.1416f) + doy*doy*dw/3.1416f); // localization: //dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/2/3.1416f) + doy*doy*dw/2/3.1416f); // localization: float den = 1 + doy*doy / (dxy*dxy) * ( (2*3.1416f)*(2*3.1416f) / ((2*3.1416f-dw)*(2*3.1416f-dw)) - 1 ); dws = 2*3.1416f * (1 - 1/sqrt(den)); float3 LL = L * doy - pos; // L should start from the object (and not from the reference point) !!! LL = normalize(LL); float3 H = normalize(L + V); // halfway vector float3 R = reflect(-V, N); // reflection vector // from texture float4 color = 0; float cos_value; if (shininess <= 0) cos_value = dot(N,L); // diffuse else cos_value = dot(R,L); // specular float2 tex; tex.x = (cos_value + 1)/2; tex.y = dws/2/PI; // lookup into precalculated reflectivity values cos_value = tex2D(DecorationSampler, tex).g * 3; color = Lin * 0.5 * cos_value; return color; } // Method #1 /// \brief Calculates diffuse or specular contributions of all texels in #SmallEnvironmentMap to the current point. /// For each texel of #SmallEnvironmentMap, function GetContr(int,float3,float3,float3,float3) is called. #define _EnvMapDiffuseLocalizedPS( M ) \ float4 EnvMapDiffuseLocalized##M##PS( _EnvMapVS_output IN ) : COLOR \ { \ IN.View = -normalize( IN.View ); \ IN.Normal = normalize( IN.Normal ); \ IN.Position -= reference_pos.xyz; /* relative to the ref.point */ \ \ float3 R = -reflect( IN.View, IN.Normal ); /* reflection direction */ \ \ float4 I = 0; \ \ for (int x = 0; x < M; x++) /* foreach texel */ \ for (int y = 0; y < M; y++) \ { \ /* compute intensity for 6 texels with equal solid angles */ \ \ float2 tpos = float2( (x+0.5f)/M, (y+0.5f)/M ); /* texture coord (0..1) */ \ \ float2 p = float2(tpos.x, 1-tpos.y); \ p.xy = 2*p.xy - 1; /* position (-1..1) */ \ \ I += GetContr( M, float3(p.x, p.y, 1), IN.Position, IN.Normal, IN.View ); \ I += GetContr( M, float3(p.x, p.y, -1), IN.Position, IN.Normal, IN.View ); \ I += GetContr( M, float3(p.x, 1, p.y), IN.Position, IN.Normal, IN.View ); \ I += GetContr( M, float3(p.x, -1, p.y), IN.Position, IN.Normal, IN.View ); \ I += GetContr( M, float3(1, p.x, p.y), IN.Position, IN.Normal, IN.View ); \ I += GetContr( M, float3(-1, p.x, p.y), IN.Position, IN.Normal, IN.View ); \ } \ \ return intensity * I; \ } // end of macro definition _EnvMapDiffuseLocalizedPS( 2 ); _EnvMapDiffuseLocalizedPS( 4 ); _EnvMapDiffuseLocalizedPS( 8 ); _EnvMapDiffuseLocalizedPS( 16 ); // Method #2 /// \brief Calculates diffuse or specular contributions of the 5 "most important" texels of #SmallEnvironmentMap to the current point. /// For these texels, function GetContr(int,float3,float3,float3,float3) is called. float4 EnvMapDiffuseLocalized5TexPS( _EnvMapVS_output IN ) : COLOR { IN.View = -normalize( IN.View ); IN.Normal = normalize( IN.Normal ); // translate reference point to the origin IN.Position -= reference_pos.xyz; float3 R = -reflect( IN.View, IN.Normal ); // reflection direction float4 I = 0; float3 q; if ( shininess <= 0 ) q = IN.Normal; // diffuse else q = R; float rr = max( max(abs(q.x), abs(q.y)), abs(q.z) ); // select the largest component q /= rr; // scale the largest component to value +/-1 float3 offset1 = float3(1,0,0); // default: largest: z float3 offset2 = float3(0,1,0); // select: x,y if (abs(q.x) > abs(q.y) && abs(q.x) > abs(q.z)) { // largest: x offset1 = float3(0,0,1); // select y,z } if (abs(q.y) > abs(q.x) && abs(q.y) > abs(q.z)) { // largest: y offset2 = float3(0,0,1); // select x,z } I += GetContr( LR_CUBEMAP_SIZE, q, IN.Position, IN.Normal, IN.View ); I += GetContr( LR_CUBEMAP_SIZE, q + offset1*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View ); I += GetContr( LR_CUBEMAP_SIZE, q - offset1*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View ); I += GetContr( LR_CUBEMAP_SIZE, q + offset2*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View ); I += GetContr( LR_CUBEMAP_SIZE, q - offset2*(2.0/LR_CUBEMAP_SIZE), IN.Position, IN.Normal, IN.View ); // since only 5 texels are considered, the result gets darker. // LR_CUBEMAP_SIZE is present to compensate this. return intensity * I * LR_CUBEMAP_SIZE / 2; } // Method #3 /// \brief Calculates diffuse or specular contributions of the 5 "most important" texels of #SmallEnvironmentMap to the current point. /// For these texels, function GetContr(int,float3,float3,float3,float3) is called. float4 GetContibution(float3 L1, float3 L2, float3 L3, float3 L4, float3 pos, float3 N, float d) { L1 = d * normalize(L1); L2 = d * normalize(L2); L3 = d * normalize(L3); L4 = d * normalize(L4); float3 r1 = normalize(L1 - pos); float3 r2 = normalize(L2 - pos); float3 r3 = normalize(L3 - pos); float3 r4 = normalize(L4 - pos); float kd = 0.3; // 0.3 /* float3 R; R = cross(r1, r2); float tri1 = asin(length(R)) * dot(R, N); R = cross(r2, r3); float tri2 = asin(length(R)) * dot(R, N); R = cross(r3, r4); float tri3 = asin(length(R)) * dot(R, N); R = cross(r4, r1); float tri4 = asin(length(R)) * dot(R, N); */ float tri1 = acos(dot(r1, r2)) * dot(cross(r1, r2), N); float tri2 = acos(dot(r2, r3)) * dot(cross(r2, r3), N); float tri3 = acos(dot(r3, r4)) * dot(cross(r3, r4), N); float tri4 = acos(dot(r4, r1)) * dot(cross(r4, r1), N); return max(tri1 + tri2 + tri3 + tri4, 0); //return tri1 + tri2 + tri3 + tri4; } float4 EnvMapDiffuseLocalizedNewPS( _EnvMapVS_output IN ) : COLOR { float M = 4.0; IN.View = -normalize( IN.View ); IN.Normal = normalize( IN.Normal ); IN.Position -= reference_pos.xyz; float3 pos = IN.Position.xyz; //return reference_pos; //return texCUBE(SmallEnvironmentMapSampler, pos); float3 N =IN.Normal; float3 R = -reflect( IN.View, IN.Normal ); float4 I = 0; float3 L1, L2, L3, L4, L; float4 Le; float d; float width = 1.0 / M; for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, p.y - width, 1); L2 = float3(p.x + width, p.y - width, 1); L3 = float3(p.x + width, p.y + width, 1); L4 = float3(p.x - width, p.y + width, 1); L = float3(p.x, p.y, 1); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, p.y - width, -1); L3 = float3(p.x + width, p.y - width, -1); L2 = float3(p.x + width, p.y + width, -1); L1 = float3(p.x - width, p.y + width, -1); L = float3(p.x, p.y, -1); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(p.x - width, 1, p.y - width); L3 = float3(p.x + width, 1, p.y - width); L2 = float3(p.x + width, 1, p.y + width); L1 = float3(p.x - width, 1, p.y + width); L = float3(p.x, 1, p.y); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(p.x - width, -1, p.y - width); L2 = float3(p.x + width, -1, p.y - width); L3 = float3(p.x + width, -1, p.y + width); L4 = float3(p.x - width, -1, p.y + width); L = float3(p.x, -1, p.y); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L1 = float3(1, p.x - width, p.y - width); L2 = float3(1, p.x + width, p.y - width); L3 = float3(1, p.x + width, p.y + width); L4 = float3(1, p.x - width, p.y + width); L = float3(1, p.x, p.y); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } for (int x = 0; x < M; x++) for (int y = 0; y < M; y++) { float2 p, tpos; tpos.x = (x + 0.5) * width; // 0..1 tpos.y = (y + 0.5) * width; // 0..1 p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 L4 = float3(-1, p.x - width, p.y - width); L3 = float3(-1, p.x + width, p.y - width); L2 = float3(-1, p.x + width, p.y + width); L1 = float3(-1, p.x - width, p.y + width); L = float3(-1, p.x, p.y); Le = float4(texCUBE(SmallEnvironmentMapSampler, L).rgb, 1); d = texCUBE(SmallEnvironmentMapSampler, L).a; I += 0.5 * Le * GetContibution( L1, L2, L3, L4, pos, N, d); //I += Le / 16.0; } return intensity * I; } //-------------------------------------------------------------------------------------- // Shading the environment //-------------------------------------------------------------------------------------- /// \brief Input for vertex shader IlluminatedSceneVS(). struct _IlluminatedSceneVS_input { float4 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; }; /// \brief Input for pixel shader IlluminatedScenePS(). struct _IlluminatedSceneVS_output { float4 hPosition : POSITION; float2 TexCoord : TEXCOORD0; float3 Position : TEXCOORD1; }; _IlluminatedSceneVS_output IlluminatedSceneVS( _IlluminatedSceneVS_input IN ) { _IlluminatedSceneVS_output OUT; OUT.hPosition = mul( IN.Position, WorldViewProjection ); // texel_size as uniform parameter OUT.hPosition.x -= texel_size * OUT.hPosition.w; OUT.hPosition.y += texel_size * OUT.hPosition.w; if (iShowCubeMap > 0) { // if one of the cube maps is displayed on the walls, // position is simply forwarded OUT.Position = IN.Position; } else { // also consider camera orientation OUT.Position = mul( IN.Position, WorldView ); } OUT.TexCoord = IN.TexCoord; return OUT; } /// Displays the environment with a simple shading float4 IlluminatedScenePS( _IlluminatedSceneVS_output IN ) : COLOR0 { float3 color = objColor * tex2D(DecorationSampler, IN.TexCoord); if (iShowCubeMap > 0) { // if one of the cube maps should be displayed on the walls, // display it color = texCUBE(EnvironmentMapSampler, IN.Position) * intensity; } else if (brightness>0) { // create an exponential falloff for each face of the room float3 L = float3(2*IN.TexCoord.x-1, 2*IN.TexCoord.y-1, -1); L = normalize(L); float3 N = float3(0,0,1); color *= abs(pow(dot(L,N), 4)) * brightness; } else color *= 0.7; float dist = length( IN.Position ); return float4(color, dist); } //-------------------------------------------------------------------------------------- // Techniques //-------------------------------------------------------------------------------------- /// a helpful macro to define techniques with a common vertex program #define TechniqueUsingCommonVS(name); \ technique name \ { \ pass p0 \ { \ VertexShader = compile vs_3_0 EnvMapVS(); \ PixelShader = compile ps_3_0 name##PS(); \ } \ } TechniqueUsingCommonVS( EnvMapDiffuseClassic ); TechniqueUsingCommonVS( EnvMapDiffuseLocalized5Tex ); //TechniqueUsingCommonVS( EnvMapDiffuseLocalized ); TechniqueUsingCommonVS( EnvMapDiffuseLocalized2 ); TechniqueUsingCommonVS( EnvMapDiffuseLocalized4 ); TechniqueUsingCommonVS( EnvMapDiffuseLocalized8 ); TechniqueUsingCommonVS( EnvMapDiffuseLocalized16 ); TechniqueUsingCommonVS( EnvMapDiffuseLocalizedNew ); //TechniqueUsingCommonVS( EnvMapDiffuseLocalizedNew4 ); //TechniqueUsingCommonVS( EnvMapDiffuseLocalizedNew8 ); //TechniqueUsingCommonVS( EnvMapDiffuseLocalizedNew16 ); #define ReduceTextureTechnique(M); \ technique ReduceTexture##M \ { \ pass p0 \ { \ VertexShader = compile vs_3_0 ReduceTextureVS(); \ PixelShader = compile ps_3_0 ReduceTexture##M##PS(); \ } \ } ReduceTextureTechnique( 2 ); ReduceTextureTechnique( 4 ); ReduceTextureTechnique( 8 ); ReduceTextureTechnique( 16 ); #define ConvolutionTechnique(M); \ technique Convolution##M \ { \ pass p0 \ { \ VertexShader = compile vs_3_0 ConvolutionVS(); \ PixelShader = compile ps_3_0 Convolution##M##PS(); \ } \ } ConvolutionTechnique( 2 ); ConvolutionTechnique( 4 ); ConvolutionTechnique( 8 ); ConvolutionTechnique( 16 ); /// a helpful macro to define techniques /// where the name of EnvMapVS program is VS /// and the name of PS program is PS #define Technique(name); \ technique name \ { \ pass p0 \ { \ VertexShader = compile vs_3_0 name##VS(); \ PixelShader = compile ps_3_0 name##PS(); \ } \ } Technique( IlluminatedScene ); //Technique( Convolution ); //Technique( ReduceTexture );