4.6、片元计算
如之前提到的,OpenGLES1.x灯光模拟是GLKit通过计算光线方向矢量和每个顶点的顶点法向量之间的标量积来测定的。标量积决定了有多少光线会照向顶点。之后,计算出来的光线效果被插补在顶点之间使光线看起来平滑。
纹理为如图4-9所示的精细灯光的固定错觉控制渲染的每个片元的颜色。但是,在决定片元颜色时,GPU已经执行了复杂的运算。是否可以使用GPU为每个单独的片元而不仅仅是为顶点重新计算灯光效果?当然可以,GPU是可以通过编程来做到这 一点的。
用于顶点的相同的方程式可以用在每个片元上。光线方程式需要每个片元的法向量。解决方法是编码一个纹理的每个RGB纹素内的法向量的X、Y、Z分量。这样的纹理称为法线贴图(normalmap)。用于每个片元灯光的技术通常叫做法线贴图、凹凸贴图,或者DOT3灯光,因为这三个术语本质上都是描述的效果。一个纹理单元决定了哪一个法线贴图纹素会影响片元。一个Shading Language程序会计算由选中的纹素和光线的方向所代表的矢量的标量积。然后使用这个标量积来按 比例确定最终的片元的颜色效果。
每片元光线计算即使是在动态的灯光和几何图形的情况下,仍然可以工作良好。但,是,每片元光线计算既需要嵌人式GPU做高耗费计算,又需要使用会耗尽GPU控制内存的法线贴图。生成法线贴图时也可能会出现问题。在一些情况下,iPhone SDK附带的PVRTextureTool能够帮助生成法线贴图,但要让一切看起来刚刚好也是复杂的。由于早期工具支持、计算耗费和纹理的内存限制等原因,可用设备对于每片元光线计算的 支持并不好。随着嵌人式GPU和工具支持的必然改进,高级每片元光线计算效果会变得更实际。
在网址https://en.wikipedia.org/wiki/Normal_mapping 中可以找到多个与每片元光线计算相关的优秀源码的更多信息。由Aaftab Munshi、Dan Ginsburg和Dave Shreiner所著的《OpenGL ES 2.0 Programming Guide》
一书包含一个叫做‘ 使用法线贴图的每像
素光线计算”章节。Lighthouse3D 是-一个专注于3D计算机图形的网站,并且是深入学习灯光主题的最好资源之一。网址https://www.lighthouse3d.com/tutorials/glsl-tutorial/lighting/为实现标准的每片元灯光方程式提供了一个优秀的手把手教程。
4.7小结
真实世界的灯光效果是我们感知周围环境的关键,模拟灯光效果可以为3D渲染增加真实感。结合了材质的传统OpenGLES顶点灯光模拟提供了广泛的配置选项,但还要忍受各种限制以及嵌人式GPU的相对低的性能。比起OpenGLES材质,纹理几乎总是会产生更高质量的渲染结果。在使用了纹理之后,可以在纹理中包含一些灯光效果,同时完全避免OpenGLES灯光模拟。所有运行iOs的硬件都支持每片元灯光计算技术,并且随着内存、处理器和工具支持的改进这项技术会变得更加普遍。
截止到现在,所有渲染例子产生的都是类似一个裱在墙上的静止相片的冻结场景。下一章会讲解怎么从任意视点渲染一个场景,以及围着对象飞以从任意角度观察它们的知识。