投光物

平行光:当使用一个假设光源处于无限远处的模型时,被称为定向光。因为它的光线都有着相同的方向,与光源的位置无关。

理解:太阳光便为平行光

定义一个光线方向向量而不是位置向量来模拟一个定向光

 1 struct Light {
 2     // vec3 position; // 使用定向光就不再需要了
 3     vec3 direction;
 4 
 5     vec3 ambient;
 6     vec3 diffuse;
 7     vec3 specular;
 8 };
 9 ...
10 void main()
11 {
12   vec3 lightDir = normalize(-light.direction);
13   ...
14 }

光照计算中采用的都是一个从片段到光源的光线方向。light.direction是人们的习惯,由光源指向物体的方向。所以需要取反。

二、点光源

是处于世界中某一个位置的光源,它会朝着所有方向发光,但光线会随着距离逐渐衰减,例如:灯泡

衰减

随着光线传播距离的增长逐渐消减光的强度通常叫做衰减

随距离减少光强度的一种方式是使用一个线性方程。这样的方程能够随着距离的增长线性地减少光的强度,从而让远处的物体更暗。然而,这样的线性方程通常会看起来比较假。在现实世界中,灯在近处通常会非常亮,但随着距离的增加光源的亮度一开始会下降非常快,但在远处时剩余的光强度就会下降的非常缓慢了。所以,我们需要一个不同的公式来减少光的强度。

d:代表片段距光源的距离。

Kc:常数项;Kl:一次项;Kq:二次项。

常数项通常保持为1.0,作用为:保证值永远小于1,否则的话在某些距离上反而会增加强度

一次项会与距离值相乘,以线性的方式较少强度

二次项会与距离的平方相乘,让光源以二次递减的方式减少强度。二次项在距离比较小的时候影响会比一次项小很多,但当距离值比较大的时候就会比一次项更大了。

由于二次项的存在,光线会在大部分时候以线性的方式衰退,直到距离变得足够大,让二次项超过一次项,光的强度会以更快的速度下降。这样的结果就是,光在近距离时亮度很高,但随着距离变远亮度迅速降低,最后会以更慢的速度减少亮度。下面这张图显示了在100的距离内衰减的效果:

实现衰减:

为了实现衰减,在片段着色器中我们还需要三个额外的值:也就是公式中的常数项、一次项和二次项。它们最好储存在之前定义的Light结构体中。

然后我们将在OpenGL中设置这些项:我们希望光源能够覆盖50的距离,所以我们会使用表格中对应的常数项、一次项和二次项:

1 cubeShader.setFloat("light.constant",1.0f);
2 cubeShader.setFloat("light.linear",0.09f);
3 cubeShader.setFloat("light.quadratic",0.032f);

计算衰减:

length函数为GLSL内建的函数

1 float distance = length(light.position - fragPos);
2 float attenuation = 1.0/(light.constant + light.linear * distance + light。quadratic *(distance,distance));

接下来,我们将包含这个衰减值到光照计算中,将它分别乘以环境光、漫反射和镜面光颜色。

1 ambient  *= attenuation; 
2 diffuse  *= attenuation;
3 specular *= attenuation;

猜你喜欢

转载自www.cnblogs.com/keguniang/p/10020187.html