拓幻图形学工程师教学手册(第三讲)|一字一字敲出OpenGL学习教程

栏目:游戏资讯  时间:2023-06-20
手机版

  

  上一讲已经介绍了的OpenGL纹理部分的内容,今天这讲关于OpenGL光照(Lighting)示例代码也都在公司github共有仓了,不知道各位是不是试着跑过,没跑过也不要紧,继续往下听吧,最后总要实践的,讲再多不如自己上手一试。我记得Dr. Lee当初还做了蛮多不错的示例代码,比如旋转的五彩菊花,回头我让他贡献一下他的五彩菊花,放到我们的Github上给大家参考。后期Dr. Lee也将推出一些他自己的教程,这可是来自美国克莱姆森大学的教程,大家不要错过,关注我们微信公众号,一起来学习吧。

  跑过“太阳系”工程的同学一定发现,除了上一讲的纹理映射实现将太阳及其行星表面纹理进行实现外,还有一个重点就是光。太阳系中唯一的光源就是太阳,其他行星只是进行光反射等,并且太阳光光源是向四面八方照射的,这个系统我们可以用OpenGL光照来进行模拟。

  先来看两张不同的图,一张有光照一张没有,看看区别就知道光照在渲染方面其实还是很重要的。

  接下来就是具体的光照内容了。

  5.2 表面向量(Surface Normal)

  先引入一个概念叫表面法线(Surface Normal),也就是表面上某一点的法向量(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。具体调用如下:

  5.3 OpenGL内置光照模型

  OpenGL光照分为三种,Ambient(环境光),Diffuse(漫射光)和Specular(镜面反射光)。

  Ambient 不依赖于光源的方向。光线在物体表面上向各个方向上均匀泛射,场景中的物体都会泛射光,这些泛射光又会照射到其他 物体上继续被泛射,直到光子能量耗尽为止,这样整个场景中散布着这样的泛射光。可通过设置一个颜色常量来表示环境光。Ambient = a constant。

  Diffuse 只依赖于光源的方向和法线的方向。因此为只和表面与光线入射夹角有关的光线。我们之所以能看到物体,就是因为物体将入射的光然后向各个方向反射(所以称之为漫反射)。物体的漫反射材质属性对物体的颜色起着决定性作用。Diffuse = I*cosΘ,Θ为入射角角度,也就是光来的方向和法线的夹角。

  Specular依赖于光源的方向,法线的方向和视角的方向。不但和表面与光线入射夹角有关,而且还和观察角度有关的光线,并且根据表面光滑程度,呈现不同亮度,越光滑,越容易产生高光区域。在 OpenGL 中,镜面光的强度可通过光滑度(shininess)来调节。

  Specular = I*cossφ ,其中指数s就是光滑度。1/s就是粗糙度(Roughness)。

  看一下效果图:

  

  下面介绍一下三种不同的光源。

  Directional Light 平行光(方向光),可以改变角度。可以联想太阳光。

  Point Light 点光源(由一个点向四周发射光源),可以改变位置。可以联想灯泡。

  Spot Light 聚光灯(聚光/锥光)。比较耗费资源,可以改变位置和角度。可以联想手电筒。

  

  再看一下光源位置不同造成的不同效果:

  

  左边是点光源在人眼位置,右边为点光源在坐标原点。

  5.4 使用OpenGL光照

  教大家一个简单的运用光照的代码:

  然后再设置全局光照信息:

  这样有个好处就是可以轻松控制光的强度,比如这里的0.3f。

  设置材质:

  设置光源特性:

  可以将这些代码整合为以下代码,放到方法体里面去:

  

  

  具体怎么使用,还需要各位参见Github我们的源码再实战一下。才能真正体会到光照这一块的用法。

  这是新年前最后一更啦,要放假啦!大家也假期多休息多陪陪家人吧,别码代码了,哈哈哈。年后再见吧?。

上一篇:言情剧男女主职业高大上,但火灾救援现场甜蜜撒糖合适吗
下一篇:原创安禄山与杨贵妃打闹,偶然发明一物品,现成女性潮流