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

  1. //
  2. // Metallic Flakes Shader
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. //
  5. // Note: This effect file works with EffectEdit.
  6. //
  7. // NOTE:
  8. // The metallic surface consists of 2 layers - 
  9. // 1. a polished layer of wax on top (contributes a smooth specular reflection and an environment mapped reflection with a Fresnel term), and 
  10. // 2. a blue metallic layer with a sprinkling of gold metallic flakes underneath
  11.  
  12.  
  13. // sparkle parameters
  14. #define SPRINKLE    0.3
  15. #define SCATTER     0.3
  16.  
  17. #define VOLUME_NOISE_SCALE  10
  18.  
  19. // scene info (EffectEdit specific controls)
  20. string XFile = "bigship1.x";
  21. int    BCLR  = 0xff404080;
  22.  
  23. // textures
  24. texture EnvironmentMap 
  25.     string type = "CUBE"; 
  26.     string name = "lobbycube.dds"; 
  27. >;
  28.  
  29. // procedural texture that contains a normal map used for the metal sparkles
  30. texture NoiseMap 
  31.     string type = "VOLUME"; 
  32.     string function = "GenerateSparkle"; 
  33.     int width = 32;
  34.     int height = 32;
  35.     int depth = 32; 
  36. >;
  37.  
  38. // transformations
  39. float4x3 WorldView  : WORLDVIEW;
  40. float4x4 Projection : PROJECTION;
  41.  
  42. // light direction (view space)
  43. float3 L < string UIDirectional = "Light Direction"; > = normalize(float3(-0.397f, -0.397f, 0.827f));
  44.  
  45. // light intensity
  46. float4 I_a = { 0.3f, 0.3f, 0.3f, 1.0f };    // ambient
  47. float4 I_d = { 1.0f, 1.0f, 1.0f, 1.0f };    // diffuse
  48. float4 I_s = { 0.7f, 0.7f, 0.7f, 1.0f };    // specular
  49.  
  50. // material reflectivity
  51. float4 k_a : MATERIALAMBIENT = { 0.2f, 0.2f, 0.2f, 1.0f };    // ambient  (metal)
  52. float4 k_d : MATERIALDIFFUSE = { 0.1f, 0.1f, 0.9f, 1.0f };    // diffuse  (metal)
  53. float4 k_s = { 0.4f, 0.3f, 0.1f, 1.0f };    // specular (metal)
  54. float4 k_r = { 0.7f, 0.7f, 0.7f, 1.0f };    // specular (wax)
  55.  
  56. // function used to fill the volume noise texture
  57. float4 GenerateSparkle(float3 Pos : POSITION) : COLOR
  58. {
  59.     float4 Noise = (float4)0;
  60.  
  61.     // scatter the normal (in vertex space) based on SCATTER
  62.     Noise.rgb = float3(1 - SCATTER * abs(noise(Pos * 500)), SCATTER * noise((Pos + 1) * 500), SCATTER * noise((Pos + 2) * 500));
  63.     Noise.rgb = normalize(Noise.rgb);
  64.  
  65.     // set the normal to zero with a probability based on SPRINKLE
  66.     if (SPRINKLE < abs(noise(Pos * 600)))
  67.         Noise.rgb = 0;
  68.  
  69.     // bias the normal
  70.     Noise.rgb = (Noise.rgb + 1)/2;
  71.  
  72.     // diffuse noise
  73.     Noise.w = abs(noise(Pos * 500)) * 0.0 + 1.0;
  74.  
  75.     return Noise;
  76. }
  77.  
  78. struct VS_OUTPUT
  79. {
  80.     float4 Position   : POSITION;
  81.     float3 Diffuse    : COLOR0;
  82.     float3 Specular   : COLOR1;               
  83.     float3 Reflection : TEXCOORD0;               
  84.     float3 NoiseCoord : TEXCOORD1;               
  85.     float3 Glossiness : TEXCOORD2;               
  86.     float3 HalfVector : TEXCOORD3;
  87. };
  88.  
  89. // vertex shader
  90. VS_OUTPUT VS(    
  91.     float3 Position : POSITION,
  92.     float3 Normal   : NORMAL, 
  93.     float3 Tangent  : TANGENT)
  94. {
  95.     VS_OUTPUT Out = (VS_OUTPUT)0;
  96.  
  97.     L = -L;
  98.  
  99.     float3 P = mul(float4(Position, 1), (float4x3)WorldView);   // position (view space)
  100.     float3 N = normalize(mul(Normal, (float3x3)WorldView));     // normal (view space)
  101.     float3 T = normalize(mul(Tangent, (float3x3)WorldView));    // tangent (view space)
  102.     float3 B = cross(N, T);                                     // binormal (view space)
  103.     float3 R = normalize(2 * dot(N, L) * N - L);                // reflection vector (view space)
  104.     float3 V = -normalize(P);                                   // view direction (view space)
  105.     float3 G = normalize(2 * dot(N, V) * N - V);                // glance vector (view space)
  106.     float3 H = normalize(L + V);                                // half vector (view space)
  107.     float  f = 0.5 - dot(V, N); f = 1 - 4 * f * f;              // fresnel term
  108.  
  109.     // position (projected)
  110.     Out.Position = mul(float4(P, 1), Projection);             
  111.  
  112.     // diffuse + ambient (metal)
  113.     Out.Diffuse = I_a * k_a + I_d * k_d * max(0, dot(N, L)); 
  114.  
  115.     // specular (wax)
  116.     Out.Specular  = saturate(dot(H, N));
  117.     Out.Specular *= Out.Specular;
  118.     Out.Specular *= Out.Specular;
  119.     Out.Specular *= Out.Specular;
  120.     Out.Specular *= Out.Specular;                              
  121.     Out.Specular *= Out.Specular;                        
  122.     Out.Specular *= k_r;                                       
  123.  
  124.      // glossiness (wax)
  125.     Out.Glossiness = f * k_r;
  126.  
  127.     // transform half vector into vertex space
  128.     Out.HalfVector = float3(dot(H, N), dot(H, B), dot(H, T));   
  129.     Out.HalfVector = (1 + Out.HalfVector) / 2;  // bias
  130.  
  131.     // environment cube map coordinates
  132.     Out.Reflection = float3(-G.x, G.y, -G.z);                   
  133.  
  134.     // volume noise coordinates
  135.     Out.NoiseCoord = Position * VOLUME_NOISE_SCALE;             
  136.  
  137.     return Out;
  138. }
  139.  
  140. // samplers
  141. sampler Environment = sampler_state
  142.     Texture = (EnvironmentMap);
  143.     MipFilter = LINEAR;
  144.     MinFilter = LINEAR;
  145.     MagFilter = LINEAR;
  146. };
  147.  
  148. sampler SparkleNoise = sampler_state
  149.     Texture = (NoiseMap);
  150.     MipFilter = LINEAR; 
  151.     MinFilter = LINEAR;
  152.     MagFilter = LINEAR;
  153. };
  154.  
  155. // pixel shader
  156. float4 PS(VS_OUTPUT In) : COLOR
  157. {   
  158.     float4 Color = (float4)0;
  159.     float3 Diffuse, Specular, Gloss, Sparkle;
  160.  
  161.     // volume noise
  162.     float4 Noise = tex3D(SparkleNoise, In.NoiseCoord);
  163.  
  164.     // noisy diffuse of metal
  165.     Diffuse = In.Diffuse * Noise.a;
  166.     
  167.     // glossy specular of wax
  168.     Specular  = In.Specular;
  169.     Specular *= Specular;
  170.     Specular *= Specular;
  171.     
  172.     // glossy reflection of wax 
  173.     Gloss = texCUBE(Environment, In.Reflection) * saturate(In.Glossiness);              
  174.  
  175.     // specular sparkle of flakes
  176.     Sparkle  = saturate(dot((saturate(In.HalfVector) - 0.5) * 2, (Noise.rgb - 0.5) * 2));
  177.     Sparkle *= Sparkle;
  178.     Sparkle *= Sparkle;
  179.     Sparkle *= Sparkle;                                                                    
  180.     Sparkle *= k_s;      
  181.  
  182.     // combine the contributions
  183.     Color.rgb = Diffuse + Specular + Gloss + Sparkle;
  184.     Color.w   = 1;
  185.  
  186.     return Color;
  187. }  
  188.  
  189. // technique
  190. technique TMetallicFlakes
  191. {
  192.     pass P0
  193.     {
  194.         VertexShader = compile vs_1_1 VS();
  195.         PixelShader  = compile ps_1_1 PS();
  196.  
  197.         AlphaBlendEnable = FALSE;
  198.         CullMode         = NONE;
  199.     }
  200. }
  201.  
  202.