346 lines
9.4 KiB
HLSL
346 lines
9.4 KiB
HLSL
|
//-----------------------------------------------------------------------------
|
||
|
// SkinnedEffect.fx
|
||
|
//
|
||
|
// Microsoft XNA Community Game Platform
|
||
|
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
#include "Macros.fxh"
|
||
|
|
||
|
#define SKINNED_EFFECT_MAX_BONES 72
|
||
|
|
||
|
|
||
|
DECLARE_TEXTURE(Texture, 0);
|
||
|
|
||
|
|
||
|
BEGIN_CONSTANTS
|
||
|
|
||
|
float4 DiffuseColor _vs(c0) _ps(c1) _cb(c0);
|
||
|
float3 EmissiveColor _vs(c1) _ps(c2) _cb(c1);
|
||
|
float3 SpecularColor _vs(c2) _ps(c3) _cb(c2);
|
||
|
float SpecularPower _vs(c3) _ps(c4) _cb(c2.w);
|
||
|
|
||
|
float3 DirLight0Direction _vs(c4) _ps(c5) _cb(c3);
|
||
|
float3 DirLight0DiffuseColor _vs(c5) _ps(c6) _cb(c4);
|
||
|
float3 DirLight0SpecularColor _vs(c6) _ps(c7) _cb(c5);
|
||
|
|
||
|
float3 DirLight1Direction _vs(c7) _ps(c8) _cb(c6);
|
||
|
float3 DirLight1DiffuseColor _vs(c8) _ps(c9) _cb(c7);
|
||
|
float3 DirLight1SpecularColor _vs(c9) _ps(c10) _cb(c8);
|
||
|
|
||
|
float3 DirLight2Direction _vs(c10) _ps(c11) _cb(c9);
|
||
|
float3 DirLight2DiffuseColor _vs(c11) _ps(c12) _cb(c10);
|
||
|
float3 DirLight2SpecularColor _vs(c12) _ps(c13) _cb(c11);
|
||
|
|
||
|
float3 EyePosition _vs(c13) _ps(c14) _cb(c12);
|
||
|
|
||
|
float3 FogColor _ps(c0) _cb(c13);
|
||
|
float4 FogVector _vs(c14) _cb(c14);
|
||
|
|
||
|
float4x4 World _vs(c19) _cb(c15);
|
||
|
float3x3 WorldInverseTranspose _vs(c23) _cb(c19);
|
||
|
|
||
|
float4x3 Bones[SKINNED_EFFECT_MAX_BONES] _vs(c26) _cb(c22);
|
||
|
|
||
|
MATRIX_CONSTANTS
|
||
|
|
||
|
float4x4 WorldViewProj _vs(c15) _cb(c0);
|
||
|
|
||
|
END_CONSTANTS
|
||
|
|
||
|
|
||
|
#include "Structures.fxh"
|
||
|
#include "Common.fxh"
|
||
|
#include "Lighting.fxh"
|
||
|
|
||
|
|
||
|
void Skin(inout VSInputNmTxWeights vin, uniform int boneCount)
|
||
|
{
|
||
|
float4x3 skinning = 0;
|
||
|
|
||
|
[unroll]
|
||
|
for (int i = 0; i < boneCount; i++)
|
||
|
{
|
||
|
skinning += Bones[vin.Indices[i]] * vin.Weights[i];
|
||
|
}
|
||
|
|
||
|
vin.Position.xyz = mul(vin.Position, skinning);
|
||
|
vin.Normal = mul(vin.Normal, (float3x3)skinning);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: vertex lighting, one bone.
|
||
|
VSOutputTx VSSkinnedVertexLightingOneBone(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 1);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: vertex lighting, two bones.
|
||
|
VSOutputTx VSSkinnedVertexLightingTwoBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 2);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: vertex lighting, four bones.
|
||
|
VSOutputTx VSSkinnedVertexLightingFourBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 4);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: one light, one bone.
|
||
|
VSOutputTx VSSkinnedOneLightOneBone(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 1);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: one light, two bones.
|
||
|
VSOutputTx VSSkinnedOneLightTwoBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 2);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: one light, four bones.
|
||
|
VSOutputTx VSSkinnedOneLightFourBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputTx vout;
|
||
|
|
||
|
Skin(vin, 4);
|
||
|
|
||
|
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
|
||
|
SetCommonVSOutputParams;
|
||
|
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: pixel lighting, one bone.
|
||
|
VSOutputPixelLightingTx VSSkinnedPixelLightingOneBone(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputPixelLightingTx vout;
|
||
|
|
||
|
Skin(vin, 1);
|
||
|
|
||
|
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
|
||
|
SetCommonVSOutputParamsPixelLighting;
|
||
|
|
||
|
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: pixel lighting, two bones.
|
||
|
VSOutputPixelLightingTx VSSkinnedPixelLightingTwoBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputPixelLightingTx vout;
|
||
|
|
||
|
Skin(vin, 2);
|
||
|
|
||
|
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
|
||
|
SetCommonVSOutputParamsPixelLighting;
|
||
|
|
||
|
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Vertex shader: pixel lighting, four bones.
|
||
|
VSOutputPixelLightingTx VSSkinnedPixelLightingFourBones(VSInputNmTxWeights vin)
|
||
|
{
|
||
|
VSOutputPixelLightingTx vout;
|
||
|
|
||
|
Skin(vin, 4);
|
||
|
|
||
|
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
|
||
|
SetCommonVSOutputParamsPixelLighting;
|
||
|
|
||
|
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
|
||
|
vout.TexCoord = vin.TexCoord;
|
||
|
|
||
|
return vout;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Pixel shader: vertex lighting.
|
||
|
float4 PSSkinnedVertexLighting(PSInputTx pin) : SV_Target0
|
||
|
{
|
||
|
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
|
||
|
|
||
|
AddSpecular(color, pin.Specular.rgb);
|
||
|
ApplyFog(color, pin.Specular.w);
|
||
|
|
||
|
return color;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Pixel shader: vertex lighting, no fog.
|
||
|
float4 PSSkinnedVertexLightingNoFog(PSInputTx pin) : SV_Target0
|
||
|
{
|
||
|
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
|
||
|
|
||
|
AddSpecular(color, pin.Specular.rgb);
|
||
|
|
||
|
return color;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Pixel shader: pixel lighting.
|
||
|
float4 PSSkinnedPixelLighting(PSInputPixelLightingTx pin) : SV_Target0
|
||
|
{
|
||
|
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
|
||
|
|
||
|
float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
|
||
|
float3 worldNormal = normalize(pin.NormalWS);
|
||
|
|
||
|
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
|
||
|
|
||
|
color.rgb *= lightResult.Diffuse;
|
||
|
|
||
|
AddSpecular(color, lightResult.Specular);
|
||
|
ApplyFog(color, pin.PositionWS.w);
|
||
|
|
||
|
return color;
|
||
|
}
|
||
|
|
||
|
|
||
|
VertexShader VSArray[9] =
|
||
|
{
|
||
|
compile vs_2_0 VSSkinnedVertexLightingOneBone(),
|
||
|
compile vs_2_0 VSSkinnedVertexLightingTwoBones(),
|
||
|
compile vs_2_0 VSSkinnedVertexLightingFourBones(),
|
||
|
|
||
|
compile vs_2_0 VSSkinnedOneLightOneBone(),
|
||
|
compile vs_2_0 VSSkinnedOneLightTwoBones(),
|
||
|
compile vs_2_0 VSSkinnedOneLightFourBones(),
|
||
|
|
||
|
compile vs_2_0 VSSkinnedPixelLightingOneBone(),
|
||
|
compile vs_2_0 VSSkinnedPixelLightingTwoBones(),
|
||
|
compile vs_2_0 VSSkinnedPixelLightingFourBones(),
|
||
|
};
|
||
|
|
||
|
|
||
|
int VSIndices[18] =
|
||
|
{
|
||
|
0, // vertex lighting, one bone
|
||
|
0, // vertex lighting, one bone, no fog
|
||
|
1, // vertex lighting, two bones
|
||
|
1, // vertex lighting, two bones, no fog
|
||
|
2, // vertex lighting, four bones
|
||
|
2, // vertex lighting, four bones, no fog
|
||
|
|
||
|
3, // one light, one bone
|
||
|
3, // one light, one bone, no fog
|
||
|
4, // one light, two bones
|
||
|
4, // one light, two bones, no fog
|
||
|
5, // one light, four bones
|
||
|
5, // one light, four bones, no fog
|
||
|
|
||
|
6, // pixel lighting, one bone
|
||
|
6, // pixel lighting, one bone, no fog
|
||
|
7, // pixel lighting, two bones
|
||
|
7, // pixel lighting, two bones, no fog
|
||
|
8, // pixel lighting, four bones
|
||
|
8, // pixel lighting, four bones, no fog
|
||
|
};
|
||
|
|
||
|
|
||
|
PixelShader PSArray[3] =
|
||
|
{
|
||
|
compile ps_2_0 PSSkinnedVertexLighting(),
|
||
|
compile ps_2_0 PSSkinnedVertexLightingNoFog(),
|
||
|
compile ps_2_0 PSSkinnedPixelLighting(),
|
||
|
};
|
||
|
|
||
|
|
||
|
int PSIndices[18] =
|
||
|
{
|
||
|
0, // vertex lighting, one bone
|
||
|
1, // vertex lighting, one bone, no fog
|
||
|
0, // vertex lighting, two bones
|
||
|
1, // vertex lighting, two bones, no fog
|
||
|
0, // vertex lighting, four bones
|
||
|
1, // vertex lighting, four bones, no fog
|
||
|
|
||
|
0, // one light, one bone
|
||
|
1, // one light, one bone, no fog
|
||
|
0, // one light, two bones
|
||
|
1, // one light, two bones, no fog
|
||
|
0, // one light, four bones
|
||
|
1, // one light, four bones, no fog
|
||
|
|
||
|
2, // pixel lighting, one bone
|
||
|
2, // pixel lighting, one bone, no fog
|
||
|
2, // pixel lighting, two bones
|
||
|
2, // pixel lighting, two bones, no fog
|
||
|
2, // pixel lighting, four bones
|
||
|
2, // pixel lighting, four bones, no fog
|
||
|
};
|
||
|
|
||
|
|
||
|
int ShaderIndex = 0;
|
||
|
|
||
|
|
||
|
Technique SkinnedEffect
|
||
|
{
|
||
|
Pass
|
||
|
{
|
||
|
VertexShader = (VSArray[VSIndices[ShaderIndex]]);
|
||
|
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
||
|
}
|
||
|
}
|