法线贴图、视差贴图和普通着色

  在FX Composer里面实现的,先给大家看看效果对比图:

            

                                               视差贴图

                                                   

               

                                                   普通法线贴图

             

                                                       啥也没有的普通着色

 

           由于光源是动态移动的,所以会有所不同。不过已经可以明显的看出视差贴图比法线贴图更加具有立体感,当然它并不是真的有立体效果,而是我们的眼睛欺骗了我们。当我们把视角拉平的时候就能看出来它原来是平的:


        任何好处的获得都是要付出一定的代价的,相对法线贴图而言,视差贴图要多一些小步骤,当然,个人认为这并不能阻碍我们使用它。

        至于没有特殊效果的着色是最简单的,不过效果当然不能比哦~

下面是代码:

/**
* @brief a simple implement of normal-mapping and parallax-mapping.
* @author dongbo
* @date 2010.10.21
* @remarks http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2
*/
float4x4 matWorldViewProj : WorldViewProjection;
float4x4 matWorld         : World;
float4x4 matWorldIT       : WorldInverseTranspose;
float4x4 matViewIX        : ViewInverse;

struct VS_Input
{
float4 Position : POSITION;
float3 Normal   : NORMAL;
float3 Tangent  : TANGENT;
float2 Tex      : TEXCOORD0;
};

struct VS_Output
{
float4 Pos      : POSITION;
float3 Normal   : NORMAL;
float2 Tex      : TEXCOORD0;
float3 LightDir : TEXCOORD1;
float3 ViewDir  : TEXCOORD2;
};

float3 g_WorldLightPos : POSITION
<
string object = "pointlight";
string space  = "world";
string UIName = "Light0 Position";
>;

float  g_fSpeed<
string UIName = "Light Speed";
string UIWidget = "Slider";
float  UIMax = 10;
float  UIMin = 0.0f;
float  UIStep = 1.0f;
> = 0.0f;

float  g_fTime : TIME;

float  g_fSelfShadowParam<
string UIName   = "Self Shadow Param";
string UIWidget = "Slider";
float  UIMax    = 10;
float  UIMin    = 0.0;
float  UIStep   = 0.5;
> = 4.0f;

float  g_fSpecExp<
string UIName   = "Spec Exp";
string UIWidget = "Slider";
float  UIMax    = 100;
float  UIMin    = 0;
float  UIStep   = 1;
> = 20;

texture g_NormalTexture<
string UIName = "NormalTex";
string ResourceName = "normalMap.bmp";
>;
sampler g_NormalSmapler = sampler_state
{
Texture = <g_NormalTexture>;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Linear;
MipFilter = Linear;
MipFilter = Linear;   
};

texture g_HeightTexture<
string UIName = "HeightTex";
string ResourceName = "heightMap.bmp";
>;
sampler g_HeightSampler = sampler_state
{
Texture = <g_HeightTexture>;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Linear;
MipFilter = Linear;
MipFilter = Linear;   
};

texture g_ColorTexture<
string UIName = "ColorTex";
string ResourceName = "colorMap.bmp";
>;
sampler g_ColorSmapler = sampler_state
{
Texture = <g_ColorTexture>;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Linear;
MipFilter = Linear;
MipFilter = Linear;   
};

VS_Output mainVS( VS_Input input )
{
VS_Output output = (VS_Output)0;

output.Pos = mul( input.Position, matWorldViewProj );
output.Tex = input.Tex;

// copy from google. thanks google.
float3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul( input.Tangent, matWorld);
worldToTangentSpace[1] = mul( cross( input.Tangent, input.Normal ), matWorld );
worldToTangentSpace[2] = mul( input.Normal, matWorld );

float3 WorldPos  = mul( input.Position, matWorld ).xyz;
float3 WorldView = normalize( matViewIX[3].xyz - WorldPos );

output.ViewDir = normalize( mul( worldToTangentSpace, WorldView ) );

float3 WorldLightPos = g_WorldLightPos;
WorldLightPos.x += sin( g_fTime ) * g_fSpeed;
WorldLightPos.z += cos( g_fTime ) * g_fSpeed;

float3 LightDir = normalize( WorldLightPos - WorldPos );
output.LightDir = normalize( mul( worldToTangentSpace, LightDir ) );

float3 WorldNormal = mul( input.Normal, matWorldIT );
output.Normal = normalize( mul( worldToTangentSpace, WorldNormal ) );

return output;
}

float4 StandardLighting(
float3 Normal,
float3 LightDir,
float3 ViewDir,
float2 Tex
)
{
float4 color = tex2D( g_ColorSmapler, Tex );

LightDir = normalize( LightDir );
ViewDir  = normalize( ViewDir );
Normal   = normalize( Normal );

float4 diffuse = saturate( dot( Normal, LightDir ) );

float  fShadow = saturate( g_fSelfShadowParam * diffuse );

float3 Reflect = normalize( 2 * diffuse * Normal - LightDir );

float4 Spec    = min( pow( saturate( dot( Reflect, ViewDir ) ), g_fSpecExp ), color. a );

color = color * 0.5 + fShadow * ( color * diffuse + Spec );

return color;
}

float4 mainPS_Normal( VS_Output input ) : COLOR
{
float4 color = StandardLighting( input.Normal, input.LightDir, input.ViewDir, input.Tex );

return color;
}

float4 mainPS_NormalMapping( VS_Output input ) : COLOR
{
float4 color = {1.0f,1.0f,1.0f,1.0f};

float3 Normal = 2 * ( tex2D( g_NormalSmapler, input.Tex ) - 0.5 );

color = StandardLighting( Normal, input.LightDir, input.ViewDir, input.Tex );   

return color;
}

float g_Scale <
string UIName   = "Parallax Scale";
string UIWidget = "Slider";
float  UIMax    = 0.1f;
float  UIMin    = 0.0f;
float  UIStep   = 0.001f;
> = 0.0f;

float g_Bias <
string UIName   = "Parallax Bias";
string UIWidget = "Slider";
float  UIMax    = 0.1f;
float  UIMin    = -0.1f;
float  UIStep   = 0.001f;
> = 0.0f;

float4 mainPs_Parallaxmapping( VS_Output input ) : COLOR
{
float4 color = {1.0f,1.0f,1.0f,1.0f};

float4 height = g_Scale * tex2D( g_HeightSampler, input.Tex ) - g_Bias;

float2 texNew= input.ViewDir * height + input.Tex;

float3 Normal = 2 * ( tex2D( g_NormalSmapler, texNew ) - 0.5 );

color = StandardLighting( Normal, input.LightDir, input.ViewDir, texNew );   

return color;
}

technique normalMapping
{
pass p0
{
CullMode = None;
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS_NormalMapping();
}
}

technique ParallaxMapping
{
pass p0
{
CullMode = None;
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPs_Parallaxmapping();
}
}

technique NormalEffect
{
pass
{
CullMode = None;
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS_Normal();
}
}
PS:晚上回来心血来潮无聊弄的,可能有Bug或者不严谨的地方,大家原谅则个~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值