镜面反射颜色计算公式:
color = AIntensity * Acolor * Amaterial+ DIntensity * Dcolor * N dot L * Dmaterial+ SIntensity * Scolor * R dot V * Smaterial
N 是漫反射顶点法向量 ,L是漫反射入射光向量的反向量,V是镜面反射的观察点向量(从被观察点指向观察点),R是镜面反射的的反射向量(出射光)
1.顶点渲染器代码
//==============================================================
// Desc: 顶点渲染器代码
//==============================================================
//--------------------------------------------------------------
// 全局变量
//--------------------------------------------------------------
float4x4 matWorldViewProj; //复合变换矩阵
float4x4 matWorld; //世界矩阵
float4 vecLightDir; //灯光方向
float4 vecEye; //观察点位置
float4 materialAmbient; //材质反射环境光系数
float4 materialDiffuse; //材质漫反射系数
float4 materialSpecular; //材质镜面反射系数
//--------------------------------------------------------------
// 输出结构
//--------------------------------------------------------------
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); // transform Position
//计算灯光方向和观察方向
float3 lightDir = normalize( vecLightDir );
float3 posWorld = normalize( mul(pos, matWorld) );
float3 viewDir = normalize( vecEye - posWorld );
//计算法向量方向和漫反射强度
float3 normalWorld = normalize( mul(normal, matWorld) );
float4 diff = saturate( dot(normalWorld, lightDir) );
//计算反射光方向( R = 2 * (N.L) * N - L)和镜面反射强度
float3 Reflect = normalize( 2 * diff * normalWorld - lightDir );
float4 specu = pow( saturate(dot(Reflect, viewDir)), 0.5 );
//计算顶点颜色
float4 diffuseColor = { 1.0f, 1.0f, 1.0f, 1.0f};
float4 ambientColor = { 0.5f, 0.5f, 0.5f, 1.0f};
float4 specularColor = { 0.0f, 0.0f, 1.0f, 1.0f};
Out.Color = ambientColor * materialAmbient +
diffuseColor * diff * materialDiffuse +
specularColor * specu * materialSpecular;
return Out;
}
//构造观察矩阵
D3DXMATRIXA16 matView;
D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5 );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
//构造投影矩阵
D3DXMATRIXA16 matProj;
float fAspectRatio = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspectRatio, 1.0f, 100.0f );
//构造世界矩阵
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
//设置坐标变换矩阵
D3DXMATRIXA16 matWorldViewProj;
matWorldViewProj = matWorld * matView * matProj;
V_RETURN(g_pConstant->SetMatrix( pd3dDevice, "matWorldViewProj", &matWorldViewProj ));
V_RETURN(g_pConstant->SetMatrix(pd3dDevice, "matWorld", &matWorld ));
V_RETURN(g_pConstant->SetVector( pd3dDevice, "vecEye",
&D3DXVECTOR4(vEyePt.x, vEyePt.y, vEyePt.z, 0) ));
//设置剔出模式,为不剔出任何面
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
//设置材质
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
mtrl.Ambient.r = 1.0f;
mtrl.Ambient.g = 1.0f;
mtrl.Ambient.b = 0.0f;
mtrl.Ambient.a = 1.0f;
V_RETURN(g_pConstant->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_pConstant->SetVector( pd3dDevice, "materialDiffuse",
&D3DXVECTOR4(mtrl.Diffuse.r, mtrl.Diffuse.g,
mtrl.Diffuse.b, mtrl.Diffuse.a)));
mtrl.Specular.r = 1.0f;
mtrl.Specular.g = 1.0f;
mtrl.Specular.b = 1.0f;
mtrl.Specular.a = 1.0f;
V_RETURN(g_pConstant->SetVector( pd3dDevice, "materialSpecular",
&D3DXVECTOR4(mtrl.Specular.r, mtrl.Specular.g,
mtrl.Specular.b, mtrl.Specular.a)));