使用GLSL实现对光照的模拟(一)

使用GLSL实现对光照的模拟(一)

       这个例子本来几天前就已经完成了,但是由于工作的关系以及自己的一点儿懒惰,一直没有写成博文,趁着刚刚醒来,精力百倍的情况下,一气呵成,把这篇文章写好。也算是做到坚持吧。

       OpenGL1.1是很老的OpenGL标准了,即使这样,对于光照也是提供了很好的支持。OpenGL默认的光照着色模型是高洛德(Gouraud)着色模型,虽然着色的精度上不是很好,但却非常好理解,对于该光照模型的例子也非常多,在《OpenGL ES 2.0 Programming Guide》中使用OpenGLES2.0实现了OpenGL1.1的高洛德着色模型。互联网上搜索GLSL+光照,相应的文章也是非常的多。有些直接成了我参考的蓝本。不管怎么样,花了大概一周的时间在以前的基础上使用Qt + OpenGL(ES2.0)基本实现了高洛德着色,而且可以突破固定渲染管线的8个光源的限制了。

       下面是程序的截图:

使用GLSL实现对光照的模拟(一)_第1张图片

       为了最大程度地对OpenGL的光照进行模拟以及利用C++类型封装的特点,我将灯光抽象成了BaseLight类,该着色模型支持的灯光类型有方向光(DirectionalLight)、点光源(PointLight)以及聚光灯(SpotLight)。所以具体的灯光类还要从BaseLight中继承才行。目前BaseLight所拥有的属性有全局光、镜面反射以及漫反射,而具体的灯光类比如说SpotLight,则增加了位置、点光源方向、衰减、衰减指数、以及半切角。

       当然,除了在host端有相应的类以外,在着色器部分也会对光源进行定义。在OpenGL (ES2.0)中,顶点着色器是替代固定渲染管线的T&L阶段的,所以对于光照的处理一般在顶点着色器中完成。在顶点着色器中对于每种光源都定义一个struct类型(因为GLSL无法定义class类型以及面向对象编程)。可以定义若干个uniform来让其支持多少的光源。在OpenGLES2.0中,最多能够支持128个uniformentries,不过这也不是一定的,因为显卡好的话,顶点着色器的编译器会允许多于128个uniformentries,所以那时定义百个光照也是没问题的。

       最后的问题该是如何将host端的数据传入着色器中了,我以每一个mesh定义一个着色器,这些着色器都包含了对于光照的处理。随后在渲染的阶段通过传递uniform向着色器传递光照,渲染每一个mesh都会通过unform传递一次。这样做可以保证每个mesh的材质渲染的独立性。如果某个mesh不需要接收光照,可以避免在着色器中写入光照部分的逻辑,从而达到不接收光照的目的。

       技术细节呢,请期待下一篇的解说。

你可能感兴趣的:(qt,OpenGL,GLSL)