冯氏光照模型

冯氏光照模型


在现实中的光照是难以用计算机模拟的,因此我们要用简化的光照模型来对现实世界进行近似。 冯氏光照模型( Phong Lighting Model)就是其中之一。冯氏光照模型由三部分组成: 环境光( ambient)、 漫反射( diffuse)、 镜面反射( specular)。

img

环境光(Ambient Lighting)

在生活中,即使是黑暗的环境,世界上依旧存在着一些光照(如月光),环境光就是模拟这个的。有环境光时,物体几乎是不会黑暗的。

在OpenGL中,我们通常使用一个系数 ambient来乘以光源的颜色作为环境光

float ambientStrength = 0.1; //环境光的强度系数
vec3 ambient = ambientStrength * lightColor; //环境光

漫反射(Diffuse Lighting)

该部分用来模拟光源对物体的方向性影响,即物体越是正对光源的面越亮,这也是冯氏光照模型中视觉最显著的分量。

上面说到,漫反射是用来模拟光源对物体的方向性的影响的,所以我们要做的就是判断光源方向与每个点的正对程度。如下图所示

img

假设光线方向与该点的法线夹角为 θ \theta θ ,如果 θ \theta θ 为0度,即光源正射该点,此时该光源对该点的影响达到最大化,换句话说,最亮。如果 θ \theta θ为90,则影响最小。因此,我们只需要计算出来光线方向与法线接近程度即可。利用点乘可以判断出两个向量的接近的程度。

两个单位向量的点乘结果是这两个向量夹角的余弦值。两个向量越接近,这个值越接近于1。

计算漫反射光我们需要两个数据:法向量和光线方向(光源的位置,点的位置)。

//计算出法向量和光线方向的单位向量
vec3 norm = normalize(Normal); 
vec3 lightDir = normalize(lightPos - FragPos);
//判断漫反射强度系数
float diff = max(dot(norm, lightDir), 0.0);
//计算漫反射光照
vec3 diffuse = diff * lightColor;

镜面反射(Specular Lighting)

该部分用来模拟光滑物体表面的高光。镜面反射的颜色更倾向于光照的颜色

在现实生活中,光滑物体表面的高光是会随着人的视线发生改变的,它依赖于人的观察方向。

镜面反射基于光的反射特性,如下图所示

img

R ‾ \overline{R} R代表光线的反射光线。 人的视线与反射光线的夹角 θ \theta θ越小,观察到的镜面反射的效果越明显。

float specularStrength = 0.5; //镜面反射强度
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; //镜面反射光线

float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 中的32代表高光的反射度(Shininess)。反射度越高,反射光的能力越强,高光点越小,如下图所示。

img

合成环境光、漫反射和镜面反射

当三个分量都计算出来后,对它们进行求和,就可以得到完整的光照了。

vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);

参考

LearnOpenGL\Basic Lighting

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值