home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the 3D Game Programming Gurus / gurus.iso / DirectX / dx9sdkcp.exe / SDK (C++) / Samples / Media / DepthOfField.fx < prev    next >
Encoding:
Text File  |  2002-11-18  |  10.2 KB  |  475 lines

  1. //
  2. // Depth of field effect
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. //
  5. // Note: This effect file does not work with EffectEdit.
  6. //
  7.  
  8. float4 Ambient;
  9. float4 Specular;
  10. float4 Diffuse;
  11. float4 Emissive;
  12. float Power;
  13.  
  14. texture RenderTargetTexture;
  15. texture EarthTexture;
  16.  
  17. float4x4 mWorldView;
  18. float4x4 mProjection;
  19.  
  20. float3 vLightDir = normalize(float3(1.0f, 1.0f, 1.0f));
  21.  
  22. float4 vFocalPlane;
  23. float  fHyperfocalDistance = 0.4f;
  24.  
  25. float MaxBlurFactor = 3.0f / 4.0f;
  26.  
  27. sampler RenderTarget = 
  28. sampler_state
  29. {
  30.     Texture = <RenderTargetTexture>;
  31.     MinFilter = LINEAR;
  32.     MagFilter = LINEAR;
  33.  
  34.     AddressU = Clamp;
  35.     AddressV = Clamp;
  36. };
  37.  
  38. float2 TwelveKernel[12];
  39. float2 TwelveKernelBase[12] =
  40. {
  41.     { 1.0f,  0.0f},
  42.     { 0.5f,  0.8660f},
  43.     {-0.5f,  0.8660f},
  44.     {-1.0f,  0.0f},
  45.     {-0.5f, -0.8660f},
  46.     { 0.5f, -0.8660f},
  47.     
  48.     { 1.5f,  0.8660f},
  49.     { 0.0f,  1.7320f},
  50.     {-1.5f,  0.8660f},
  51.     {-1.5f, -0.8660f},
  52.     { 0.0f, -1.7320f},
  53.     { 1.5f, -0.8660f},
  54. };
  55.  
  56. //
  57. // HLSL can't currently generate a 5 sample DepthOfField
  58. // shader within ps1.4 instruction limits.
  59. //
  60. PIXELSHADER ps14DepthOfFieldNoRings = 
  61. asm
  62. {
  63.     ps.1.4
  64.     
  65.     def c0, 0.66666, 0, 0.4, 0.5
  66.  
  67.     texld r0, t0
  68.     texld r1, t1
  69.     texld r2, t2
  70.     texld r3, t3
  71.  
  72.     mul_sat r1.a, r1.a, r0.a
  73.     lrp r1.rgb, r1.a, r1, r0
  74.  
  75.     +mul_sat r2.a, r2.a, r0.a
  76.     lrp r2.rgb, r2.a, r2, r0
  77.  
  78.     +mul_sat r3.a, r3.a, r0.a
  79.     lrp r3.rgb, r3.a, r3, r0
  80.  
  81.     lrp r1, c0.a, r1, r2
  82.  
  83.     lrp r3.rgb, c0.r, r1, r3
  84.  
  85.     phase
  86.  
  87.     texld r0, t0
  88.     texld r1, t4
  89.     texld r2, t5
  90.  
  91.     mul_sat r1.a, r1.a, r0.a
  92.     lrp r1.rgb, r1.a, r1, r0
  93.  
  94.     +mul_sat r2.a, r2.a, r0.a
  95.     lrp r2.rgb, r2.a, r2, r0
  96.  
  97.     lrp r1.rgb, c0.a, r1, r2
  98.  
  99.     lrp r0.rgb, c0.z, r1, r3
  100. };
  101.  
  102. PIXELSHADER ps11DepthOfFieldNoRings = 
  103. asm
  104. {
  105.     ps_1_1
  106.     
  107.     def c0, 0, 0, 0, 0.5
  108.     def c1, 0, 0, 0, 0.666666
  109.  
  110.     tex t0
  111.     tex t1
  112.     tex t2
  113.     tex t3
  114.  
  115.     mul_sat t1.a, t1.a, t0.a
  116.     lrp t1.rgb, t1.a, t1, t0
  117.  
  118.     +mul_sat t2.a, t2.a, t0.a
  119.     lrp t2.rgb, t2.a, t2, t0
  120.  
  121.     +mul_sat t3.a, t3.a, t0.a
  122.     lrp t3.rgb, t3.a, t3, t0
  123.  
  124.     lrp t1, c0.a, t1, t2
  125.     lrp r0, c1.a, t1, t3
  126. };
  127.  
  128. float4 DepthOfFieldNoRings
  129.     (
  130.     in float2 OriginalUV : TEXCOORD0,
  131.     in float2 JitterUV[3] : TEXCOORD1
  132.     ) : COLOR
  133. {
  134.     float4 Original = tex2D(RenderTarget, OriginalUV);
  135.     float4 Jitter[3];
  136.     float3 Blurred;
  137.     
  138.     for(int i = 0; i < 3; i++)
  139.     {
  140.         Jitter[i] = tex2D(RenderTarget, JitterUV[i]);
  141.         Jitter[i].rgb = lerp(Original.rgb, Jitter[i].rgb, saturate(Original.a*Jitter[i].a));
  142.     }
  143.         
  144.     // Average the first two jitter samples
  145.     Blurred = lerp(Jitter[0].rgb, Jitter[1].rgb, 0.5);
  146.     
  147.     // Equally weight all three jitter samples
  148.     Blurred = lerp(Jitter[2].rgb, Blurred, 0.66666);
  149.     
  150.     return float4(Blurred, 1.0f);
  151. }
  152.     
  153. float4 DepthOfFieldWithSixTexcoords
  154.     (
  155.     in float2 OriginalUV : TEXCOORD0,
  156.     in float2 JitterUV[5] : TEXCOORD1
  157.     ) : COLOR
  158. {
  159.     float4 Original = tex2D(RenderTarget, OriginalUV);
  160.     float4 Jitter[5];
  161.     float3 Blurred = 0;
  162.     
  163.     for(int i = 0; i < 5; i++)
  164.     {
  165.         Jitter[i] = tex2D(RenderTarget, JitterUV[i]);
  166.         Blurred += lerp(Original.rgb, Jitter[i].rgb, saturate(Original.a*Jitter[i].a));
  167.     }
  168.             
  169.     return float4(Blurred / 5.0f, 1.0f);
  170. }
  171.     
  172. float4 DepthOfFieldManySamples
  173.     (
  174.     in float2 OriginalUV : TEXCOORD0,
  175.     uniform float2 KernelArray[12],
  176.     uniform int NumSamples
  177.     ) : COLOR
  178. {
  179.     float4 Original = tex2D(RenderTarget, OriginalUV);
  180.     float3 Blurred = 0;
  181.     
  182.     for(int i = 0; i < NumSamples; i++)
  183.     {
  184.         float4 Current = tex2D(RenderTarget, OriginalUV + KernelArray[i]);
  185.         Blurred += lerp(Original.rgb, Current.rgb, saturate(Original.a*Current.a));
  186.     }
  187.             
  188.     return float4(Blurred / NumSamples, 1.0f);
  189. }
  190.  
  191. PIXELSHADER ps11DepthOfFieldWithRings = 
  192. asm
  193. {
  194.     ps.1.1
  195.     
  196.     def c0, 0.33333, 0.33333, 0.33333, 0.33333
  197.     def c1, 0.66666, 0.5, 0.5, 0.5
  198.     def c2, 0.66666, 0.5, 0.5, 0.666666
  199.  
  200.     tex t0
  201.     tex t1
  202.     tex t2
  203.     tex t3
  204.  
  205.     lrp t1.rgb, t0.a, t1, t0
  206.  
  207.     lrp t2.rgb, t0.a, t2, t0
  208.  
  209.     lrp t3.rgb, t0.a, t3, t0
  210.  
  211.     lrp t1, c1.a, t1, t2
  212.     lrp r0, c2.a, t1, t3
  213. };
  214.  
  215. float4 DepthOfFieldWithRings
  216.     (
  217.     in float2 OriginalUV : TEXCOORD0,
  218.     in float2 JitterUV[3] : TEXCOORD1
  219.     ) : COLOR
  220. {
  221.     float4 Original = tex2D(RenderTarget, OriginalUV);
  222.     float4 Jitter[3];
  223.     float3 Blurred;
  224.     
  225.     for(int i = 0; i < 3; i++)
  226.     {
  227.         Jitter[i] = tex2D(RenderTarget, JitterUV[i]);
  228.         Jitter[i].rgb = lerp(Original.rgb, Jitter[i].rgb, Original.a);
  229.     }
  230.         
  231.     // Average the first two jitter samples
  232.     Blurred = lerp(Jitter[0].rgb, Jitter[1].rgb, 0.5);
  233.     
  234.     // Equally weight all three jitter samples
  235.     Blurred = lerp(Jitter[2].rgb, Blurred, 0.66666);
  236.     
  237.     return float4(Blurred, 1.0f);
  238. }
  239.     
  240.  
  241. PIXELSHADER ps11ShowAlpha = 
  242. asm
  243. {
  244.     ps.1.1
  245.     tex t0
  246.     mov r0, t0.a
  247. };
  248.  
  249.  
  250. PIXELSHADER ps11ShowUnmodified = 
  251. asm
  252. {
  253.     ps.1.1
  254.     tex t0
  255.     mov r0, t0
  256. };
  257.  
  258.  
  259. // Output structure for WorldTransform
  260. struct VS_OUTPUT_TEXCOORD0
  261. {
  262.     float4 Position : POSITION;
  263.     float4 Diffuse : COLOR;
  264.     float2 Texture0 : TEXCOORD0;
  265. };
  266.  
  267.  
  268. // Transform objects into the view, also setting the appropriate blur factor
  269. VS_OUTPUT_TEXCOORD0 WorldTransform
  270.     (
  271.     float4 vPos : POSITION, 
  272.     float3 vNormal : NORMAL,
  273.     float2 vTexCoord0 : TEXCOORD0
  274.     )
  275. {
  276.     VS_OUTPUT_TEXCOORD0 Output;
  277.     float3 vTransformedPosition;
  278.     float3 vTransformedNormal;
  279.     float fBlurFactor;
  280.   
  281.     // tranform the position/normal into view space
  282.     vTransformedPosition = mul(vPos, (float4x3)mWorldView);
  283.     vTransformedNormal = mul(vNormal, (float3x3)mWorldView);       
  284.     
  285.     // tranform view space position into screen space
  286.     Output.Position = mul(float4(vTransformedPosition, 1.0), mProjection);
  287.     
  288.     // Compute simple lighting equation
  289.     //   NOTE: color could be negative with this equation, but will be clamped to zero before pixel shader
  290.     Output.Diffuse.rgb = Diffuse * dot(vTransformedNormal, vLightDir) + Ambient;
  291.     
  292.     // Compute blur factor and place in output alpha
  293.     fBlurFactor      = dot(float4(vTransformedPosition, 1.0), vFocalPlane)*fHyperfocalDistance;
  294.     Output.Diffuse.a = fBlurFactor*fBlurFactor;
  295.     
  296.     // put a cap on the max blur value.  This is required to ensure that the center pixel
  297.     //  is always weighted in the blurred image.  I.E. in the PS11 case, the correct maximum
  298.     //  value is (NumSamples - 1) / NumSamples, otherwise at BlurFactor == 1.0f, only the outer
  299.     //  samples are contributing to the blurred image which causes annoying ring artifacts
  300.     Output.Diffuse.a = min(Output.Diffuse.a, MaxBlurFactor);
  301.     
  302.     // just copy the texture coordinate through
  303.     Output.Texture0 = float2(1.0-vTexCoord0.x, vTexCoord0.y);
  304.     
  305.     return Output;    
  306. }
  307.  
  308.  
  309. //
  310. // Technique "World" - Draws the original, unblurred image
  311. //
  312. technique World
  313. {
  314.     pass P0
  315.     {        
  316.         VertexShader = compile vs_1_1 WorldTransform();
  317.  
  318.         MinFilter[0] = Linear;
  319.         MagFilter[0] = Linear;
  320.         MipFilter[0] = Linear;
  321.  
  322.         // Stage0
  323.         ColorOp[0]   = Modulate;
  324.         ColorArg1[0] = Texture;
  325.         ColorArg2[0] = Current;
  326.         AlphaOp[0]   = SelectArg1;
  327.         AlphaArg1[0] = Current;
  328.  
  329.         Texture[0] = <EarthTexture>;
  330.  
  331.         // Stage1
  332.         ColorOp[1] = Disable;
  333.         AlphaOp[1] = Disable;
  334.     }
  335. }
  336.  
  337.  
  338. //
  339. // Various techniques for simulating depth of field
  340. // 
  341.  
  342. technique UsePS11WithRings
  343. <
  344.     float MaxBlurFactor = 3.0f / 4.0f;
  345. >
  346. {
  347.     pass P0
  348.     {        
  349.         PixelShader = compile ps_1_1 DepthOfFieldWithRings();
  350.     }
  351. }
  352.  
  353. technique UsePS11WithRingsAsm
  354. <
  355.     float MaxBlurFactor = 3.0f / 4.0f;
  356. >
  357. {
  358.     pass P0
  359.     {        
  360.         Sampler[0] = <RenderTarget>;
  361.         Sampler[1] = <RenderTarget>;
  362.         Sampler[2] = <RenderTarget>;
  363.         Sampler[3] = <RenderTarget>;
  364.  
  365.         PixelShader = <ps11DepthOfFieldWithRings>;
  366.     }
  367. }
  368.  
  369. technique UsePS11NoRings
  370. <
  371.     float MaxBlurFactor = 3.0f / 4.0f;
  372. >
  373. {
  374.     pass P0
  375.     {        
  376.         PixelShader = compile ps_1_1 DepthOfFieldNoRings();
  377.     }
  378. }
  379.  
  380. technique UsePS11NoRingsAsm
  381. <
  382.     float MaxBlurFactor = 3.0f / 4.0f;
  383. >
  384. {
  385.     pass P0
  386.     {        
  387.         Sampler[0] = <RenderTarget>;
  388.         Sampler[1] = <RenderTarget>;
  389.         Sampler[2] = <RenderTarget>;
  390.         Sampler[3] = <RenderTarget>;
  391.  
  392.         PixelShader = <ps11DepthOfFieldNoRings>;
  393.     }
  394. }
  395.  
  396. technique UsePS14NoRingsAsm
  397. <
  398.     float MaxBlurFactor = 4.0f / 5.0f;
  399. >
  400. {
  401.     pass P0
  402.     {        
  403.         Sampler[0] = <RenderTarget>;
  404.         Sampler[1] = <RenderTarget>;
  405.         Sampler[2] = <RenderTarget>;
  406.         Sampler[3] = <RenderTarget>;
  407.  
  408.         PixelShader = <ps14DepthOfFieldNoRings>;
  409.     }
  410. }
  411.  
  412. technique UsePS20SixTexcoords
  413. <
  414.     float MaxBlurFactor = 4.0f / 5.0f;
  415. >
  416. {
  417.     pass P0
  418.     {        
  419.         PixelShader = compile ps_2_0 DepthOfFieldWithSixTexcoords();
  420.     }
  421. }
  422.  
  423. technique UsePS20SevenLookups
  424. <
  425.     float MaxBlurFactor = 6.0f / 7.0f;
  426.     int NumKernelEntries = 12;
  427.     string KernelInputArray = "TwelveKernelBase";
  428.     string KernelOutputArray = "TwelveKernel";  
  429. >
  430. {
  431.     pass P0
  432.     {        
  433.         PixelShader = compile ps_2_0 DepthOfFieldManySamples(TwelveKernel, 6);
  434.     }
  435. }
  436.  
  437. technique UsePS20ThirteenLookups
  438. <
  439.     float MaxBlurFactor = 12.0f / 13.0f;
  440.     int NumKernelEntries = 12;
  441.     string KernelInputArray = "TwelveKernelBase";
  442.     string KernelOutputArray = "TwelveKernel";  
  443. >
  444. {
  445.     pass P0
  446.     {        
  447.         PixelShader = compile ps_2_0 DepthOfFieldManySamples(TwelveKernel, 12);
  448.     }
  449. }
  450.  
  451. //
  452. // Technique "ShowAlpha" - display the per pixel blur factor
  453. // 
  454. technique ShowAlpha
  455. {
  456.     pass P0
  457.     {        
  458.         Sampler[0] = <RenderTarget>;
  459.  
  460.         PixelShader = <ps11ShowAlpha>;
  461.     }
  462. }
  463.  
  464. //
  465. // Technique "ShowUnmodified" - display the original unblurred image
  466. // 
  467. technique ShowUnmodified
  468. {
  469.     pass P0
  470.     {        
  471.         Sampler[0] = <RenderTarget>;
  472.  
  473.         PixelShader = <ps11ShowUnmodified>;
  474.     }
  475. }