//----------------------------------------------------------------------------- // dual_paraboloid_environment_map.fx // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- float4x4 mWVP : WorldViewProjection; float4x4 ModelWorld : World; float4x4 ParaboloidBasis : LightSpaceTransform; float4 CameraPos : ViewPosition; //----------------------------------------------------------------------------- texture FrontMap : ColorMap6; // Forward Hemisphere texture BackMap : ColorMap7; // Backward Hemisphere //----------------------------------------------------------------------------- sampler FrontSampler = sampler_state { Texture = (FrontMap); MinFilter = LINEAR; // linear filtering MagFilter = LINEAR; // linear filtering AddressU = Border; // border sampling in U AddressV = Border; // border sampling in V BorderColor = float4(0,0,0,0); // outside of border should be black }; sampler BackSampler = sampler_state { Texture = (BackMap); MinFilter = LINEAR; // linear filtering MagFilter = LINEAR; // linear filtering AddressU = Border; // border sampling in U AddressV = Border; // border sampling in V BorderColor = float4(0,0,0,0); // outside of border should be black }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- struct vertex { float3 position : POSITION; float3 normal : NORMAL; }; //----------------------------------------------------------------------------- struct fragment { float4 position : POSITION; float3 normal : TEXCOORD0; float3 eye : TEXCOORD1; }; //----------------------------------------------------------------------------- struct pixel { float4 color : COLOR; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Vertex Shader //----------------------------------------------------------------------------- fragment VS( vertex IN ) { fragment OUT; float4 WorldPos = mul( float4(IN.position, 1), ModelWorld ); // find world space position float3 N = normalize(mul(IN.normal, (float3x3)ModelWorld)); // find world space normal float3 E = normalize(WorldPos.xyz - CameraPos.xyz); // find world space eye vector OUT.position = mul( float4(IN.position, 1), mWVP ); // output clip space position OUT.normal = N; // output world space normal vector OUT.eye = E; // output world space eye vector return OUT; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Pixel Shader //----------------------------------------------------------------------------- pixel PS( fragment IN ) { pixel OUT; float3 N = normalize( IN.normal ); // normalize input per-vertex normal vector float3 E = normalize( IN.eye ); // normalize input per-vertex eye vector float3 R = reflect( E, N ); // calculate the reflection vector R = mul( R, (float3x3)ParaboloidBasis ); // transform reflection vector to the maps basis // calculate the forward paraboloid map texture coordinates float2 front; front.x = (R.x / (2*(1 + R.z))) + 0.5; front.y = 1-((R.y / (2*(1 + R.z))) + 0.5); // calculate the backward paraboloid map texture coordinates float2 back; back.x = (R.x / (2*(1 - R.z))) + 0.5; back.y = 1-((R.y / (2*(1 - R.z))) + 0.5); float4 forward = tex2D( FrontSampler, front ); // sample the front paraboloid map float4 backward = tex2D( BackSampler, back ); // sample the back paraboloid map OUT.color = max(forward, backward); // output the max of the two maps return OUT; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- technique DualParaboloidEnvironmentMapping { pass P0 { VertexShader = compile vs_1_1 VS(); PixelShader = compile ps_2_0 PS(); } } //-----------------------------------------------------------------------------