漫反射要考虑光源位置和方向,因此这也就是所谓的位置光照模型,反射光线与观察者位置无关他不会因为观察点的变化而变化,所以其常用来模拟不光滑表面。
通常将漫反射和环境光成分相加来综合这些光照,顶点计算公式:
Color(颜色) = A(Intensity) * AColor * Amaterial + DIntensity * D Color* (N dot L) * D material
A=环境 D=漫反射 Intensity = 强度 Amaterial=材质的反射系数,Dmaterial=材质的漫反射系数 N=法向量 L=光向量
1.顶点渲染器代码
//--------------------------------------------------------------
// 全局变量
//--------------------------------------------------------------
float4x4 matWorldViewProj; //复合变换矩阵
float4x4 matWorld; //世界矩阵
float4 vecLightDir; //灯光方向
float4 materialAmbient; //材质反射环境光系数
float4 materialDiffuse; //材质漫反射系数
//--------------------------------------------------------------
// 输出结构
//--------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos: POSITION;
float4 Color: COLOR;
};
//---------------------------------------------------------------
// 顶点渲染器主函数
//---------------------------------------------------------------
VS_OUTPUT VS( float4 Pos: POSITION, float3 Normal: NORMAL )
{
//计算顶点位置
VS_OUTPUT Out = (VS_OUTPUT) 0;
Out.Pos = mul(Pos, matWorldViewProj);
//计算顶点颜色
float4 Light = normalize(vecLightDir);
float4 Norm = normalize( mul(Normal, matWorld) );
float4 diffuseColor = { 1.0f, 1.0f, 1.0f, 1.0f};
float4 ambientColor = { 0.5f, 0.5f, 0.5f, 1.0f};
//saturate Clamps x to the range [0, 1]
Out.Color = ambientColor * materialAmbient + diffuseColor * saturate(dot(Light, Norm)) * materialDiffuse;
return Out;
}
2.编译顶点渲染器
3.创建顶点渲染器
4.设置顶点渲染器全局变量
D3DXMATRIXA16 matWorldViewProj;
matWorldViewProj = matWorld * matView * matProj;
V_RETURN(g_pConstantTable->SetMatrix( pd3dDevice, "matWorldViewProj", &matWorldViewProj ));
V_RETURN(g_pConstantTable->SetMatrix(pd3dDevice, "matWorld", &matWorld ));
5.设置材质ambient和diffuse
//设置材质
D3DMATERIAL9 mtrl;
ZeroMemory(&mtrl,sizeof(D3DMATERIAL9));
mtrl.Ambient.a=1.0f;
mtrl.Ambient.r=1.0f;
mtrl.Ambient.g=1.0f;
mtrl.Ambient.b=0.0f;
V_RETURN(g_pConstantTable->SetVector(pd3dDevice,"materialAmbient",&D3DXVECTOR4(mtrl.Ambient.r,mtrl.Ambient.g,
mtrl.Ambient.b,mtrl.Ambient.a)));
mtrl.Diffuse.r=1.0f;
mtrl.Diffuse.g=1.0f;
mtrl.Diffuse.b=0.0f;
mtrl.Diffuse.a=1.0f;
V_RETURN(g_pConstantTable->SetVector(pd3dDevice,"materialDiffuse",&D3DXVECTOR4(mtrl.Diffuse.r,mtrl.Diffuse.g,
mtrl.Diffuse.b,mtrl.Diffuse.a)));
6.设置光的方向
//设置光的方向
D3DXVECTOR4 LightDirect;
LightDirect=D3DXVECTOR4(cosf(timeGetTime()/350.0f),1.0f,sinf(timeGetTime()/350.0f),1.0f);
g_pConstantTable->SetVector(pd3dDevice,"vecLightDir",&LightDirect);
结合顶点渲染器代码部分
//计算顶点颜色
float4 Light = normalize(vecLightDir);
float4 Norm = normalize( mul(Normal, matWorld) );/////////////////////////////////////////////////
float4 diffuseColor = { 1.0f, 1.0f, 1.0f, 1.0f};
float4 ambientColor = { 0.5f, 0.5f, 0.5f, 1.0f};
//saturate Clamps x to the range [0, 1]
Out.Color = ambientColor * materialAmbient + diffuseColor * saturate(dot(Light, Norm)) * materialDiffuse;////////////////////////////////////////
两处///////////////////////////即为计算光照叠加效果颜色的关键部分