/****************************************************************************** simple normal map shader by Ben Cloward ben@bencloward.com http://www.bencloward.com This shader uses a normal map to give the illusion that the model surface contains more detail than is really there. It's based on several shaders written by Kevin Bjorke of Nvidia and included with the Cg plugin for 3DS Max. I created it for use with the tutorial I wrote on creating normal maps: http://www.monitorstudios.com/bcloward/tutorials_normal_maps1.html ******************************************************************************/ /************* TWEAKABLES **************/ float4x4 world : World; float4x4 WorldIMatrix : WorldI; float4x4 wvp : WorldViewProjection; float4 lightPos : Position < string Object = "PointLight"; string Space = "World"; > = {100.0f, 100.0f, 100.0f, 0.0f}; float4 lightColor : Diffuse < string Object = "PointLight"; > = { 0.8f, 0.8f, 0.8f, 0.0f }; float4 ambiColor : Ambient = {0.1f, 0.1f, 0.1f, 1.0f}; texture colorTexture : DiffuseMap < string File = "default_color.dds"; string TextureType = "2D"; >; texture normalMap : NormalMap < string File = "default_bump_normal.dds"; string TextureType = "2D"; >; sampler2D cmap = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; sampler2D normalSampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; /*************/ /************* STRUCTS **************/ // vertex input struct VertexIn { float4 Position : POSITION; //in object space float4 UV : TEXCOORD0; //in object space float4 Normal : NORMAL; //in object space float3 T : TEXCOORD1; //in object space float3 B : TEXCOORD2; //in object space }; //vertex output struct VertexOut { float4 HPosition : POSITION; float4 texCoord0 : TEXCOORD0; float4 texCoord1 : TEXCOORD1; float3 LightVector : TEXCOORD2; }; //pixel output struct PixelOut { float4 col : COLOR; }; /*************/ //vertex shader************************************* VertexOut DiffuseBumpVS(VertexIn IN, uniform float4x4 WorldViewProj, uniform float4x4 WorldIMatrix, uniform float4x4 World, uniform float4 LightPos) { //create the vertex out struct VertexOut OUT; OUT.texCoord0 = IN.UV; //pass coords for diffuse map OUT.texCoord1 = IN.UV; //pass coords for normal map // transform position to projection space OUT.HPosition = mul(WorldViewProj, IN.Position); // compute the 3x3 tranform from tangent space to object space float3x3 objToTangentSpace; objToTangentSpace[0] = IN.T; objToTangentSpace[1] = -IN.B; objToTangentSpace[2] = IN.Normal; //put the vert position in world space float4 worldSpacePos = mul(World, IN.Position); //cast a ray to the light float4 normLightVec = normalize(LightPos - worldSpacePos); //transform the light vector to object space float4 objnormLightVec = mul(WorldIMatrix, normLightVec); // transform light vector from object space to tangent space and pass it as a color OUT.LightVector.xyz = 0.5 * mul(objToTangentSpace, objnormLightVec.xyz) + 0.5.xxx; return OUT; } //pixel shader************************************* PixelOut myps(VertexOut IN, uniform sampler2D colorMap, uniform sampler2D NormalMap, uniform float4 LightColor, uniform float4 AmbientColor) { PixelOut OUT; //get the color from the diffuse texture float4 texColor = tex2D(colorMap, IN.texCoord0); //get the color (normal) from the normal map float4 bumpNormal = tex2D(NormalMap, IN.texCoord1) * 2 - 1; //expand iterated light vector to [-1,1] float3 lightVector = IN.LightVector * 2 - 1; //compute final color (diffuse + ambient) float4 bump = saturate(dot(bumpNormal.xyz,lightVector.xyz)); OUT.col = texColor * bump * LightColor + (AmbientColor * texColor); return OUT; } //MAIN************************************* technique diffuseBump { pass p0 { ZEnable = true; ZWriteEnable = true; CullMode = None; AlphaBlendEnable = false; VertexShader = compile vs_1_1 DiffuseBumpVS(wvp,WorldIMatrix,world,lightPos); PixelShader = compile ps_1_1 myps(cmap,normalSampler,lightColor,ambiColor); } } /***************************** eof ***/