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