//----------------------------------------------------------------------------- // EnvironmentMapEffect.fx // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #include "Macros.fxh" DECLARE_TEXTURE(Texture, 0); DECLARE_CUBEMAP(EnvironmentMap, 1); BEGIN_CONSTANTS float3 EnvironmentMapSpecular _ps(c0) _cb(c0); float FresnelFactor _vs(c0) _cb(c0.w); float EnvironmentMapAmount _vs(c1) _cb(c2.w); float4 DiffuseColor _vs(c2) _cb(c1); float3 EmissiveColor _vs(c3) _cb(c2); float3 DirLight0Direction _vs(c4) _cb(c3); float3 DirLight0DiffuseColor _vs(c5) _cb(c4); float3 DirLight1Direction _vs(c6) _cb(c5); float3 DirLight1DiffuseColor _vs(c7) _cb(c6); float3 DirLight2Direction _vs(c8) _cb(c7); float3 DirLight2DiffuseColor _vs(c9) _cb(c8); float3 EyePosition _vs(c10) _cb(c9); float3 FogColor _ps(c1) _cb(c10); float4 FogVector _vs(c11) _cb(c11); float4x4 World _vs(c16) _cb(c12); float3x3 WorldInverseTranspose _vs(c19) _cb(c16); MATRIX_CONSTANTS float4x4 WorldViewProj _vs(c12) _cb(c0); END_CONSTANTS // We don't use these parameters, but Lighting.fxh won't compile without them. #define SpecularPower 0 #define SpecularColor float3(0, 0, 0) #define DirLight0SpecularColor float3(0, 0, 0) #define DirLight1SpecularColor float3(0, 0, 0) #define DirLight2SpecularColor float3(0, 0, 0) #include "Structures.fxh" #include "Common.fxh" #include "Lighting.fxh" float ComputeFresnelFactor(float3 eyeVector, float3 worldNormal) { float viewAngle = dot(eyeVector, worldNormal); return pow(max(1 - abs(viewAngle), 0), FresnelFactor) * EnvironmentMapAmount; } VSOutputTxEnvMap ComputeEnvMapVSOutput(VSInputNmTx vin, uniform bool useFresnel, uniform int numLights) { VSOutputTxEnvMap vout; float4 pos_ws = mul(vin.Position, World); float3 eyeVector = normalize(EyePosition - pos_ws.xyz); float3 worldNormal = normalize(mul(vin.Normal, WorldInverseTranspose)); ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights); vout.PositionPS = mul(vin.Position, WorldViewProj); vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a); if (useFresnel) vout.Specular.rgb = ComputeFresnelFactor(eyeVector, worldNormal); else vout.Specular.rgb = EnvironmentMapAmount; vout.Specular.a = ComputeFogFactor(vin.Position); vout.TexCoord = vin.TexCoord; vout.EnvCoord = reflect(-eyeVector, worldNormal); return vout; } // Vertex shader: basic. VSOutputTxEnvMap VSEnvMap(VSInputNmTx vin) { return ComputeEnvMapVSOutput(vin, false, 3); } // Vertex shader: fresnel. VSOutputTxEnvMap VSEnvMapFresnel(VSInputNmTx vin) { return ComputeEnvMapVSOutput(vin, true, 3); } // Vertex shader: one light. VSOutputTxEnvMap VSEnvMapOneLight(VSInputNmTx vin) { return ComputeEnvMapVSOutput(vin, false, 1); } // Vertex shader: one light, fresnel. VSOutputTxEnvMap VSEnvMapOneLightFresnel(VSInputNmTx vin) { return ComputeEnvMapVSOutput(vin, true, 1); } // Pixel shader: basic. float4 PSEnvMap(PSInputTxEnvMap pin) : SV_Target0 { float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a; color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb); ApplyFog(color, pin.Specular.w); return color; } // Pixel shader: no fog. float4 PSEnvMapNoFog(PSInputTxEnvMap pin) : SV_Target0 { float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a; color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb); return color; } // Pixel shader: specular. float4 PSEnvMapSpecular(PSInputTxEnvMap pin) : SV_Target0 { float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a; color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb); color.rgb += EnvironmentMapSpecular * envmap.a; ApplyFog(color, pin.Specular.w); return color; } // Pixel shader: specular, no fog. float4 PSEnvMapSpecularNoFog(PSInputTxEnvMap pin) : SV_Target0 { float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a; color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb); color.rgb += EnvironmentMapSpecular * envmap.a; return color; } VertexShader VSArray[4] = { compile vs_2_0 VSEnvMap(), compile vs_2_0 VSEnvMapFresnel(), compile vs_2_0 VSEnvMapOneLight(), compile vs_2_0 VSEnvMapOneLightFresnel(), }; int VSIndices[16] = { 0, // basic 0, // basic, no fog 1, // fresnel 1, // fresnel, no fog 0, // specular 0, // specular, no fog 1, // fresnel + specular 1, // fresnel + specular, no fog 2, // one light 2, // one light, no fog 3, // one light, fresnel 3, // one light, fresnel, no fog 2, // one light, specular 2, // one light, specular, no fog 3, // one light, fresnel + specular 3, // one light, fresnel + specular, no fog }; PixelShader PSArray[4] = { compile ps_2_0 PSEnvMap(), compile ps_2_0 PSEnvMapNoFog(), compile ps_2_0 PSEnvMapSpecular(), compile ps_2_0 PSEnvMapSpecularNoFog(), }; int PSIndices[16] = { 0, // basic 1, // basic, no fog 0, // fresnel 1, // fresnel, no fog 2, // specular 3, // specular, no fog 2, // fresnel + specular 3, // fresnel + specular, no fog 0, // one light 1, // one light, no fog 0, // one light, fresnel 1, // one light, fresnel, no fog 2, // one light, specular 3, // one light, specular, no fog 2, // one light, fresnel + specular 3, // one light, fresnel + specular, no fog }; int ShaderIndex = 0; Technique EnvironmentMapEffect { Pass { VertexShader = (VSArray[VSIndices[ShaderIndex]]); PixelShader = (PSArray[PSIndices[ShaderIndex]]); } }