漫反射与Lambert模型

漫反射指的是粗糙的物体表面各个方向等强度地反射光,即等同的各个方向散射的现象


(图片源于Unity Shader 入门精要-冯乐乐著)

对于物体上的某一点,使用环境光源的情况下

A=K*I(环境光强)

其中A为漫反射物体与环境光交互反射的光强

K为漫反射物体材质的反射系数,取值范围为(0,1)

I1为环境光光强


因为环境光在物体各个点的强度相同,且没有方向因此上述Lambert公式中无需考虑光强的方向,但对于使用点光源就要考虑了

对于物体上的某一点,使用环境光源的情况下

A=K*I2*Cos(α)(点光源)

其中A为漫反射物体与环境光交互反射的光强

K为漫反射物体材质的反射系数,取值范围为(0,1)

I2为点光源光强

α为点光源向量与表面法向量的夹角


在Cg中,点光源向量为顶点指向光源的向量,并非普通情况下所指的从光源位置到顶点的向量,即:


(图片源于Unity Shader 入门精要-冯乐乐著)

如图所示,l为顶点指向光源的单位向量,n为顶点单位法向量,将向量表示为单位向量可以避免一些错误

因此A=K*I2*Cos(α)可以表示为A=K*I2*(n*l).



因为n*l=|n|*|l|*Cos(α)

而|n|=|l|=1

所以A=K*I2*Cos(α)等价于A=K*I2*(n*l)

对于|n|>1或|l|>1时

A=K*I2*Cos(α)等价于A=K*I2*(n*l)/(|n|*|l|)

对于漫反射模型来说,n,l,的数值并不是必须的,所以还是将其归一化会比较好,也可以避免一些额外的计算


因此,综合环境光和点光源计算得到最终的公式:A=K*I1+K*I2*(n*l) (n,l为单位向量)

附上源代码:

struct VertexIn
{
float4 position:POSITION;
float4 normal:NORMAL;
};
struct VertexScreen
{
float4 oPosition:POSITION;
float4 color:COLOR;
};
void main_v(
VertexIn posIn,
out VertexScreen posOut,

uniform float4x4 modelViewProj,
uniform float4x4 worldMatrix,
uniform float4x4 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; //RGB

posOut.color.w= 1; //Alpha
}
(代码源于GPU编程+Cg语言之阳春白雪下里巴人)
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值