/* * StaticMesh.fx * Authors: August Zinsser * * Copyright August Zinsser 2007 * This program is distributed under the terms of the GNU General Public License * * Renders non-animated 3D models in various ways */ // --------------------------------------------------------------------------- // Parameters // --------------------------------------------------------------------------- float4x4 xWorldMat; float4x4 xViewProjMat; float3 xLightDir; float4 xLightColor; float xLightAmbient; float xLightPower; float4 xAmbientColor; float4 xDiffuseColor; Texture xDiffuseMap; Texture xNormalMap; Texture xDiffuseMap1; Texture xDiffuseMap2; Texture xDiffuseMap3; sampler TextureSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR; AddressU = MIRROR; AddressV = MIRROR; }; sampler Texture1Sampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR; AddressU = MIRROR; AddressV = MIRROR; }; sampler Texture2Sampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR; AddressU = MIRROR; AddressV = MIRROR; }; sampler Texture3Sampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR; AddressU = MIRROR; AddressV = MIRROR; }; // --------------------------------------------------------------------------- // Structs // --------------------------------------------------------------------------- struct sPUNT { float4 Position : POSITION0; float2 UV : TEXCOORD0; float3 Normal : NORMAL; float3 Tangent : TANGENT; }; struct sPUN { float4 Position : POSITION0; float2 UV : TEXCOORD0; float3 Normal : TEXCOORD1; }; struct sPCUNWD { float4 Position : POSITION0; float4 Color : COLOR0; float3 Normal : TEXCOORD0; float4 TextureCoords : TEXCOORD1; float4 TextureWeights : TEXCOORD3; float Depth : TEXCOORD4; }; // --------------------------------------------------------------------------- // Helper Functions // --------------------------------------------------------------------------- // Generates the matrix to transform from world space to tangent space float3x3 ComputeWorldToTangentMatrix(float3 tangent, float3 normal, float4x4 world) { float3x3 world2TanMat; float3 biTan = cross(normal, tangent); // more commonly called the "binormal" // Please not the reversed order we use the world matrix here. // The reason for this is the rebuild skin matrix, which is transposed! world2TanMat[2] = normalize(mul((float3x3)world, (float3)tangent)); world2TanMat[1] = normalize(mul((float3x3)world, (float3)biTan)); world2TanMat[0] = normalize(mul((float3x3)world, (float3)normal)); //world2TanMat[2] = normalize(mul((float3)tangent, (float3x3)world)); //world2TanMat[1] = normalize(mul((float3)biTan, (float3x3)world)); //world2TanMat[0] = normalize(mul((float3)normal, (float3x3)world)); return world2TanMat; } // --------------------------------------------------------------------------- // Vertex Shaders // --------------------------------------------------------------------------- sPUN BlankVS(sPUNT In) { sPUN Out; float4x4 preViewProjection = xViewProjMat; float4x4 preWorldViewProjection = mul (xWorldMat, preViewProjection); Out.Position = mul(In.Position, preWorldViewProjection); Out.Normal = normalize(mul(In.Normal, xWorldMat)); Out.Normal = In.Normal; // Pass the rest through Out.UV = In.UV; /* // Transform position from object space into clip space Out.Position = mul(In.Position, xWorldMat); Out.Position = mul(Out.Position, xViewProjMat); // Pass through the rest Out.Normal = In.Normal; Out.UV = In.UV; */ return Out; } sPCUNWD MultiTexturedVS( float4 inPos : POSITION, float3 inNormal: NORMAL, float4 inTexCoords: TEXCOORD0, float4 inTexWeights: TEXCOORD1) { sPCUNWD Out = (sPCUNWD)0; float4x4 preViewProjection = xViewProjMat; float4x4 preWorldViewProjection = mul (xWorldMat, preViewProjection); Out.Position = mul(inPos, preWorldViewProjection); Out.Normal = normalize(mul(inNormal, xWorldMat)); Out.TextureCoords = inTexCoords; Out.TextureWeights = inTexWeights; Out.Depth = Out.Position.z; return Out; } // --------------------------------------------------------------------------- // Pixel Shaders // --------------------------------------------------------------------------- float4 BlankPS(sPUN In) : COLOR0 { float intensity = dot(In.Normal, xLightDir); float4 Out = float4(intensity, intensity, intensity, 1.0f); return Out; } float4 TexturedPS(sPUN In) : COLOR0 { float4 Out = (float4)0; float intensity = saturate(saturate(dot(In.Normal, xLightDir)* xLightPower) + xLightAmbient); // Diffuse component float4 diffuseColor = float4(0,0,0,1); diffuseColor.rgb = xDiffuseColor.rgb * xDiffuseColor.a; diffuseColor.rgb += tex2D(TextureSampler, In.UV); // Material's ambient color + global color + diffuseColor Out.rgb = saturate((xAmbientColor.rgb * xAmbientColor.a) + (xLightAmbient * xLightColor) + (diffuseColor * intensity)); Out.a = 1.0f; //Out.r = 1.0f * In.Normal.x; //Out.g = 1.0f * In.Normal.y; //Out.b = 1.0f * In.Normal.z; return Out; } float4 MultiTexturedPS(sPCUNWD In) : COLOR0 { float4 Out = (float4)0; float blendDistance = 30; float blendWidth = 50; float blendFactor = clamp((In.Depth-blendDistance)/blendWidth, 0, 1); float intensity = saturate(saturate(dot(In.Normal, xLightDir)* xLightPower) + xLightAmbient); // Diffuse is a mix of far and near blended texture samples and the material's diffuse color float4 farColor; farColor = tex2D(TextureSampler, In.TextureCoords)*In.TextureWeights.x; farColor += tex2D(Texture1Sampler, In.TextureCoords)*In.TextureWeights.y; farColor += tex2D(Texture2Sampler, In.TextureCoords)*In.TextureWeights.z; farColor += tex2D(Texture3Sampler, In.TextureCoords)*In.TextureWeights.w; float4 nearColor; float2 nearTextureCoords = In.TextureCoords*3; nearColor = tex2D(TextureSampler, nearTextureCoords)*In.TextureWeights.x; nearColor += tex2D(Texture1Sampler, nearTextureCoords)*In.TextureWeights.y; nearColor += tex2D(Texture2Sampler, nearTextureCoords)*In.TextureWeights.z; nearColor += tex2D(Texture3Sampler, nearTextureCoords)*In.TextureWeights.w; float4 diffuseColor = xDiffuseColor*xDiffuseColor.a + farColor*blendFactor + nearColor*(1-blendFactor); Out.rgb = saturate((xAmbientColor.rgb * xAmbientColor.a) + (xLightAmbient * xLightColor) + (diffuseColor * intensity)); Out.a = 1.0f; return Out; } // --------------------------------------------------------------------------- // Techniques // --------------------------------------------------------------------------- technique Blank { pass P0 { VertexShader = compile vs_1_1 BlankVS(); PixelShader = compile ps_1_1 BlankPS(); } } technique TexturedLambert { pass P0 { VertexShader = compile vs_1_1 BlankVS(); PixelShader = compile ps_1_1 TexturedPS(); } } technique MultiTexturedLambert { pass P0 { VertexShader = compile vs_2_0 MultiTexturedVS(); PixelShader = compile ps_2_0 MultiTexturedPS(); } }