这节教程的框架跟DiffuseLight那节教程的框架差不多,也就是灯光常量缓存那里改变和PixelShader改变了,
首先说一点,首先AmbientLight,DiffuseLight,SpecualrLight都是局部光照,而其中DiffuseLight,SpecualrLight在游戏场景中经常照射不到某些地方造成一片黑暗,为了近似模拟现实世界,就用AmbientLight模拟全局光的效果,当然效果比起全局光还是大大不如,但是运行效率是非常不错的.具体的三种光照的公式我在这里贴出来吧,(注意:这里还不设计具体光源类型,只谈光照类型)
LitColor(Ambient)=La*Ma;
La为环境光的颜色,Ma为物体材质对环境光的反射率,注意这个为离散乘法,La(R1,G1,B1),Ma(R2,G2,B2),因此为离散乘法.
当然教程Ma材质默认为Ma=(1,1,1),并且是存在Texture情况下的.
这个教程建立在第六个教程DiffuseLight前提下,因此同时存在DiffuseColor和AmbientColor
当灯光方向设置为(1.0f,.0.0f,0.0f);
第一种情况:当打开DiffuseLight,而关闭AmbientLight时,背对灯光方向的一面为纯黑色
程序运行结果如下:
第二种情况,当同时打开DiffuseLight和AmbientLight时,背对灯光的一面也能轻微的亮起来(我设置的AmbientLight比较小)
程序运行结果如下:
有种模拟到全局光的感觉了
贴出我的Shader代码
Texture2D ShaderTexture:register(t0); //纹理资源
SamplerState SampleType:register(s0); //采样方式
cbuffer CBMatrix:register(b0)
{
matrix World;
matrix View;
matrix Proj;
matrix WorldInvTranspose;
};
cbuffer CBLight:register(b1)
{
float4 AmbientColor;
float4 DiffuseColor;
float3 LightDirection;
float pad;
}
struct VertexIn
{
float3 Pos:POSITION;
float2 Tex:TEXCOORD0; //多重纹理可以用其它数字
float3 Normal:NORMAL;
};
struct VertexOut
{
float4 Pos:SV_POSITION;
float2 Tex:TEXCOORD0;
float3 W_Normal:NORMAL; //世界空间的法线
};
VertexOut VS(VertexIn ina)
{
VertexOut outa;
outa.Pos = mul(float4(ina.Pos,1.0f), World);
outa.Pos = mul(outa.Pos, View);
outa.Pos = mul(outa.Pos, Proj);
outa.W_Normal = mul(ina.Normal, (float3x3)WorldInvTranspose); //此事世界逆转置矩阵的第四行本来就没啥用
outa.W_Normal = normalize(outa.W_Normal);
outa.Tex= ina.Tex;
return outa;
}
float4 PS(VertexOut outa) : SV_Target
{
float4 TexColor; //采集的纹理颜色
float LightFactor; //灯光因子
float4 color = {0.0f,0.0f,0.0f,0.0f}; //最终输出的颜色
//第一,设置颜色为环境光颜色
color = AmbientColor;
//第二,获取采样颜色
TexColor = ShaderTexture.Sample(SampleType, outa.Tex);
//第三,求出灯光因子
float3 InvLightDir = -LightDirection;
LightFactor = saturate(dot(InvLightDir,outa.W_Normal)); <span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">//saturate(float1*float4),</span>
//第四,求出漫反射灯光照射颜色
if (LightFactor>0)
{
color += LightFactor*DiffuseColor; // 叠加漫反射灯光颜色
}
color = saturate(color);
//第五,用灯光颜色调节纹理颜色
color = color*TexColor;
return color;
}
项目源码链接如下: 点击打开链接