Advertisement
Guest User

ShadowMapShader.fx

a guest
Feb 28th, 2019
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Matrix */
  2. float4x4 xWorld;
  3. float4x4 xView;
  4. float4x4 xProjection;
  5.  
  6. /* Lights */
  7. float4 xAmbientColor;
  8. float xAmbientIntensity;
  9.  
  10. float3 xDiffuseDirection;
  11. float4 xDiffuseColor;
  12. float xDiffuseIntensity;
  13.  
  14. bool xAmbientOnly; // If true, will not be affected by Diffuse.
  15.  
  16. /* Shadows */
  17. bool xReceiveShadow;
  18. float4x4 xLightsWorldViewProjection;
  19.  
  20. /* Textures */
  21. texture xTexture;
  22. texture xTexShadow;
  23. float xAlphaClipThreshold = 0.75;
  24.  
  25. /* Other */
  26. float xAlpha; // Transparency.
  27.  
  28.  
  29. /* MAIN */
  30. struct MainVertexInput
  31. {
  32.     float4 Position : POSITION0;
  33.     float4 Normal : NORMAL0;
  34.     float2 TextureCoordinate : TEXCOORD0;
  35.     float4 Color : COLOR0;
  36. };
  37.  
  38. // The output from the vertex shader, used for later processing
  39. struct MainVertexToPixel
  40. {
  41.     float4 Position             : POSITION0;
  42.     float4 Pos2DAsSeenByLight    : TEXCOORD0;
  43.  
  44.     float4 Normal : TEXCOORD1;
  45.     float2 TextureCoordinate : TEXCOORD2;
  46.     float4 Color : COLOR0;
  47. };
  48.  
  49. /* SHADOWS */
  50. struct ShadowVertexToPixel
  51. {
  52.     float4 Position     : POSITION;
  53.     float4 Position2D   : TEXCOORD0;
  54.     float2 TextureCoordinate : TEXCOORD1;
  55. };
  56.  
  57. struct ShadowPixelToFrame
  58. {
  59.     float4 Color : COLOR0;
  60. };
  61.  
  62. // Used for the main mesh rendering.
  63. sampler2D MainSampler = sampler_state {
  64.     Texture = (xTexture);
  65.     MinFilter = Linear;
  66.     MagFilter = Linear;
  67.     AddressU = Wrap;
  68.     AddressV = Wrap;
  69. };
  70.  
  71. // Used when rendering meshes for Shadow Map.
  72. sampler2D ShadowMapSamplerPoint = sampler_state {
  73.     Texture = (xTexture);
  74.     MinFilter = POINT;
  75.     MagFilter = POINT;
  76.     AddressU = Wrap;
  77.     AddressV = Wrap;
  78. };
  79.  
  80. // Used when reading Shadow Map texture over the top of the world.
  81. sampler ShadowMapSamplerLinear = sampler_state {
  82.     texture = (xTexShadow);
  83.     magfilter = LINEAR;
  84.     minfilter = LINEAR;
  85.     mipfilter = LINEAR;
  86.     AddressU = clamp;
  87.     AddressV = clamp;
  88. };
  89.  
  90. /*
  91. The VertexShader is used to manipulate vertex data.
  92. It gets a MainVertexInput object as input, and outputs a MainVertexToPixel object.
  93. */
  94. MainVertexToPixel MainVertexShader(MainVertexInput input)
  95. {
  96.     MainVertexToPixel output;
  97.  
  98.     // Standard positioning code
  99.     float4 worldPosition = mul(input.Position, xWorld);
  100.     float4 viewPosition = mul(worldPosition, xView);
  101.     output.Position = mul(viewPosition, xProjection);
  102.  
  103.     // Shadow
  104.     output.Pos2DAsSeenByLight = mul(input.Position, xLightsWorldViewProjection);
  105.  
  106.     // Normals cannot be imported as float4s. The 4th value in a Normal must always be 0, or else weird calculations will happen.
  107.     // Transform (rotate) the normal the same way that the model has been transformed and pass it to the Pixel Shader.
  108.     output.Normal = mul(float4(input.Normal.xyz, 0), xWorld);
  109.  
  110.     output.TextureCoordinate = input.TextureCoordinate;
  111.     output.Color = input.Color;
  112.  
  113.     return output;
  114. }
  115.  
  116. /* The Pixel Shader manipulates all pixels of the model. Its input is the output from the Vertex Shader. */
  117. float4 MainPixelShader(MainVertexToPixel input) : COLOR0
  118. {
  119.     float2 ProjectedTexCoords;
  120.     ProjectedTexCoords[0] = input.Pos2DAsSeenByLight.x / input.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
  121.     ProjectedTexCoords[1] = -input.Pos2DAsSeenByLight.y / input.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
  122.  
  123.     // Intensity of the shadow on any shaded area.
  124.     float diffuseLightingFactor = 0.6;
  125.    
  126.     if (xReceiveShadow)
  127.     {
  128.         // Clip the lighting only to the shaded area (not in use. I want all areas outside the shaded area to be fully lit).
  129.         /*if ((saturate(ProjectedTexCoords).x == ProjectedTexCoords.x) &&
  130.             (saturate(ProjectedTexCoords).y == ProjectedTexCoords.y))
  131.         {*/
  132.  
  133.         float4 t = tex2D(ShadowMapSamplerLinear, ProjectedTexCoords);
  134.         float depthStoredInShadowMap = t.r;
  135.         float realDistance = input.Pos2DAsSeenByLight.z / input.Pos2DAsSeenByLight.w;
  136.  
  137.         // If the area is lit, then don't affect its lighting.
  138.         if ((realDistance - 1.0f / 100.0f) <= depthStoredInShadowMap)
  139.         {
  140.             diffuseLightingFactor = 1;
  141.         }
  142.  
  143.         //}
  144.     }
  145.     else
  146.     {
  147.         // This mesh won't receive shadows. Don't affect its lighting.
  148.         diffuseLightingFactor = 1;
  149.     }
  150.  
  151.     float4 diffuse = input.Color + xAmbientColor * xAmbientIntensity;
  152.  
  153.     // Only apply diffuse when necessary.
  154.     if (!xAmbientOnly)
  155.     {
  156.         float4 normal = normalize(input.Normal);
  157.         float4 NdotL = saturate(dot(normal, float4(-xDiffuseDirection, 1.0)));
  158.         diffuse += NdotL;
  159.         diffuse *= xDiffuseIntensity;
  160.     }
  161.    
  162.     diffuse *= xDiffuseColor;
  163.  
  164.     float4 textureColor = tex2D(MainSampler, input.TextureCoordinate);
  165.     float4 color = diffuse * textureColor * diffuseLightingFactor;
  166.    
  167.     // Cut off the sides of transparent textures.
  168.     color.a = textureColor.a;
  169.     clip(color.a < xAlphaClipThreshold ? -1 : 1);
  170.     color.a *= xAlpha;
  171.  
  172.     return color;
  173. }
  174.  
  175. // Simple vert to pixel. Textures are included to allow for more accurate shadows on meshes with transparent textures.
  176. ShadowVertexToPixel ShadowVertexShader(float4 inPos : POSITION, float2 textureCoordinate : TEXCOORD0)
  177. {
  178.     ShadowVertexToPixel output = (ShadowVertexToPixel)0;
  179.  
  180.     output.Position = mul(inPos, xLightsWorldViewProjection);
  181.     output.Position2D = output.Position;
  182.  
  183.     output.TextureCoordinate = textureCoordinate;
  184.  
  185.     return output;
  186. }
  187.  
  188. ShadowPixelToFrame ShadowPixelShader(ShadowVertexToPixel input)
  189. {
  190.     ShadowPixelToFrame output = (ShadowPixelToFrame)0;
  191.  
  192.     // Determine the alpha of each pixel (to cut out of the shadow if its transparent).
  193.     float textureAlpha = tex2D(ShadowMapSamplerPoint, input.TextureCoordinate).a;
  194.     clip(textureAlpha < xAlphaClipThreshold ? -1 : 1);
  195.  
  196.     output.Color = input.Position2D.z / input.Position2D.w;
  197.     output.Color.a = textureAlpha;
  198.  
  199.     return output;
  200. }
  201.  
  202. /**************/
  203. /* TECHNIQUES */
  204. /**************/
  205.  
  206. // Draw the main scene (draw after drawing the ShadowMap technique).
  207. technique ShadowedScene
  208. {
  209.     pass Pass1
  210.     {
  211.         VertexShader = compile vs_2_0 MainVertexShader();
  212.         PixelShader = compile ps_2_0 MainPixelShader();
  213.     }
  214. }
  215.  
  216. // Draw the shadow map to a texture.
  217. technique ShadowMap
  218. {
  219.     pass Pass2
  220.     {
  221.         VertexShader = compile vs_2_0 ShadowVertexShader();
  222.         PixelShader = compile ps_2_0 ShadowPixelShader();
  223.     }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement