第二章 光照
2.1 颜色
现实生活中人眼看到某一物体的颜色,是它所反射的颜色。如将白光照在红色的玩具上,玩具会吸收白光中除了红色以外的所有子颜色,不被吸收的红色光被反射到我们的眼中,让这个玩具看起来是红色的。
该颜色反射的定律运用在OpenGL时,给定光源颜色,把光源的颜色与物体的颜色值相乘,所得到的就是这个物体所反射的颜色。
glm::vec3 ambientColor(0.0f, 1.0f, 0.0f);
glm::vec3 objColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = ambientColor * objColor; // = (0.0f, 0.5f, 0.0f);
将环境光和物体光设为uniform变量
uniform vec3 objColor;
uniform vec3 ambientColor;
void main()
{
FragColor=vec4(objColor*ambientColor,1.0)* mix(texture(TextureA, TexCoord),texture(TextureB, TexCoord),0.2);//从外部输入的纹理图像ourTexture中,使用纹理坐标TexCoord进行采样
}
2.2 基础光照
2.2.1 冯氏光照模型
冯氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。
2.2.2 环境光照
即使在黑暗的情况下,世界上也仍然有一些光亮。为模拟这种情况,使用一个很小的环境光照常量,添加到物体的最终颜色中。即便场景中没有直接的光源,也能看起来存在有一些发散的光。
环境光照分量ambient
:光的颜色lightColor
乘以一个常量环境因子ambientStrength
。
float ambientStrength=0.5;
vec3 ambient=ambientStrength*lightColor;
2.2.3 漫反射光照
漫反射光照使物体上与光线方向越接近的片段能从光源处获得更多的亮度。如果光线垂直于物体表面,这束光对物体的影响会最大化(更亮)。为了测量光线和片段的角度,使用片段法向量与光线方向向量的点乘计算。两个单位向量的点乘结果为一个标量,夹角越小,点乘结果越倾向于1,光对片段颜色的影响就应该越大。
1、片段法向量:把法线数据手工添加到顶点数据中,并更新顶点属性指针吗,就可以在顶点着色器中输入片段法向量。
- 如何将法向量变换到世界坐标系:法向量只是一个方向向量,没有w分量,位移不会影响到法向量。因此,将法向量乘以模型矩阵中的旋转部分,只实施缩放和旋转变换,变换到世界坐标系中。
- 当模型矩阵执行了不等比缩放,顶点的改变会导致法向量不再垂直于表面,通过法线矩阵可移除对法向量错误缩放的影响。
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
Normal= mat3(transpose(inverse(modelMat))) * aNormal;
...
2、光线方向:通过光源的位置向量和片段的位置向量计算。
-
光源的位置是一个静态变量,在片段着色器中把它声明为
uniform vec3 lightPos
: -
片段位置位于世界坐标系中,可以通过把顶点位置属性乘以模型矩阵来把它变换到世界空间坐标。
Frapos=vec3(modelMat*vec4(aPos, 1.0))
-
光的方向向量是光源位置向量与片段位置向量之间的向量差。
vec3 lightDir=normalize