Advertisement
Dekowta

Cel Shader

Feb 19th, 2012
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.20 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // file:    CelShader.fx
  3. //
  4. // summary: cel shader class
  5. ////////////////////////////////////////////////////////////////////////////////////////////////////
  6.  
  7. ///////////////////////
  8. //      Matrixs
  9. ///////////////////////
  10.  
  11. /// <summary> Same as with the ToonShader these store the matrixs used
  12. ///           for postioning the sprite. </summary>
  13. matrix World;
  14. matrix View;
  15. matrix Projection;
  16.  
  17. ///////////////////////
  18. //      Textures
  19. ///////////////////////
  20.  
  21. /// <summary> When both techniques of the toon shader
  22. ///           are rendered to render tragets it will create
  23. ///           a basic Scene map which the end result will
  24. ///           multiply with.
  25. ///          
  26. ///           The normal depth texture though can be sampled
  27. ///           to detect the edges. </summary>
  28. Texture2D Scene;
  29. Texture2D NormDepth;
  30.  
  31. ///////////////////////
  32. //  Global Variables
  33. ///////////////////////
  34.  
  35. /// <summary> These variables effect the intensity, strength and
  36. ///           depth of the cel shading
  37. ///           However I have not experimented on all of them yet
  38. ///           get a full understanding of their effects. </summary>
  39. float edgeWidth = 1;
  40.  
  41. float edgeIntensity = 1;
  42.  
  43. float normalSensitivity = 1;
  44.  
  45. float depthSensitivity = 10;
  46.  
  47. float normalThreshold = 0.5;
  48.  
  49. float depthThreshold = 0.1;
  50.  
  51. /// <summary> This should not be set in the shader and should be
  52. ///           defined outside of the shader. for now though
  53. ///           I have set it to the size of my render target
  54. ///           (which was the full screen) </summary>
  55. float2 screenResolution = float2(1280, 720);
  56.  
  57. ///////////////////////
  58. //  Sample state
  59. ///////////////////////
  60.  
  61. SamplerState SampleType
  62. {
  63.     Filter = MIN_MAG_MIP_LINEAR;
  64.     AddressU = Wrap;
  65.     AddressV = Wrap;
  66. };
  67.  
  68. ///////////////////////
  69. // Inputs and outputs
  70. // structures
  71. ///////////////////////
  72.  
  73. /// <summary> Since this shader is going to be used on a sprite
  74. ///           the vertes and pixel structure only need position and
  75. ///           texture coordinates. </summary>
  76. struct PS_INPUT
  77. {
  78.     float4 Pos      : SV_POSITION;
  79.     float2 tex      : TEXCOORD0;
  80. };
  81.  
  82. struct VS_INPUT
  83. {
  84.     float4 Pos      : POSITION;
  85.     float2 tex      : TEXCOORD0;   
  86. };
  87.  
  88. ///////////////////////
  89. //    VertexShader
  90. ///////////////////////
  91.  
  92. /// <summary> Standard vertex shader which positions the sprite and sends
  93. ///           the texture coord to the pixel shader </summary>
  94. PS_INPUT VS( VS_INPUT input )
  95. {
  96.     PS_INPUT output;
  97.    
  98.     // Change the position vector to be 4 units for proper matrix calculations.
  99.     input.Pos.w = 1.0f;
  100.  
  101.     output.Pos = mul( input.Pos, World );
  102.     output.Pos = mul( output.Pos, View );    
  103.     output.Pos = mul( output.Pos, Projection );
  104.    
  105.     // Store the texture coordinates for the pixel shader.
  106.     output.tex = input.tex;
  107.  
  108.     return output;  
  109. }
  110.  
  111. ///////////////////////
  112. //   PixelShader
  113. ///////////////////////
  114. /// <summary> This is where all the cel shading and edge detection
  115. ///           happens. I dont understand all of what happens here
  116. ///           and have commeneted as much as I can. </summary>
  117. float4 PS( PS_INPUT input ) : SV_Target
  118. {
  119.  
  120.     /// <summary> The scene textue is sampled to get the colour
  121.     ///           that will be mulitplied later </summary>
  122.     float3 scene = Scene.Sample(SampleType, input.tex);
  123.  
  124.  
  125.     /// <summary> This edge detection process will output the edges as black
  126.     ///           and will produce white for the rest (i believe) </summary>
  127.  
  128.     float2 edgeOffset = edgeWidth / screenResolution;
  129.  
  130.     /// <summary> The normal map is sampled  </summary>
  131.     float4 n1 = NormDepth.Sample(SampleType, input.tex + float2(-1, -1) * edgeOffset);
  132.  
  133.     float4 n2 = NormDepth.Sample(SampleType, input.tex + float2( 1, 1) * edgeOffset);
  134.  
  135.     float4 n3 = NormDepth.Sample(SampleType, input.tex + float2(-1, 1) * edgeOffset);
  136.  
  137.     float4 n4 = NormDepth.Sample(SampleType, input.tex + float2( 1, -1) * edgeOffset);
  138.  
  139.     float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4);
  140.  
  141.     float normalDelta = dot(diagonalDelta.xyz, 1);
  142.  
  143.     float depthDelta = diagonalDelta.w;
  144.  
  145.     normalDelta = saturate((normalDelta - normalThreshold) * normalSensitivity);
  146.  
  147.     depthDelta = saturate((depthDelta - depthThreshold) * depthSensitivity);
  148.  
  149.     float edgeAmount = saturate(normalDelta + depthDelta) * edgeIntensity;
  150.  
  151.     /// <summary> Once the edges are found and created it will then multiply it
  152.     ///           with the Scene. now since the edges are black any colour
  153.     ///           value multiplied with black will be black. </summary>
  154.     scene *= (1 - edgeAmount);
  155.  
  156.     /// <summary> The final colour is then outputted </summary>
  157.     return float4(scene, 1);
  158.  
  159. }
  160.  
  161.  
  162. ////////////////////////////////////////////////////////////////////////////////
  163. // Technique
  164. ////////////////////////////////////////////////////////////////////////////////
  165.  
  166. technique10 render
  167. {
  168.     pass P0
  169.     {
  170.         SetVertexShader(CompileShader(vs_4_0, VS()));
  171.         SetPixelShader (CompileShader(ps_4_0, PS()));
  172.         SetGeometryShader(NULL);
  173.     }
  174. }
  175.  
  176. ////////////////////////////////////////////////////////////////////////////////////////////////////
  177. // End of CelShader.fx
  178. ////////////////////////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement