上一讲已经介绍了的OpenGL纹理部分的内容,今天这讲关于OpenGL光照(Lighting)示例代码也都在公司github共有仓了,不知道各位是不是试着跑过,没跑过也不要紧,继续往下听吧,最后总要实践的,讲再多不如自己上手一试。我记得Dr. Lee当初还做了蛮多不错的示例代码,比如旋转的五彩菊花,回头我让他贡献一下他的五彩菊花,放到我们的Github上给大家参考。后期Dr. Lee也将推出一些他自己的教程,这可是来自美国克莱姆森大学的教程,大家不要错过,关注我们微信公众号,一起来学习吧。
- 光照(Lighting)
5.1 基本概念
跑过“太阳系”工程的同学一定发现,除了上一讲的纹理映射实现将太阳及其行星表面纹理进行实现外,还有一个重点就是光。太阳系中唯一的光源就是太阳,其他行星只是进行光反射等,并且太阳光光源是向四面八方照射的,这个系统我们可以用OpenGL光照来进行模拟。
先来看两张不同的图,一张有光照一张没有,看看区别就知道光照在渲染方面其实还是很重要的。
接下来就是具体的光照内容了。
5.2 表面向量
先引入一个概念叫表面法线,也就是表面上某一点的法向量(Normal Vector),是在该点处与表面垂直的方向。对于平面,其上各点的法向是一样的,统一为这个平面的法向。
以上是计算表面法线向量的方法,不多说。
这是对于平面而言,那么更多时候绘制的不是平面而是曲面,该怎么计算表面法线。
顶点法线(Vertex Normal)是过顶点的一个矢量,在生成曲面时,通常令顶点法线和相邻平面的法线保持等角,这样进行渲染时,会在平面接缝处产生一种平滑过渡的效果。
这样就产生两种计算表面法线的方法:Per-face和Per-vertex:
在OpenGL中使用方法如下:
Per-face:
Per-vertex:
所产生的效果,per-face会对于曲面会产生粗糙分割面的感觉,我们称之为“Flat Shading”,per-vertex则会产生平滑感,称之为“Smooth Shading”。
介绍一个函数glShadeModel函数。用于控制opengl中绘制指定两点间其他点颜色的过渡模式。参数一般为GL_SMOOTH(默认),GL_FLAT。OpenGL默认是将制定的两点颜色进行插值,绘制之间的其他点,如果两点的颜色相同,使用两个参数效果相同,如果两点颜色不同,GL_SMOOTH会出现过渡效果,GL_FLAT 则只是以指定的某一点的单一色绘制其他所有点。看下效果:
GL_FLAT:
GL_SMOOTH:
来看看具体调用和结合Per-face/Per-vertex的效果:
注意这里介绍一下,glEnable( GL_NORMALIZE ),在进行光照计算之前自动单位化法向量。之所以需要自动单位化法向量是因为法向量会受到glScalef的影响,当glScalef将物体的坐标放大k倍时,法向量变为1/k。具体调用如下: