根据教程:ogldev一步步从零开始,记录学习历程
上一节学习了怎么渲染环境光,相关博文:
OpenGL学习之路15—-环境光
漫射光
之前我们学习到的环境光忽视光线的方向,如果只有环境光,整个场景是被均匀照亮的
漫射光跟环境光唯一的区别是漫射光依赖光线的方向,漫射光照射到物体上,被照射的一面要比背面亮
漫射光的强度,与光线入射的角度有关,如果光线垂直物体,则漫射光强最大,随着入射光线与法线夹角的增大,慢射光强逐渐减小
如图所示,随着当α为0°时,即垂直照射到物体表面,和法线成180°,漫射光强最大;而随着α增大,漫射光强逐渐减小:
计算光的强度,使用光线和物体表面法线的夹角α的余弦值作为一个参数,下图中表示了四个不同角度照射到表面上的情况:
- A的强度是最大的,因为α为0,余弦值最大为1
- B的强度是,cos(α)
- C从表面的一侧入射,此时光线和法线垂直,所以α角度为90,余弦值为0,即光线C对表面照亮没有任何效果
- D从表面的背面入射,α是一个钝角,余弦值为负,光线D也对物体表面没有照亮作用
结构体表示漫反射:
struct DirectionalLight
{
Vector3f Color;
float AmbientIntensity;
Vector3f Direction;
float DiffuseIntensity;
};
- 可以看到我们平行光结构体,在上一节环境光两个属性参数的基础上增加了两个代表着漫反射属性参数的变量
- Direction:代表光线入射的方向向量
- DiffuseIntensity:表示为漫反射的光线强度
计算顶点法线
多边形面上分布的任意法向量都是相同的,所以一个面取一个法向量即可代表平面法向量。 但是这样会导致一个平面上光线强度一样,导致多边形几个面之间光线不平滑。
这时引入“顶点法线”的概念:顶点法线即是共用一个顶点的所有三角形法线的平均值
我们在顶点着色器中根据顶点法线顶点计算出在世界空间里每个点的法向量的值,并传递到片元着色器中计算出每个像素法向量对应的光照强度
如下图,左边是两个平面各自的法向量,而右边是由顶点法线计算后得到每个点的法向量的样子:
计算顶点法线的代码:
static void CalcNormals(const unsigned int* pIndices, unsigned int IndexCount, Vertex* pVertices, unsigned int VertexCount)
{
for (unsigned int i = 0; i < IndexCount; i += 3) {
unsigned int Index0 = pIndices[i];
unsigned int Index1 = pIndices[i+