|
|
发表于 2007-7-16 18:45:00
|
显示全部楼层
Re:不用shader可以用法线贴图吗
我也在搞shader版的法线贴图,没有书,只有代码,对切线空间转置变换不理解。
以下是部分代码:
OutputVS NormalMapVS(float3 posL : POSITION0,
float3 tangentL : TANGENT0,
float3 binormalL : BINORMAL0,
float3 normalL : NORMAL0,
float2 tex0 : TEXCOORD0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;
// Build TBN-basis.
float3x3 TBN;
TBN[0] = tangentL;
TBN[1] = binormalL;
TBN[2] = normalL;
// Matrix transforms from object space to tangent space.
float3x3 toTangentSpace = transpose(TBN); //就是这里不明白。
// Transform eye position to local space.
float3 eyePosL = mul(float4(gEyePosW, 1.0f), gWorldInv);
// Transform to-eye vector to tangent space.
float3 toEyeL = eyePosL - posL;
outVS.toEyeT = mul(toEyeL, toTangentSpace);
// Transform light direction to tangent space.
float3 lightDirL = mul(float4(gLight.dirW, 0.0f), gWorldInv).xyz;
outVS.lightDirT = mul(lightDirL, toTangentSpace);
// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);
// Pass on texture coordinates to be interpolated in rasterization.
outVS.tex0 = tex0;
// Done--return the output.
return outVS;
}
float4 NormalMapPS(float3 toEyeT : TEXCOORD0,
float3 lightDirT : TEXCOORD1,
float2 tex0 : TEXCOORD2) : COLOR
{
// Interpolated normals can become unnormal--so normalize.
toEyeT = normalize(toEyeT);
lightDirT = normalize(lightDirT);
// Light vector is opposite the direction of the light.
float3 lightVecT = -lightDirT;
// Sample normal map.
float3 normalT = tex2D(NormalMapS, tex0);
// Expand from [0, 1] compressed interval to true [-1, 1] interval.
normalT = 2.0f*normalT - 1.0f;
// Make it a unit vector.
normalT = normalize(normalT);
// Compute the reflection vector.
float3 r = reflect(-lightVecT, normalT);
// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEyeT), 0.0f), gMtrl.specPower);
// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(lightVecT, normalT), 0.0f);
// If the diffuse light intensity is low, kill the specular lighting term.
// It doesn't look right to add specular light when the surface receives
// little diffuse light.
if(s <= 0.0f)
t = 0.0f;
// Compute the ambient, diffuse and specular terms separatly.
float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
float3 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgb;
float3 ambient = gMtrl.ambient*gLight.ambient;
// Get the texture color.
float4 texColor = tex2D(TexS, tex0);
// Combine the color from lighting with the texture color.
float3 color = (ambient + diffuse)*texColor.rgb + spec;
// Output the color and the alpha.
return float4(color, gMtrl.diffuse.a*texColor.a);
} |
|