Normal Map HLSL实现

本文介绍了一种在DirectX平台上实现Tangent Space Normal Mapping的技术细节。通过顶点着色器与像素着色器的配合,实现了光照效果的真实感增强。文章详细展示了着色器代码,包括如何构建切线空间矩阵、读取法线贴图以及计算光照强度。

Normal Map 分为Object Space 和Tangent Space。下面是Tagent Space的实现。

贴上Normal Map在DX 上的实现。

sampler NormalMap =
sampler_state
{
    Texture = <g_Texture1>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

struct VS_INPUT_Mesh_N
{
    float4 Position     : POSITION;
    float3 Normal       : NORMAL;
    float2 Tex0   : TEXCOORD0;
    float3 Tangent      : TANGENT;
    float3 Binormal     : BINORMAL;
   
};

struct VS_OUTPUT_Mesh_N
{
    float4 Position   : POSITION;
    float2 Tex0    : TEXCOORD0;
    float3 Normal     : TEXCOORD1;
    float3 Tangent    : TEXCOORD2;
    float3 Binormal   : TEXCOORD3;
    float3 VertexPos   : TEXCOORD4;
};

VS_OUTPUT_Mesh_N VShaderMeshNormalMap( VS_INPUT_Mesh_N In )
{
    VS_OUTPUT_Mesh_N Out;
    Out.Position = 0;
    Out.Normal = 0;
    Out.Tangent = 0;
    Out.Binormal = 0;
    Out.VertexPos = In.Position.xyz;
   
    float4 position =  mul(In.Position, g_mWorld);
    Out.Position = mul(float4(position.xyz, 1.0f), g_mViewProj);
   
    Out.Normal = normalize(mul(In.Normal, (float3x3)g_mWorld));   // normal (world space)
    Out.Tangent = normalize(mul(-In.Tangent, (float3x3)g_mWorld));  //maya exporter perhaps "-"
    Out.Binormal = normalize(mul(-In.Binormal, (float3x3)g_mWorld));
   
    //Out.Binormal = cross( Out.Normal, Out.Tangent );
   
    // Pass the texture coordinate
    Out.Tex0 = In.Tex0;
       
    return Out;
}

PS_OUTPUT PShaderMeshNormalMap( VS_OUTPUT_Mesh_N In)
{
 PS_OUTPUT Out; 
 
 float4 diffuse_color = tex2D(DiffuseMap, In.Tex0);
 float3 normal_map = tex2D( NormalMap, In.Tex0 ).xyz;
    
    float3 L = normalize(g_LightDir[0].xyz);
    float3 V = normalize ( g_vCameraPosition - In.VertexPos ) ;
    float3 H = normalize ( V + L ) ;
   
    float3 N = normalize(normal_map . xyz/* * 2.0f - 0.5f*/) ;
    float3x3 TBNMatrix = float3x3(In.Tangent, In.Binormal, In.Normal);
    N = normalize(mul(N, TBNMatrix));
   
 float intensity = saturate( dot(N, L) );
 float3 ambient = g_LightAmbient;
 float3 diffuse = intensity * g_LightDiffuse[0];
 float3 light = lerp( ambient + diffuse, float3(1,1,1), emissive ) ;
 float3 specular_light = pow(max(dot(H , N) , 0.001f) , g_MaterialShininess) * g_LightDiffuse[0] ;
 
 Out.RGBColor.xyz = diffuse_color.xyz * light + specular_light;
    Out.RGBColor.w = diffuse_color.w;
   
 return Out;
}

technique MeshNormalMap
{
    pass P0
    { 
        VertexShader = compile vs_2_0 VShaderMeshNormalMap();
        PixelShader  = compile ps_2_0 PShaderMeshNormalMap();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值