SHARE
TWEET

Untitled

a guest Aug 4th, 2013 109 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //-----------------------------------------------------------------------------
  2. // PostprocessEffect.fx
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7.  
  8.  
  9. // Settings controlling the edge detection filter.
  10. float EdgeWidth = 1;
  11. float EdgeIntensity = 1;
  12.  
  13. // How sensitive should the edge detection be to tiny variations in the input data?
  14. // Smaller settings will make it pick up more subtle edges, while larger values get
  15. // rid of unwanted noise.
  16. float NormalThreshold = 0.5;
  17. float DepthThreshold = 0.1;
  18.  
  19. // How dark should the edges get in response to changes in the input data?
  20. float NormalSensitivity = 1;
  21. float DepthSensitivity = 10;
  22.  
  23. // How should the sketch effect respond to changes of brightness in the input scene?
  24. float SketchThreshold = 0.1;
  25. float SketchBrightness = 0.333;
  26.  
  27. // Randomly offsets the sketch overlay pattern to create a hand-drawn animation effect.
  28. float2 SketchJitter;
  29.  
  30. // Pass in the current screen resolution.
  31. float2 ScreenResolution;
  32.  
  33.  
  34. // This texture contains the main scene image, which the edge detection
  35. // and/or sketch filter are being applied over the top of.
  36. texture SceneTexture;
  37.  
  38. sampler SceneSampler : register(s0) = sampler_state
  39. {
  40.     Texture = (SceneTexture);
  41.    
  42.     MinFilter = Linear;
  43.     MagFilter = Linear;
  44.    
  45.     AddressU = Clamp;
  46.     AddressV = Clamp;
  47. };
  48.  
  49.  
  50. // This texture contains normals (in the color channels) and depth (in alpha)
  51. // for the main scene image. Differences in the normal and depth data are used
  52. // to detect where the edges of the model are.
  53. texture NormalDepthTexture;
  54.  
  55. sampler NormalDepthSampler : register(s1) = sampler_state
  56. {
  57.     Texture = (NormalDepthTexture);
  58.    
  59.     MinFilter = Linear;
  60.     MagFilter = Linear;
  61.    
  62.     AddressU = Clamp;
  63.     AddressV = Clamp;
  64. };
  65.  
  66.  
  67. // This texture contains an overlay sketch pattern, used to create the hatched
  68. // pencil drawing effect.
  69. texture SketchTexture;
  70.  
  71. sampler SketchSampler : register(s2) = sampler_state
  72. {
  73.     Texture = (SketchTexture);
  74.  
  75.     AddressU = Wrap;
  76.     AddressV = Wrap;
  77. };
  78.  
  79.  
  80. // Pixel shader applies the edge detection and/or sketch filter postprocessing.
  81. // It is compiled several times using different settings for the uniform boolean
  82. // parameters, producing different optimized versions of the shader depending on
  83. // which combination of processing effects is desired.
  84. float4 PixelShaderFunction(float2 texCoord : TEXCOORD0, uniform bool applyEdgeDetect,
  85.                                                         uniform bool applySketch,
  86.                                                         uniform bool sketchInColor) : COLOR0
  87. {
  88.     // Look up the original color from the main scene.
  89.     float3 scene = tex2D(SceneSampler, texCoord);
  90.    
  91.     // Apply the sketch effect?
  92.     if (applySketch)
  93.     {
  94.         // Adjust the scene color to remove very dark values and increase the contrast.
  95.         float3 saturatedScene = saturate((scene - SketchThreshold) * 2);
  96.        
  97.         // Look up into the sketch pattern overlay texture.
  98.         float3 sketchPattern = tex2D(SketchSampler, texCoord + SketchJitter);
  99.    
  100.         // Convert into negative color space, and combine the scene color with the
  101.         // sketch pattern. We need to do this multiply in negative space to get good
  102.         // looking results, because pencil sketching works by drawing black ink
  103.         // over an initially white page, rather than adding light to an initially
  104.         // black background as would be more common in computer graphics.
  105.         float3 negativeSketch = (1 - saturatedScene) * (1 - sketchPattern);
  106.        
  107.         // Convert the result into a positive color space greyscale value.
  108.         float sketchResult = dot(1 - negativeSketch, SketchBrightness);
  109.        
  110.         // Apply the sketch result to the main scene color.
  111.         if (sketchInColor)
  112.             scene *= sketchResult;
  113.         else
  114.             scene = sketchResult;
  115.     }
  116.    
  117.     // Apply the edge detection filter?
  118.     if (applyEdgeDetect)
  119.     {
  120.         // Look up four values from the normal/depth texture, offset along the
  121.         // four diagonals from the pixel we are currently shading.
  122.         float2 edgeOffset = EdgeWidth / ScreenResolution;
  123.        
  124.         float4 n1 = tex2D(NormalDepthSampler, texCoord + float2(-1, -1) * edgeOffset);
  125.         float4 n2 = tex2D(NormalDepthSampler, texCoord + float2( 1,  1) * edgeOffset);
  126.         float4 n3 = tex2D(NormalDepthSampler, texCoord + float2(-1,  1) * edgeOffset);
  127.         float4 n4 = tex2D(NormalDepthSampler, texCoord + float2( 1, -1) * edgeOffset);
  128.  
  129.         // Work out how much the normal and depth values are changing.
  130.         float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4);
  131.  
  132.         float normalDelta = dot(diagonalDelta.xyz, 1);
  133.         float depthDelta = diagonalDelta.w;
  134.        
  135.         // Filter out very small changes, in order to produce nice clean results.
  136.         //normalDelta = saturate((normalDelta - NormalThreshold) * NormalSensitivity);
  137.         //depthDelta = saturate((depthDelta - DepthThreshold) * DepthSensitivity);
  138.  
  139.         // Does this pixel lie on an edge?
  140.         float edgeAmount = saturate(normalDelta + depthDelta) * EdgeIntensity;
  141.        
  142.         // Apply the edge detection result to the main scene color.
  143.         scene *= (1 - edgeAmount);
  144.     }
  145.  
  146.     return float4(scene, 1);
  147. }
  148.  
  149.  
  150. // Compile the pixel shader for doing edge detection without any sketch effect.
  151. technique EdgeDetect
  152. {
  153.     pass P0
  154.     {
  155.         PixelShader = compile ps_2_0 PixelShaderFunction(true, false, false);
  156.     }
  157. }
  158.  
  159. // Compile the pixel shader for doing edge detection with a monochrome sketch effect.
  160. technique EdgeDetectMonoSketch
  161. {
  162.     pass P0
  163.     {
  164.         PixelShader = compile ps_2_0 PixelShaderFunction(true, true, false);
  165.     }
  166. }
  167.  
  168. // Compile the pixel shader for doing edge detection with a colored sketch effect.
  169. technique EdgeDetectColorSketch
  170. {
  171.     pass P0
  172.     {
  173.         PixelShader = compile ps_2_0 PixelShaderFunction(true, true, true);
  174.     }
  175. }
  176.  
  177. // Compile the pixel shader for doing a monochrome sketch effect without edge detection.
  178. technique MonoSketch
  179. {
  180.     pass P0
  181.     {
  182.         PixelShader = compile ps_2_0 PixelShaderFunction(false, true, false);
  183.     }
  184. }
  185.  
  186. // Compile the pixel shader for doing a colored sketch effect without edge detection.
  187. technique ColorSketch
  188. {
  189.     pass P0
  190.     {
  191.         PixelShader = compile ps_2_0 PixelShaderFunction(false, true, true);
  192.     }
  193. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top