HLSL normal map code

2019-04-14 11:59发布

一般来说normalMap都是从高模获得,用来使低模渲染获得更好的颜 {MOD}效果
帖上一段凹凸贴图的hlsl,不一定要用shader实现,看懂原理就行了

struct VS_INPUT
{
float4 position  : POSITION;
float3 normal    : NORMAL;
float3 tangent   : TANGENT;
float2 texcoord0 : TEXCOORD0;
};

struct VS_OUTPUT
{
float4 position : POSITION;
float3 color0   : COLOR0;
float2 texcoord0 : TEXCOORD0;
};

VS_OUTPUT VS_PerpixelDiffuseLighting( VS_INPUT In )
{
VS_OUTPUT Out;
Out.position = mul( In.position, matWorldViewProj );
//Out.position.z -= 0.01;
//把光照方向转到世界坐标中,这样可以避免把normal图中得到的每点的normal值
//都转到屏幕坐标上来,节约运算
float3 worldNormal = normalize(mul( In.normal, (float3x3)matWorld ));

float3 worldTangent = normalize(mul( In.tangent, (float3x3)matWorld ));
float3 worldBinormal = cross( worldNormal, worldTangent );
float3 L = normalize( lightDir.xyz );
float3x3 tangentBase = { worldTangent, worldBinormal, worldNormal };
float3 LInTangent = mul( tangentBase, -L );

//颜 {MOD}值只能是0-1.normal可以是-1-1,这里要进行一次转化
Out.color0 = float4( 0.5 * LInTangent + 0.5, 1 );
Out.texcoord0 = In.texcoord0;
return Out;
}

float4 PS_PerpixelDiffuseLighting( VS_OUTPUT In ) : COLOR
{
//取得normal图上每点的normal
float3 pixelNormal = tex2D( sNormal, In.texcoord0 );
// 2*(pixelNormal-0.5) 是把0-1转化为-1到1
//这一步就是normalmap的使用了,把光线方向与normal dot一下

float diffuse = dot( 2*(In.color0-0.5), 2*(pixelNormal-0.5) );
float3 texTerm = tex2D( sDiffuse, In.texcoord0 );
float4 finalColor = { texTerm*diffuse, 1 };
return finalColor;
}

这样作的最终目标是让低模能够获得高模一样的光照效果