先来几个概念:
环境光(Ambient Light): 从物体表面所产生的反射光的统一照明,称为环境光
或背景光。环境光没有空间和方向性,在所有方向上和所有物体表面上投射的环境光强度是统一的恒定值。平行光:即光线都从同一个方向照射。
漫反射:英文是diffuse reflection,不用解释了。
Lambert反射体:即理想漫反射体,产生光的漫反射现象的物体表面。
Iambdiff=kdIa 用以求某点处漫反射的光强。
其中 Ia 表示环境光强度(简称光强), kd(0<kd<1) 为材质对环境光的反射系数。 I——ambdiff 是漫反射体与环境光交互反射的光强。Lambert漫反射模型:
Ildiff=kdIlcosθ
Il 是点光源强度, θ 是入射光方向与顶点法线的夹角( 0≤θ≤90∘ ), Ildiff 是漫反射体与方向光交互反射的光强。
因为 cosθ 等于顶点单位法向量和从顶点指向光源的单位向量的点积,故 Ildiff=kdIl(N∙L) ,N为顶点单位法向量,L为顶点指向光源的单位向量。
综合考虑环境光和方向,Lambert光照模型可以写成:
Idiff=Iambdiff+Ildiff=kdIa+kdIl(N∙L)
漫反射光照模型顶点着色程序:
void main_v(
float4 position : Position,
float4 normal : NORMAL,
out float4 oPosition : POSITION,
out float4 color : COLOR,
uniform float4*4 modelViewProj,
uniform float4*4 worldMatrix,
uniform float4*4 worldMatrix_IT,
uniform float3 globalAmbient,
uniform float3 lightPosition,
uniform float3 lightColor,
uniform float3 Kd)
{
oPostion = mul(modelViewProj,postion);//mul:计算两个矩阵相乘
float3 worldPos = mul(worldMatrix, position).xyz;
float3 N = mul(worldMatrix_IT,normal).xyz;
N = normalize(N);
//计算入射光方向
float3 L = lightPosition - worldPos;
L = normalize(L);
//计算方向光漫反射光强
float3 diffuseColor = Kd*lightColor*max(dot(N,L),0);
color.xyz = diffuseColor + ambientColor;
color.w = 1;
}
漫反射光照模型顶点着色程序
struct VertextIn
{
float4 position : Position;
float4 normal : NORMAL;
};
struct VertexScreen
{
float4 oPosition : POSITION;
float4 color : COLOR;
};
void main_v(
VertexScreen posOut,
uniform float4*4 modelViewPorj,
uniform float4*4 worldMatrix,
uniform float4*4 worldMatrix_IT,
uniform float3 globalAmbient,
uniform float3 lightPosition,
uniform float3 lightColor,
uniform float3 Kd)
{
posOut.oPosition = mul(modelViewProj, posIn.position);
float3 worldPos = mul(worldMatrix, posIn.position).xyz;
float3 N = mul(worldMatrix_IT, posIn.normal).xyz;
N = normalize(N);
//计算入射光方向
float3 L = lightPosition - worldPos;
L = normalize(L);
//计算方向光漫反射光强
float3 diffuseColor = Kd*lightColor*max(dot(N, L), 0);
//计算环境光漫反射光强
float3 ambientColor = Kd*globalAmbient;
posOut.color.xyz = diffuseColor+ambientColor;
posOut.color.w = 1;
}