?/TD>
Microsoft DirectX 9.0

Apply a Glow


This example contains two techniques. This first technique, called GlowOnly, applies a glow to an object. GlowOnly uses the function Unskinned to calculate lighting and copy the texture coordinates. The Unskinned function also uses the helper function, TransformUnskinned, to transform position and normal data.

The second technique, called GlowAndNormal, contains two passes. The first pass draws the object normally and the second pass draws an outline.

This example is representative of a high level language sample, it does not compile as shown below.

Example

// 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;
   }
}



© 2002 Microsoft Corporation. All rights reserved.