NormalMapping.fx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. float4x4 World;
  2. float4x4 View;
  3. float4x4 Projection;
  4. // ***** Light properties *****
  5. float3 LightPosition;
  6. float4 LightColor;
  7. float4 AmbientLightColor;
  8. // ****************************
  9. // ***** material properties *****
  10. // output from phong specular will be scaled by this amount
  11. float Shininess;
  12. // specular exponent from phong lighting model. controls the "tightness" of
  13. // specular highlights.
  14. float SpecularPower;
  15. // *******************************
  16. texture2D NormalMap;
  17. sampler2D NormalMapSampler = sampler_state
  18. {
  19. Texture = <NormalMap>;
  20. MinFilter = linear;
  21. MagFilter = linear;
  22. MipFilter = linear;
  23. };
  24. texture2D Texture;
  25. sampler2D DiffuseTextureSampler = sampler_state
  26. {
  27. Texture = <Texture>;
  28. MinFilter = linear;
  29. MagFilter = linear;
  30. MipFilter = linear;
  31. };
  32. struct VS_INPUT
  33. {
  34. float4 position : POSITION0;
  35. float2 texCoord : TEXCOORD0;
  36. float3 normal : NORMAL0;
  37. float3 binormal : BINORMAL0;
  38. float3 tangent : TANGENT0;
  39. };
  40. // output from the vertex shader, and input to the pixel shader.
  41. // lightDirection and viewDirection are in world space.
  42. // NOTE: even though the tangentToWorld matrix is only marked
  43. // with TEXCOORD3, it will actually take TEXCOORD3, 4, and 5.
  44. struct VS_OUTPUT
  45. {
  46. float4 position : POSITION0;
  47. float2 texCoord : TEXCOORD0;
  48. float3 lightDirection : TEXCOORD1;
  49. float3 viewDirection : TEXCOORD2;
  50. float3x3 tangentToWorld : TEXCOORD3;
  51. };
  52. VS_OUTPUT VertexShaderFunction( VS_INPUT input )
  53. {
  54. VS_OUTPUT output;
  55. // transform the position into projection space
  56. float4 worldSpacePos = mul(input.position, World);
  57. output.position = mul(worldSpacePos, View);
  58. output.position = mul(output.position, Projection);
  59. // calculate the light direction ( from the surface to the light ), which is not
  60. // normalized and is in world space
  61. output.lightDirection = LightPosition - worldSpacePos;
  62. // similarly, calculate the view direction, from the eye to the surface. not
  63. // normalized, in world space.
  64. float3 eyePosition = mul(-View._m30_m31_m32, transpose(View));
  65. output.viewDirection = worldSpacePos - eyePosition;
  66. // calculate tangent space to world space matrix using the world space tangent,
  67. // binormal, and normal as basis vectors. the pixel shader will normalize these
  68. // in case the world matrix has scaling.
  69. output.tangentToWorld[0] = mul(input.tangent, World);
  70. output.tangentToWorld[1] = mul(input.binormal, World);
  71. output.tangentToWorld[2] = mul(input.normal, World);
  72. // pass the texture coordinate through without additional processing
  73. output.texCoord = input.texCoord;
  74. return output;
  75. }
  76. float4 PixelShaderFunction( VS_OUTPUT input ) : COLOR0
  77. {
  78. // look up the normal from the normal map, and transform from tangent space
  79. // into world space using the matrix created above. normalize the result
  80. // in case the matrix contains scaling.
  81. float3 normalFromMap = tex2D(NormalMapSampler, input.texCoord);
  82. normalFromMap = mul(normalFromMap, input.tangentToWorld);
  83. normalFromMap = normalize(normalFromMap);
  84. // clean up our inputs a bit
  85. input.viewDirection = normalize(input.viewDirection);
  86. input.lightDirection = normalize(input.lightDirection);
  87. // use the normal we looked up to do phong diffuse style lighting.
  88. float nDotL = max(dot(normalFromMap, input.lightDirection), 0);
  89. float4 diffuse = LightColor * nDotL;
  90. // use phong to calculate specular highlights: reflect the incoming light
  91. // vector off the normal, and use a dot product to see how "similar"
  92. // the reflected vector is to the view vector.
  93. float3 reflectedLight = reflect(input.lightDirection, normalFromMap);
  94. float rDotV = max(dot(reflectedLight, input.viewDirection), 0);
  95. float4 specular = Shininess * LightColor * pow(rDotV, SpecularPower);
  96. float4 diffuseTexture = tex2D(DiffuseTextureSampler, input.texCoord);
  97. // return the combined result.
  98. return (diffuse + AmbientLightColor) * diffuseTexture + specular;
  99. }
  100. Technique NormalMapping
  101. {
  102. Pass Go
  103. {
  104. VertexShader = compile vs_2_0 VertexShaderFunction();
  105. PixelShader = compile ps_2_0 PixelShaderFunction();
  106. }
  107. }