Dekowta

Toon and Normal Depth Shader

Feb 19th, 2012
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.37 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // file:    ToonShader.fx
  3. //
  4. // summary: Toon Shader
  5. ////////////////////////////////////////////////////////////////////////////////////////////////////
  6.  
  7.  
  8.  
  9. ///////////////////////
  10. //      Matrixs
  11. ///////////////////////
  12.  
  13.  
  14. /// <summary> The World Matrix.
  15. ///           This information is sent to the shader from the engine
  16. ///           and will use the engine World Matrix </summary>
  17. matrix World;
  18. /// <summary> same as the world matrix but this time with the
  19. ///           View Matrix </summary>
  20. matrix View;
  21. /// <summary> same as the world matrix but this time with the
  22. ///           Projection Matrix </summary>
  23. matrix Projection;
  24.  
  25.  
  26. ///////////////////////
  27. //  Ambient Lighting
  28. ///////////////////////
  29.  
  30. /// <summary> This is the Ambient lighting vaiables
  31. ///           This can be defined outside of the shader
  32. ///           but for not its best to leave a fixed version
  33. ///           Variables:
  34. ///           AmbientColor - Effects the colour of the ambiant lighting
  35. ///           AmbientIntensity - How bright the ambiant lighting shines  </summary>
  36. float4 AmbientColor = float4(1.0f, 1.0f, 1.0f, 1.0f);    //eg rgba float4(1.0f, 1.0f, 1.0f, 1.0f);
  37. float  AmbientIntensity = 0.5f; //eg 0.4f;
  38.  
  39. ///////////////////////
  40. //  Diffuse Lighting
  41. ///////////////////////
  42.  
  43. /// <summary> This is the Diffuse lighting vaiables
  44. ///           Variables:
  45. ///           DiffuseColor - Effects the colour of the Diffuse lighting
  46. ///           DiffuseIntensity - How bright the Diffuse lighting shines
  47. ///           DiffuseLightDirection - The Direction of the Diffuse light  </summary>
  48. float4 DiffuseColor = float4(1.0f, 1.0f, 1.0f, 1.0f);           //eg rgba float4(1.0f, 1.0f, 1.0f, 1.0f);
  49. float  DiffuseIntensity = 0.5f;     //eg 0.4f
  50. float3 DiffuseLightDirection = float3(0.0f, 0.0f, 1.0f);   //eg xyz float3(0.0f, 0.0f, 1.0f);
  51.  
  52.  
  53. int     ShadingLevels = 4;
  54. float   BorderThickness = 0.1f;    
  55. float4  BorderColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
  56.  
  57. float3  CameraPosition;
  58.  
  59. ///////////////////////
  60. //   Model Texture
  61. ///////////////////////
  62.  
  63. /// <summary> The main texture for the model </summary>
  64. Texture2D ModelTexture;
  65.  
  66. /// <summary> I am unsure what this does but from the looks of it
  67. ///           it has something to do with how it gets the colour
  68. ///           from the texture </summary>
  69. SamplerState SampleType
  70. {
  71.     Filter = MIN_MAG_MIP_LINEAR;
  72.     AddressU = Wrap;
  73.     AddressV = Wrap;
  74. };
  75.  
  76. ///////////////////////
  77. // Inputs and outputs
  78. // structures
  79. ///////////////////////
  80.  
  81. /// <summary> This is the vertex shader structure.
  82. ///           The vertex shader structure should be the same
  83. ///           as the input layout described in engine  </summary>
  84. struct VertexInputType
  85. {
  86.     /// <summary> The position of the vertex
  87.     ///           xyzw. w is the scale default is guessed to be 1.0f
  88.     ///           to be sure you can just set w to 1.0f in the vertex
  89.     ///           shader. </summary>
  90.     float4 Pos      : POSITION0;
  91.     /// <summary> The Colour of the vertex
  92.     ///           This is is not needed really but worth keeping </summary>
  93.     float4 Color    : COLOR0;
  94.     /// <summary> Texture coordinates
  95.     ///           This is needed to place the texture onto the model </summary>
  96.     float2 tex      : TEXCOORD0;
  97.     /// <summary> The normals are very important for lighting and other
  98.     ///           stuff such as bump maps. </summary>
  99.     float3 Normal   : NORMAL0;
  100. };
  101.  
  102. /// <summary> This is the Pixel shader structure.
  103. ///           The pixel shader structure will be obtained from
  104. ///           vertex shader this has no effect on the vertex
  105. ///           Layout of the engine it just happens this is the same
  106. ///           as the vertex layout as it need all that information  </summary>
  107. struct PixelInputType
  108. {
  109.     float4 position : SV_POSITION;
  110.     float2 tex      : TEXCOORD0;
  111.     float3 normal   : NORMAL;
  112.     float4 Color    : COLOR0;
  113.  
  114. };
  115.  
  116.  
  117. ///////////////////////
  118. //   VertexShader pass0
  119. ///////////////////////
  120.  
  121. /// <summary> Takes in a vertex shader structure called input </summary>
  122. PixelInputType VS(VertexInputType input)
  123. {
  124.     /// <summary> A pixel shader structure is created
  125.     ///           called output this is what will be send to the
  126.     ///           pixel shader </summary>
  127.     PixelInputType output;
  128.    
  129.    
  130.     /// <summary> As I said about with the vertex structure the
  131.     ///           position also has a w value which is scale
  132.     ///           this is set to 1.0f which should be defualt </summary>
  133.     input.Pos.w = 1.0f;
  134.  
  135.     /// <summary> Nothing really super special happens here but this
  136.     ///           is needed as it works out the vertex position based
  137.     ///           of the world then the view and then the projection </summary>
  138.     output.position = mul(input.Pos, World);
  139.     output.position = mul(output.position, View);
  140.     output.position = mul(output.position, Projection);
  141.    
  142.     /// <summary> Stores the texture coord to the output as it will
  143.     ///           be needed by the pixel shader </summary>
  144.     output.tex = input.tex;
  145.  
  146.     /// <summary> This i am a bit unsure of why it is needed but it works
  147.     ///           out the normal against the word matrix </summary>
  148.     output.normal = mul(input.Normal, (float3x3)World);
  149.    
  150.     /// <summary> Agaian another area I am unsure since I have no idea
  151.     ///           what normalize does but it is a built in function
  152.     ///           of hlsl like mul. This just normalises the normals </summary>
  153.     output.normal = normalize(output.normal);
  154.  
  155.     /// <summary> The colour of the vertex is set to the output colour </summary>
  156.     output.Color = input.Color;
  157.  
  158.     /// <summary> returns the output which is sent to the pixel shader </summary>
  159.     return output;
  160. }
  161.  
  162.  
  163. ///////////////////////
  164. //   VertexShader pass0
  165. ///////////////////////
  166.  
  167. /// <summary> This is where most of the magic happens visually as it works out the pixe
  168. ///           output on the screen. This takes the output from the vertex shader </summary>
  169. float4 PS(PixelInputType input) : SV_Target//this SV_Target is impotant and would be COLOR0 in the old
  170. {                                          //shader models
  171.                                            //SV_Target can select a single type by calling
  172.                                            //SV_Target0 to 3 (depending on the VS structure i beleive
  173.  
  174.  
  175.  
  176.     /// <summary> Determine the diffuse component by finding the angle between the light and the normal.
  177.     /// The smaller the angle between the normal and the light direction, the closer the dot
  178.     /// product will be to 1, and the brighter the pixel will be. </summary>
  179.     float4 diffuse = dot( DiffuseLightDirection, input.normal ) * DiffuseIntensity * DiffuseColor;
  180.    
  181.     /// <summary> Calculate our ambient component  </summary>
  182.     float4 ambient = AmbientIntensity * AmbientColor;
  183.    
  184.     /// <summary> Return the total light component as a combination of the diffuse and ambient.
  185.     // Saturate it to keep the color between 0 and 1. </summary>
  186.     float4 color = saturate( diffuse + ambient );
  187.  
  188.  
  189.     /// </summary>This is the important part of the toon shading and this is a great method I found from
  190.     ///           Daniel Greenheck @ Digit 7 allong with the lighting
  191.     ///           Unlike many other example which have set values which the shading should be
  192.     ///           this method allows x different shades of light. If later you decide toon lighting
  193.     ///           isn't so great you can change ShadingLevels to 100 and having it back to a smooth
  194.     ///           shading though it would not be recomended as you could do it without this calcluation<summary>
  195.  
  196.     /// <summary> Multiply by the number of shading levels so the color value can range from 0 to ShadingLevels </summary>
  197.     color.rgb *= ShadingLevels;
  198.     /// <summary> Round to the highest integer. This is what flattens out the color </summary>
  199.     color.rgb = ceil(color.rgb);
  200.     /// <summary> Redivide by the number of shading levels to normalize the values to between 0 and 1. </summary>
  201.     color.rgb /= (float)ShadingLevels;
  202.    
  203.     /// <summary> Sample the pixel color from the texture using the sampler at this texture coordinate location  </summary>
  204.     float4 textureColor = ModelTexture.Sample(SampleType, input.tex);
  205.  
  206.     /// <summary> multiply the shading with the texture to get the result colour which will
  207.     ///           give the toon shaded look to a textured model  </summary>
  208.     color = color * textureColor;
  209.  
  210.     /// <summary> and finaly return the colour </summary>
  211.     return color;
  212.    
  213. }
  214.  
  215.  
  216. ///////////////////////
  217. //     DepthShader
  218. ///////////////////////
  219.  
  220.  
  221. /// <summary> The Second part of this shader I took from a post on MSDN by
  222. ///           ukstudentzine who used a depth normal map to produce the
  223. ///           post process effect as it would make edge detection a lot easier </summary>
  224.  
  225.  
  226. /// <summary> Output structure for the vertex shader that renders normal and depth information. </summary>
  227. struct NormalDepthVertexShaderOutput
  228. {
  229.     float4 Position : SV_POSITION;
  230.     float2 tex      : TEXCOORD0;
  231.     float3 normal   : NORMAL;
  232.     float4 Color    : COLOR0;
  233. };
  234.  
  235. ///////////////////////
  236. //    VertexShader pass1
  237. ///////////////////////
  238.  
  239. // Alternative vertex shader outputs normal and depth values, which are then
  240. // used as an input for the edge detection filter in PostprocessEffect.fx.
  241. NormalDepthVertexShaderOutput VSN(VertexInputType input)
  242. {
  243.     NormalDepthVertexShaderOutput output;
  244.  
  245.     /// <summary> As I said about with the vertex structure the
  246.     ///           position also has a w value which is scale
  247.     ///           this is set to 1.0f which should be defualt </summary>
  248.     input.Pos.w = 1.0f;
  249.  
  250.     /// <summary> Nothing really super special happens here but this
  251.     ///           is needed as it works out the vertex position based
  252.     ///           of the world then the view and then the projection </summary>
  253.     output.Position = mul(input.Pos, World);
  254.     output.Position = mul(output.Position, View);
  255.     output.Position = mul(output.Position, Projection);
  256.    
  257.     float3 worldNormal = mul(input.Normal, World);
  258.  
  259.     /// <summary> The output color holds the normal, scaled to fit into a 0 to 1 range. </summary>
  260.     output.Color.rgb = (worldNormal + 1) / 2;
  261.  
  262.     /// <summary> The output alpha holds the depth, scaled to fit into a 0 to 1 range. </summary>
  263.     output.Color.a = output.Position.z / output.Position.w;
  264.    
  265.     return output;    
  266. }
  267.  
  268. ///////////////////////
  269. //   PixelShader pass1
  270. ///////////////////////
  271.  
  272. /// <summary> Simple pixel shader for rendering the normal and depth information. </summary>
  273. float4 PSN(NormalDepthVertexShaderOutput input) : SV_Target
  274. {
  275.     return input.Color;
  276. }
  277.  
  278.  
  279.  
  280. ////////////////////////////////////////////////////////////////////////////////
  281. // Technique
  282. ////////////////////////////////////////////////////////////////////////////////
  283.  
  284. /// <summary> I have kept the techniques seperate so they can be called seperatly without
  285. ///           affecting the other effect. </summary>
  286. technique10 ToonShade
  287. {
  288.     pass pass0
  289.     {
  290.         SetVertexShader(CompileShader(vs_4_0, VS()));
  291.         SetPixelShader (CompileShader(ps_4_0, PS()));
  292.         SetGeometryShader(NULL);
  293.     }
  294. }
  295.  
  296. technique10 DepthNorm
  297. {
  298.     pass pass0
  299.     {
  300.         SetVertexShader(CompileShader(vs_4_0, VSN()));
  301.         SetPixelShader (CompileShader(ps_4_0, PSN()));
  302.         SetGeometryShader(NULL);
  303.     }
  304. }
  305.  
  306. ////////////////////////////////////////////////////////////////////////////////////////////////////
  307. // End of ToonShader.fx
  308. ////////////////////////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment