如果我们能时时刻刻都在学习,从观察、聆听、注视和行动中学习,那么你会发现,学习是不断进展,永无过去 | 学习技术不是发财之道 | 学习技术,因为崇尚科学与真理
SkinningMesh.fx#include "skin.vsh"
//----------- normal global value-----------------//extern matrix g_vMatrix;extern matrix g_pMatrix;extern matrix g_vpMatrix;extern vector g_eyePos;extern vector g_lightDir;
//------------ global value for skinned mesh----------//extern float4 g_lightDiffuse = { 0.6f, 0.6f, 0.6f, 1.0f};extern float4 g_materialAmbient : MATERIALAMBIENT = {0.1f, 0.1f, 0.1f, 1.0f};extern float4 g_materialDiffuse : MATERIALDIFFUSE = {0.8f, 0.8f, 0.8f, 1.0f};static const int MAX_MATRICES = 26;extern float4x3 g_mWorldMatrixArray[ MAX_MATRICES] : WORLDMATRIXARRAY;extern int g_curNumBones = 2;
struct VS_INPUT{ float4 pos : POSITION;
//---- for skinned mesh--- // float3 blendWeights : BLENDWEIGHT; float4 blendIndices : BLENDINDICES;
float3 nor : NORMAL; float3 tex : TEXCOORD0;};
struct VS_OUTPUT{ float4 pos : POSITION; float4 diffuse : COLOR; float2 tex : TEXCOORD0;};
VS_OUTPUT VS_SkinningMesh(VS_INPUT input){ VS_OUTPUT output = (VS_OUTPUT)0;
//---------- skinned mesh------------
float3 pos = 0.0f; float3 nor = 0.0f; float lastWeight = 0.0f;
VS_SKIN_INPUT vsi = { input.pos, input.blendWeights, input.blendIndices, input.nor }; VS_SKIN_OUTPUT vso = VS_Skin( vsi, g_curNumBones);
matrix vpMatrix = mul( g_vMatrix, g_pMatrix); output.pos = mul( float4( vso.vPos.xyz, 1.0f), vpMatrix);
nor = normalize( vso.vNor );
output.diffuse = float4( g_materialAmbient.xyz + saturate( dot( nor, g_lightDir.xyz ) ) * g_materialDiffuse.xyz, 1.0 );
output.tex = input.tex.xy;
return output;}
technique tec0{ pass pass0 { vertexShader = compile vs_2_0 VS_SkinningMesh(); }}
skin.vsh//// HLSL function for skinning a mesh. In your shader, you can #define // MATRIX_PALETTE_SIZE if desired, and then #include this file.// Copyright (c) 2000-2003 Microsoft Corporation. All rights reserved.//
#ifndef VS_SKIN_VSH#define VS_SKIN_VSH
//----------------------------------------------------------------------------// Global parameters //----------------------------------------------------------------------------
// Declare the 4x3 matrix palette. This is the array of bone matrices used in// skinning vertices.
// The palette size is 26 by default. This is sufficiently small for most // vs_1_1 shaders. Shaders targeted at vs_2_0 and above can set this higher// to accommondate more bones in a call. For example, tiny_anim.x has 35// bones, and so can be rendered in a single call if MATRIX_PALETTE_SIZE is// set to 35 or more.
// An HLSL shader can set MATRIX_PALETTE_SIZE_DEFAULT to a different value.// The calling app can also set it in the D3DXMACRO structure when compiling// the shader. The calling app can query the actual palette size by examining// MATRIX_PALETTE_SIZE (but changing it after compilation will not change the// palette size in the compiled shader, of course).
#ifndef MATRIX_PALETTE_SIZE_DEFAULT#define MATRIX_PALETTE_SIZE_DEFAULT 26#endif
const int MATRIX_PALETTE_SIZE = MATRIX_PALETTE_SIZE_DEFAULT;float4x3 amPalette[ MATRIX_PALETTE_SIZE_DEFAULT ];
//----------------------------------------------------------------------------// Shader body - VS_ Skin//----------------------------------------------------------------------------
// define the inputs -- caller must fill this, usually right from the VBstruct VS_SKIN_INPUT{ float4 vPos; float3 vBlendWeights; float4 vBlendIndices; float3 vNor;};
// return skinned position and normalstruct VS_SKIN_OUTPUT{ float4 vPos; float3 vNor;};
// call this function to skin VB position and normalVS_SKIN_OUTPUT VS_Skin( const VS_SKIN_INPUT vInput, int iNumBones ){ VS_SKIN_OUTPUT vOutput = (VS_SKIN_OUTPUT) 0;
float fLastWeight = 1.0; float fWeight; float afBlendWeights[ 3 ] = (float[ 3 ]) vInput.vBlendWeights; int aiIndices[ 4 ] = (int[ 4 ]) D3DCOLORtoUBYTE4( vInput.vBlendIndices ); for( int iBone = 0; (iBone < 3) && (iBone < iNumBones - 1); ++ iBone ) { fWeight = afBlendWeights[ iBone ]; fLastWeight -= fWeight; vOutput.vPos.xyz += mul( vInput.vPos, amPalette[ aiIndices[ iBone ] ] ) * fWeight; vOutput.vNor += mul( vInput.vNor, amPalette[ aiIndices[ iBone ] ] ) * fWeight; } vOutput.vPos.xyz += mul( vInput.vPos, amPalette[ aiIndices[ iNumBones - 1 ] ] ) * fLastWeight; vOutput.vNor += mul( vInput.vNor, amPalette[ aiIndices[ iNumBones - 1 ] ] ) * fLastWeight;
return vOutput;}
#endif // #ifndef VS_SKIN_VSH