漫反射及具体光源的照明

光照(明暗模型)概述

三维图形的真实感取决于能否成功地模拟明暗效应。明暗模型用以计算可见表面应该显示地亮度和菜色。通常涉及一个明暗模型需要考虑的主要问题是照明特性表面特性观察角度

照明特性 是指可见表面被照明的情况,主要有光源的数目和性质,环境光及阴影效应等。
表面特性 主要是指表面对入射光线的反射、折射或透明的不同情形,还有表面的纹理及颜色等。
观察角度 是指观察景物时观察者相对可见表面所在的位置。

不同明暗模型的区别主要在于模拟方法。
一般来说明暗模型可以分解为三个部分:漫射照明、具体光源的照射及透射效应。具体光源照射产生的效果又分为漫反射和镜面反射两部分。

漫反射及具体光源的照明

  1. 环境光:物体表面多次反射而产生的均匀的照明光线。环境光线的存在使物体得到漫射照明。

漫射照明的亮度:

  • I=IaKa,

I是可见表面的亮度,Ia是环境光线的总亮度,Ka是物体表面对环境光线的反射系数,在0~1之间。

  • 具体光源在物体表面可以引起漫反射和镜面反射。
  1. 漫反射
    粗糙的物体表面向各个方向等强度地反射光,这种等同地向各个方向散射的现象。观察者从不同角度观察看到这一点的亮度是相同的,即漫反射与观察者的位置无关。I=IaKa+Ip·Kd·L·N/(r+k)

Lambert 定律
当方向光照射到朗伯反射体上时,漫反射光的光强与入射光的方向和入射点表面法向夹角的余弦成正比

  • Id=Ip·Kd·cosθ

Id 是漫反射引起的可见表面上一点(点光源)的亮度,lp是点光源发出的入射光线引起的亮度。
Kd(0<k <1)漫反射系数。
θ 是可见表面法向量N(顶点法向量)和点光源方向L(由顶点指向光源)的夹角,称为入射角(0≤ θ ≤90°)。θ=0,说明光线垂直于物体表面,漫反射光强最大;θ=90°,光线与物体表面平行,物体接收不到任何光线。
为简化余弦计算,假定N和L都是单位向量,则cosθ=L·N,有Id=Ip·Kd·L·N。
若将环境光线和漫反射效果结合起来,则计算亮度的公式应为:

  • I=IaKa+Ip·Kd·L·N

通常认为具体光源对可见表面产生的照明作用随光源与表面之间距离的增加而下降。设R是光线从光源发出到达表面再反射到视点的距离,则应有

  • I=IaKa+Ip·Kd·L·N/R2
    漫反射与Lambert模型https://blog.csdn.net/sezane/article/details/81051670

然而上式对于平行投影(R=∞)、透视投影效果不好,用r+k代替 R2,获得更逼真的效果:

  • I=IaKa+Ip·Kd·L·N/(r+k)【8-6】

r是光源到表面的距离,k是根据经验选取的一个常数。

上文参考:https://blog.csdn.net/sezane/article/details/81051670

镜面反射与Phong模型

镜面反射是指来自具体光源的光线到达可见表面上某一点后,主要沿着和入射角相等的反射角所决定的方向传播,从而使得观察者从不同角度观察时,这一点呈现的亮度并不相同。在任何有光泽的表面上都可以观察到镜面反射的效果。只有当观察者相对表面观察方向与反射光线的方向之间的夹角α=0时,才能看到镜面反射引起的反射光线。对于不是非常理想的光泽表面,反射光线引起的亮度随着α增大而迅速下降。

Phong Bui-Tuong提出的光照模型
用cosnα近似表示反射光线引起的亮度随着α增大而下降的速率,1<=n<=2000,取决于反射表面的有关性质。对于理想表面α=∞。
对于实际物质,被镜面反射的入射光的数量与入射角θ有关。如果将镜面反射光的百分数记为W(θ),就有计算表面亮度式子8-6修改得到:
Phong模型上图来源于:Unity光照模型之-Phong和Blinn-Phong光照模型

  • I=IaKa+Ip/(r+k)·[Kd·cosθ+W(θ)·cos2α]

假定:反射光线的方向单位向量R和指向观察点的单位向量V,有cosα=R·V。对于W(θ)根据经验用Ks代替,则有

  • I=IaKa+Ip/(r+k)·[Kd·(L·N)+W(θ)·(R·V)n] 【8-8】

I=IaKa+Ip/(r+k)·[Kd·(L·N)+W(θ)·(R·V)n] 【8-8】已经可以得到很好的具有明暗表现的画面。
对于彩色表面也可以应用上式,只需对个颜色分量分别计算,如RGB系统中将有关亮度及反射系数等看作三元向量。

