CartoonEffect.Fx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //-----------------------------------------------------------------------------
  2. // CartoonEffect.fx
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. // Camera settings.
  8. float4x4 World;
  9. float4x4 View;
  10. float4x4 Projection;
  11. // The light direction is shared between the Lambert and Toon lighting techniques.
  12. float3 LightDirection = normalize(float3(1, 1, 1));
  13. // Settings controlling the Lambert lighting technique.
  14. float3 DiffuseLight = 0.5;
  15. float3 AmbientLight = 0.5;
  16. // Settings controlling the Toon lighting technique.
  17. float ToonThresholds[2] = { 0.8, 0.4 };
  18. float ToonBrightnessLevels[3] = { 1.3, 0.9, 0.5 };
  19. // Is texturing enabled?
  20. bool TextureEnabled;
  21. // The main texture applied to the object, and a sampler for reading it.
  22. texture Texture;
  23. sampler Sampler = sampler_state
  24. {
  25. Texture = (Texture);
  26. MinFilter = Linear;
  27. MagFilter = Linear;
  28. MipFilter = Linear;
  29. AddressU = Wrap;
  30. AddressV = Wrap;
  31. };
  32. // Vertex shader input structure.
  33. struct VertexShaderInput
  34. {
  35. float4 Position : POSITION0;
  36. float3 Normal : NORMAL0;
  37. float2 TextureCoordinate : TEXCOORD0;
  38. };
  39. // Output structure for the vertex shader that applies lighting.
  40. struct LightingVertexShaderOutput
  41. {
  42. float4 Position : POSITION0;
  43. float2 TextureCoordinate : TEXCOORD0;
  44. float LightAmount : TEXCOORD1;
  45. };
  46. // Input structure for the Lambert and Toon pixel shaders.
  47. struct LightingPixelShaderInput
  48. {
  49. float2 TextureCoordinate : TEXCOORD0;
  50. float LightAmount : TEXCOORD1;
  51. };
  52. // Vertex shader shared between the Lambert and Toon lighting techniques.
  53. LightingVertexShaderOutput LightingVertexShader(VertexShaderInput input)
  54. {
  55. LightingVertexShaderOutput output;
  56. // Apply camera matrices to the input position.
  57. output.Position = mul(mul(mul(input.Position, World), View), Projection);
  58. // Copy across the input texture coordinate.
  59. output.TextureCoordinate = input.TextureCoordinate;
  60. // Compute the overall lighting brightness.
  61. float3 worldNormal = mul(input.Normal, World);
  62. output.LightAmount = dot(worldNormal, LightDirection);
  63. return output;
  64. }
  65. // Pixel shader applies a simple Lambert shading algorithm.
  66. float4 LambertPixelShader(LightingPixelShaderInput input) : COLOR0
  67. {
  68. float4 color = TextureEnabled ? tex2D(Sampler, input.TextureCoordinate) : 0;
  69. color.rgb *= saturate(input.LightAmount) * DiffuseLight + AmbientLight;
  70. return color;
  71. }
  72. // Pixel shader applies a cartoon shading algorithm.
  73. float4 ToonPixelShader(LightingPixelShaderInput input) : COLOR0
  74. {
  75. float4 color = TextureEnabled ? tex2D(Sampler, input.TextureCoordinate) : 0;
  76. float light;
  77. if (input.LightAmount > ToonThresholds[0])
  78. light = ToonBrightnessLevels[0];
  79. else if (input.LightAmount > ToonThresholds[1])
  80. light = ToonBrightnessLevels[1];
  81. else
  82. light = ToonBrightnessLevels[2];
  83. color.rgb *= light;
  84. return color;
  85. }
  86. // Output structure for the vertex shader that renders normal and depth information.
  87. struct NormalDepthVertexShaderOutput
  88. {
  89. float4 Position : POSITION0;
  90. float4 Color : COLOR0;
  91. };
  92. // Alternative vertex shader outputs normal and depth values, which are then
  93. // used as an input for the edge detection filter in PostprocessEffect.fx.
  94. NormalDepthVertexShaderOutput NormalDepthVertexShader(VertexShaderInput input)
  95. {
  96. NormalDepthVertexShaderOutput output;
  97. // Apply camera matrices to the input position.
  98. output.Position = mul(mul(mul(input.Position, World), View), Projection);
  99. float3 worldNormal = mul(input.Normal, World);
  100. // The output color holds the normal, scaled to fit into a 0 to 1 range.
  101. output.Color.rgb = (worldNormal + 1) / 2;
  102. // The output alpha holds the depth, scaled to fit into a 0 to 1 range.
  103. output.Color.a = output.Position.z / output.Position.w;
  104. return output;
  105. }
  106. // Simple pixel shader for rendering the normal and depth information.
  107. float4 NormalDepthPixelShader(float4 color : COLOR0) : COLOR0
  108. {
  109. return color;
  110. }
  111. // Technique draws the object using smooth Lambert shading.
  112. technique Lambert
  113. {
  114. pass P0
  115. {
  116. VertexShader = compile vs_2_0 LightingVertexShader();
  117. PixelShader = compile ps_2_0 LambertPixelShader();
  118. }
  119. }
  120. // Technique draws the object using banded cartoon shading.
  121. technique Toon
  122. {
  123. pass P0
  124. {
  125. VertexShader = compile vs_2_0 LightingVertexShader();
  126. PixelShader = compile ps_2_0 ToonPixelShader();
  127. }
  128. }
  129. // Technique draws the object as normal and depth values.
  130. technique NormalDepth
  131. {
  132. pass P0
  133. {
  134. VertexShader = compile vs_2_0 NormalDepthVertexShader();
  135. PixelShader = compile ps_2_0 NormalDepthPixelShader();
  136. }
  137. }