グローの適用
グローの適用
この例では、2 つのテクニックを使用している。1 番目のテクニックは GlowOnly といい、オブジェクトにグローを適用する。GlowOnly は、Unskinned 関数を使ってライトを計算し、テクスチャ座標をコピーする。さらに Unskinned 関数は、ヘルパー関数 TransformUnskinned を使って、位置座標および法線データをトランスフォームする。
2 番目のテクニックは GlowAndNormal といい、2 つのパスから構成される。第 1 パスでオブジェクトを通常どおり描画し、第 2 パスでアウトラインを描画する。
この例は、上位レベル言語のサンプルを表し、次に示す例ではコンパイルは行わない。
例
// effect.fx texture tex0 < string name = "tiger.bmp"; >; texture tex1 < string name = "banana.bmp"; >; string XFile = "tiger.x"; // Model to load string BIMG = "lake.bmp"; // Background image DWORD BCLR = 0xff202080; // Background color (if no image) // Declare the required matrices with the appropriate semantics // so that the viewer can supply the necessary matrix information. float4x4 mProjection :PROJECTION; float4x3 mWorldView :WORLDVIEW; float4x4 mViewProjection :VIEWPROJECTION; // Declare data used by the shaders that the application can modify. float3 vLightDirection = {0.0, 0.0, -1.0 }; float vDisplace = 0.015; float4 vGlowColor = { 0.5, 0.2, 0.2, 1.0 }; float4 vGlowAmbient = { 0.2, 0.2, 0.0, 0.0 }; // Set up an output structure defining the output to the pixel shader. struct VS_OUTPUT_TEXCOORD0 { float4 Position :POSITION; float4 Diffuse :COLOR; float2 Texture0 :TEXCOORD0; }; // Helper function to transform position/normal into view space void TransformUnskinned ( float4 vPos, float3 vNormal, float3 vTransformedPosition, float3 vTransformedNormal ) { // Transform the position into view space vTransformedPosition = mul(vPos, mWorldView); // Transform the normal into view space (just use the upper 3x3 of WorldView) vTransformedNormal = mul(vNormal, (float3x3)mWorldView); } // Draws unskinned object with one texture and one directional light. VS_OUTPUT_TEXCOORD0 Unskinned ( float4 vPos :POSITION, float3 vNormal :NORMAL, float2 vTexCoord0 :TEXCOORD0 ) { float3 vTransformedPosition = {0,0,0}; float3 vTransformedNormal = {0,0,0}; VS_OUTPUT_TEXCOORD0 Output; float fDot; // Transform the position/normal into view space. TransformUnskinned(vPos, vNormal, vTransformedPosition, vTransformedNormal); // Calculate amount of light from the one light direction. fDot = dot(vTransformedNormal, vLightDirection); // Transform view space position into screen space. Output.Position = mul(float4(vTransformedPosition, 1.0), mProjection); // Multiple amount of light times light color. // Note:Color could be negative with this equation, but will be // clamped to zero before pixel shader. Output.Diffuse = float4(1.0f, 1.0f, 1.0f, 1.0f) * fDot; // Just copy the texture coordinate through. Output.Texture0 = vTexCoord0; return Output; } // Declare the output of the GlowSkinned vertex shader to the pixel shader. struct VS_OUTPUT { float4 Position :POSITION; float4 Diffuse :COLOR; }; // Draws a transparent hull of the unskinned object. VS_OUTPUT GlowUnskinned ( float4 vPos :POSITION, float3 vNormal :NORMAL ) { float3 vTransformedPosition = {0,0,0}; float3 vTransformedNormal = {0,0,0}; VS_OUTPUT Output; float fPower; // For standard "glow" this is the view direction. float3 vGlowAxis = float3(0, 0, 1); // Transform the position and normal into world space. TransformUnskinned(vPos, vNormal, vTransformedPosition, vTransformedNormal); // Displace the position by the normal, so that the glow will not // overlap the non-glowed version. vTransformedPosition += vTransformedNormal * vDisplace; // The glow is determined by the angle between the normal and the glow axis. // This ends up being similar to a fresnel approximation. fPower = dot(vTransformedNormal, vGlowAxis); fPower = 1.0f - fPower * fPower; fPower *= fPower; // Transform position into screen space from view space. Output.Position = mul(float4(vTransformedPosition, 1.0), mProjection); // Output color is the compute power times the glow color. Output.Diffuse = vGlowColor * fPower + vGlowAmbient; return Output; } // first technique - unskinned // first pass draw the object normally // second pass draw the outline technique GlowOnly { pass P1 { // Generate a 1_1 vertex shader to draw the outline of the object. VertexShader = compile vs_1_1 GlowUnskinned(); Texture[0] = NULL; // Enable alpha blending AlphaBlendEnable = True; SrcBlend = One; DestBlend = One; // Set up TSS stages to just use the diffuse color. ColorOp[0] = SelectArg2; ColorArg2[0] = Diffuse; AlphaOp[0] = SelectArg2; AlphaArg2[0] = Diffuse; ColorOp[1] = Disable; AlphaOp[1] = Disable; } } // First technique - unskinned // First pass draw the object normally // Second pass draw the outline technique GlowAndNormal { pass P0 { // Generate a 1_1 vertex shader for unskinned // single texture/one directional light. VertexShader = compile vs_1_1 Unskinned(); // Set up texture stage info for single texture. ColorOp[0] = Modulate; ColorArg1[0] = Texture; ColorArg2[0] = Current; AlphaOp[0] = Disable; // Set texture filtering. MinFilter[0] = Linear; MagFilter[0] = Linear; MipFilter[0] = Point; // Set texture into stage 0. Texture[0] = (tex0); // Disable Stage1. ColorOp[1] = Disable; AlphaOp[1] = Disable; } pass P1 { // Generate a 1_1 vertex shader to draw the outline of the object. VertexShader = compile vs_1_1 GlowUnskinned(); Texture[0] = NULL; // Enable alpha blending. AlphaBlendEnable = True; SrcBlend = One; DestBlend = One; // Set up TSS stages to just use the diffuse color. ColorOp[0] = SelectArg2; ColorArg2[0] = Diffuse; AlphaOp[0] = SelectArg2; AlphaArg2[0] = Diffuse; ColorOp[1] = Disable; AlphaOp[1] = Disable; } }