?/TD>
Microsoft DirectX 9.0

Skinned Displacement with Per Pixel Lighting


This example effect uses the high level language to perform skining using displacement mapping. It also includes per-pixel lighting.

Example

//
// Example effect: Skinned Displacement, with Per-Pixel Lighting
// Copyright (c) 2001 Microsoft Corporation. All rights reserved.
//


//----------------------------------------------------------------------------
// Types 
//----------------------------------------------------------------------------

struct VS_INPUT
{
    float4 vPosition        : POSITION;
    float3 vBlendWeights    : BLENDWEIGHT;
    int4   vBlendIndices    : BLENDINDICES;
    float3 vNormal          : NORMAL;
    float2 vTexCoords       : TEXCOORD0;
    float3 vTangent         : TANGENT;
    float  fFlip            : TEXCOORD1;
    float  fDisplacement    : TEXCOORD2;   
};


struct VS_OUTPUT
{
    float4  vPosition       : POSITION;
    float4  vTexCoord0      : TEXCOORD0;
    float4  vTexCoord1      : TEXCOORD1;
    float3  vDiffuse        : COLOR0;
    float3  vSpecular       : COLOR1;
};


//----------------------------------------------------------------------------
// Global parameters 
//----------------------------------------------------------------------------

texture tDiffuse;                               // diffuse map
texture tNormal;                                // normal map
 
float4x3 mWorld[4];                             // world position transforms
float3x3 mNormal[4];                            // world normal transforms
float4x4 mViewProj;                             // view projection transform

float4 cAmbient  = { 0.3f, 0.3f, 0.3f, 1.0f };  // ambient color
float4 cDiffuse  = { 1.0f, 1.0f, 1.0f, 1.0f };  // diffuse color
float4 cSpecular = { 0.6f, 0.6f, 0.6f, 1.0f };  // specular color

float3 vDiffuse  = { 0.0f, 1.0f, 0.0f };         // diffuse direction
float3 vSpecular = { 0.0f, 0.0f, 0.0f };         // specular direction


//----------------------------------------------------------------------------
// Helper functions 
//----------------------------------------------------------------------------

static float3 cross(float3 a, float3 b)
{
    return a.yzx * b.zxy - b.yzx * a.zxy;
}


//----------------------------------------------------------------------------
// Shader body 
//----------------------------------------------------------------------------

VS_OUTPUT main(const VS_INPUT v)
{
    VS_OUTPUT o = (VS_OUTPUT) 0;

    // Compute last blend weight
    float fLastBlendWeight = 1 - dot(v.vBlendWeights, 1);


    // Skin position(to world space)    
    float3 vPosition = 
        mul(v.vPosition, mWorld[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vPosition, mWorld[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vPosition, mWorld[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vPosition, mWorld[v.vBlendIndices.w]) * fLastBlendWeight;


    // Skin normal (to world space)
    float3 vNormal =
        mul(v.vNormal, mNormal[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vNormal, mNormal[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vNormal, mNormal[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vNormal, mNormal[v.vBlendIndices.w]) * fLastBlendWeight;


    // Skin tangent (to world space)
    float3 vTangent =
        mul(v.vTangent, mNormal[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vTangent, mNormal[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vTangent, mNormal[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vTangent, mNormal[v.vBlendIndices.w]) * fLastBlendWeight;

    // Compute binormal
    float3 vBinormal = cross(vNormal, vTangent) * v.fFlip;        

    // Light direction (to vertex space)
    float3x3 mLight =  
        float3x3(vTangent.x, vBinormal.x, vNormal.x,
                 vTangent.y, vBinormal.y, vNormal.y, 
                 vTangent.z, vBinormal.z, vNormal.z);
    

    // Output stuff
    o.vPosition = mul(float4(vPosition + vNormal * v.fDisplacement, 1), 
                      mViewProj);    
    o.vDiffuse  = mul(vDiffuse, mLight) * 0.5 + 0.5;
    o.vSpecular = mul(vSpecular, mLight) * 0.5 + 0.5;
    o.vTexCoord0.xy = o.vTexCoord1.xy = v.vTexCoords.xy;

    return o;
}


//----------------------------------------------------------------------------
// Technique
//----------------------------------------------------------------------------

technique T0
{
    pass P0
    {
        // Vertex shader
        VertexShader = compile vs_2_0 main();


        // Pixel shader
        PixelShader =
            asm
            {
                ps_1_1
                tex t0
                tex t1

                // Specular
                dp3_sat r1, t1_bx2, v1_bx2
                dp3_x4  r0, t1_bx2, v0_bx2

                mul_sat r1, r1, r0
                mul_sat r1, r1, r1
                mul_sat r1, r1, c2

                // Diffuse + Ambient
                dp3_sat r0, t1_bx2, v0_bx2          
                mad_sat r0, r0, c1, c0
                mad_sat r0, r0, t0, r1
            };

        PixelShaderConstant1[0] = (cAmbient);
        PixelShaderConstant1[1] = (cDiffuse);
        PixelShaderConstant1[2] = (cSpecular);



        // Textures and filtering
        Texture[0]   = (tDiffuse);
        MinFilter[0] = LINEAR;
        MagFilter[0] = LINEAR;
        MipFilter[0] = LINEAR;

        Texture[1]   = (tNormal);
        MinFilter[1] = LINEAR;
        MagFilter[1] = LINEAR;
        MipFilter[1] = LINEAR;


        // Clip/Raster state
        CullMode = CW;
    }
}



© 2002 Microsoft Corporation. All rights reserved.