BlinnPhong光照模型
BlinnPhong光照模型混合和了Lambert的漫反射和标准的高光,渲染有时比Phong高光更柔和、更平滑,此外它的处理速度相当快,因此成为许多CG软件中默认的光照渲染方法。
在Phong模型中,必须计算V·R的值,其中R为反射光线的单位向量,V为视线方向的单位向量。关键是对发射向量的计算(如下图R向量)
Phong光照模型中关键在于发射向量的计算

但是在BlinnPhong模型中,用N·H的值来取代V·R。BlinnPhong光照模型公式:

  • Blinn-Phong模型

Ks:物体对于反射光线的衰减系数;N:表面法向量;H:光入射方向L和视点方向V的中间向量;Shininess:高光系数。
可见,通过该式计算镜面反射光是符合基本规律的,当视点方向和反射光线方向一致时,计算得到的H与N平行,dot(N,H)取得最大;当视点方向V偏离反射方向时,H也偏离N。
同时H的计算比起反射向量R的计算简单的多,R向量的计算需要若干次的向量乘法与加法,而H的计算仅仅需要一次加法。

用途区别:
Phong适合模拟塑料,比"反射"材质表现出的介质更光滑一些,适合模拟玻璃、水、冰等高反光特性的介质
BlinnPhong大多适用于金属材质

上述内容参考:Unity光照模型之-Phong和Blinn-Phong光照模型

光的衰减

光的传播过程分为两个阶段:
第一个阶段:从光源到物体表面;这一阶段的衰减使物体表面的入射光强度变弱
第二个阶段:从物体表面到人眼;这一阶段的衰减使人眼接收到的物体表面的反射光强度变弱
总体效果使物体表面亮度下降。

光在光源到物体表面过程中的衰减

以衰减函数f(d)表示衰减比例,则有

  • f(d)=1/d2 ,d为光的传播距离

为了弥补点光源的不足,更有效的衰减函数取法:

  • f(d)=min[ 1/(C0+C1d+C2d2),1 ]

用户可以调节C0~C2控制f(d)变化的快慢,C0用来防止f(d)变得过大。f(d)最大值为1。考虑f(d),得到光照计算式为:

  • I=IaKa+f(d)·Ip/(r+k)·[Kd·(L·N)+W(θ)·(R·V)n] 【8-11】

光在物体表面到人眼过程中的衰减

为模拟光在这段传播过程中的衰减,许多系统采用深度暗示技术(Depth Cueing)。
首先在投影坐标系(记为xyz)中定义两个平面前参考面z=zf和后参考面z=zb,并赋予比例因子Sf和Sb(都在0~1之间)。
给定物体上一点的深度值Z0,该点的对应比例因子S0按如下方式确定:
点的对应比例因子S0按如下方式确定>原亮度I按比例So与融和亮度Idc混合,目的是获得最终用于显示的亮度I’,Idc由用用户指定,则有

  • I’=S0·I+(1-S0)·Idc 【8-12】

    取Sf=1,Sb=0,Idc=0,则当物体位于参考面之前时,I=I’,即亮度没有被衰减;当物体位于后参考面之后时,I‘=Idc=0,即亮度衰减为0。而当Z0∈& [Zf,Zb]时,I’=S0·I,亮度被部分衰减。
    由此可以产生较好的效果。

上文参考:https://wenku.baidu.com/view/2bd6e9e44b35eefdc8d333cd.html

冯氏光照模型下漫反射光及镜面光照的计算方式,
参考:https://www.cnblogs.com/NightFrost/p/10792602.html

1.环境光,是个常量
2.漫反射光,

将顶点的法向量标准化norm,将片段到光源的方向向量标准化lightDir;
对norm和lightDir向量进行点乘,计算光源对当前片段实际的漫反射影响,乘上光的颜色,得到漫反射分量,当法线和方向向量大于90度时,这个片段不会被光源照到,点乘得出来一个负值,但颜色不能是负值,所以要和0取最大;
如果只要环境光和漫反射光的话,得到的最终的结果是环境光加上漫反射光乘上物体的颜色,得到最后的颜色

vec3 norm = normalize(Normal); 
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0); 
vec3 diffuse = diff * lightColor;
vec3 result = (ambient + diffuse) * objectColor; 
FragColor = vec4(result, 1.0);

3.镜面光,

同样要获得顶点的法向量和光源到片段的方向向量,将这个向量标准化;
获得摄像机到片段的向量,使用reflect函数,将片段指向光源的向量和法向量作为参数传进去,得到一个反射向量;
再计算反射向量和摄像机到片段的向量的点乘和0的最大值的32次幂(32是指反光度(Shiness),反光度越高,反射光能力越强)。
把环境光,漫反射光,镜面光三个分量相加,乘上物体的颜色,得到最终的颜色;

vec3 norm = normalize(Normal); 
vec3 lightDir = normalize(lightPos - FragPos);
vec3 viewDir = normalize(viewPos - FragPos); 
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor; 
FragColor = vec4(result, 1.0);

基础光照输出=环境光+漫反射光+镜面光

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值