之前《OpenGL 随想》已经写了三篇(一,二,三)。题目中虽有 OpenGL,但内容并非介绍 OpenGL 或者讨论其技术细节,而是讨论学习过程中联想到的一些计算、软件方面的问题。OpenGL 主要作为引发思考的灵感和一些例子的来源。
这些联系很松散的文章被归于一个系列为的是体现研究 OpenGL 这样一个复杂系统的过程中能引发各种思考。在计算软件领域之外也有类似情况:研究第二次世界大战的历史可以引发人际关系、项目管理、市场走向等等方面的思考。这个系列算是对这些辉煌的灵感源泉一个微不足道的致敬。
聪明和笨
前几个月,有人总结:计算机系统的性能提升中,算法改进导致的部分超过了遵循摩尔定律的硬件发展所带来的部分,前者达到后者的四十多倍。考虑到数学等基础领域出现突破进展是多么困难,而另一方面硬件一直沿着摩尔定律设定的路线坚定不移地提升(指数发展,每 18 个月每单位晶体管数量增加一倍),这个数字有点让人惊讶。
换个角度想,也就是说计算性能的提高的很大一部分不是归功于电子学和材料学的进展,而是归功于人们原本采用了比较『笨』的数学方法。而且提高的幅度之大说明一开始的方法『笨』的不轻。从纯数字看似乎的确如此,但从另一个角度看这是个错觉。
OpenGL 的策略
OpenGL 和计算机三维图形领域的一些方法所体现的『聪明』可以很好的解释『笨』的含义。比如考虑一个基本的问题,在计算机图形中如何表示一个三维平滑曲面,比如一个球体?最直接的方法是把曲面的表面离散化,通过数学方法(比如球的解析式或者 NURBS 表示)求出各个离散点的坐标,然后用离散点构成平面。离散点分布越密集(术语叫采样频率高),每个平面越小,平面越多,结果就和真实的曲面越吻合。当采样频率在 viewport [1] 上的投影超过屏幕的分辨率的时候,就会和平滑曲面无异 [2]。遗憾的是,估计当今主流台式机硬件用这个方法连五年前的高端游戏效果都得不到。OpenGL 采用另一种方法:smooth-shading 。这种方法采用的采样频率不是很高,只计算每个离散点当前视角和光照条件下在 viewport 上的位置和色彩。然后在二维的 viewport 上对各个离散点的投影之间的区域进行二维色彩线性插值。也就是说,OpenGL 的曲面是在 viewport 上用二维位图处理,或者可以叫『伪 3D 』方法实现的。
正是这种『伪 3D 』方法,让个人计算机在七八年以前就实现了高度仿真的实时三维图形效果。那么是不是可以说这是一个『聪明』的方法而提高采样频率是个『笨』办法呢?并非如此。如果希望计算机图形系统能自动完成任何光照条件下对各种材质、包括反射等等效果的自动处理,特别是当仅仅知道光照条件和材料特征的情况下希望通过计算的方式得出场景呈现的效果,这是唯一的方法。OpenGL 采用的『伪 3D 』方法不能直接推演真实的效果,它所做的只是用一些近似方法得到任意的效果,而后必须由人来主观判断这些效果是否足够和真实场景接近。除平滑曲面之外,OpenGL 中通过 viewport『伪 3D 』方法来完成的效果还包括物体遮盖、半透明、反射等等。
另一个例子是阴影。如果要自动生成阴影,图形系统必需跟踪场景中物体对光源遮挡的效果。由于性能的原因,OpenGL 完全不做这种光线追踪处理,阴影效果要求程序员通过投射变换计算出位置和形状之后手工绘制的黑色或者灰色形状(只有透射变换计算本身可以通过 OpenGL 提供的函数完成)。而且,简单的投影计算只能呈现理想点光源的全影,无法实现太阳这样的面积光源形成的半影。如果要形成半影,程序员还必须自己写代码通过二维位图处理(也可以看作『伪 3D 』)算法生成阴影然后画在投影面上。同样通过手工计算完成的效果还有镜面反射等等。
OpenGL 并不是能直接从物体描述自动生成场景的虚拟照相机,大量二维位图处理的应用使它更像画具,只不过增加了一些稍稍方便和精确的三维旋转和透视的处理。用 OpenGL 直接构建应用程序的过程更接近绘画而非场景布置或者摄影。[3] 虽然从历史角度说 OpenGL 的设计不见得就真的经历了从『面向场景和摄制』到『面向绘制』的转变,但是很多惊叹 OpenGL 效果而不明就里的人头脑中确实把 OpenGL 的功能想像成前者。所以从认识的角度以及类比到更广阔的领域,OpenGL 做出的主要『优化』本质上是改变了需求或者说问题域。
这是计算机提高解决问题效率的一个主要方式:回避问题,改变问题!虽然目标仍然是为用户呈现高度真实感的虚拟场景,但是 OpenGL 几乎完全剔除了一切『虚拟现实』的能力。它采用与真实场景和摄影相比高度简化的近似方法,要求系统的构建者通过实际经历、想象力、或者其它 OpenGL 之外 [4] 的方法另行得出,甚至是事先得出真实场景应该呈现的效果,通过主观比较判断 OpenGL 的近似效果是否令人满意再对不够满意的地方做出调整。和表面的感觉不同,OpenGL 把看似精确的计算机图形变成了一个主观创意的问题。
问题域和人的价值
计算机领域的很多所谓『算法优化』其实是『问题域』的简化或者说窄化。一开始面对一个过于复杂的问题域,采用性能无法被接受的算法。而后慢慢收回过大的野心,用更粗糙的算法来满足更简单的问题。
对问题域的修改即使并非唯一方法,也是从硬件之外提升计算生产力的主要方式。比如代码优化这个问题,C++ 就开始放弃了对语义和程序员透明的原则,引入了需要程序员干预的 ROV 优化。相比之下『空间换时间』等等经典的优化理论受到硬件的制约比较大,可以视为硬件发展的附庸,比如廉价的内存才能保证大 cache 算法的可行。而且硬件的改进会让一些优化技术失效,比如近年 CPU 片内 cache 和主内存之间速度差距的迅速增大已经让编译器的『体积最大』优化策略难以换取『速度最快』的结果。
对原问题域的简化并非意味着对被简化部分的简单忽略,很多的简化是把问题中计算机可解部分和人类干预部分的合理划分 [5]。OpenGL 这样的计算机图形系统的功能必须通过各种建模工具的交互式界面和额外材料来填补其『面向绘制』问题域与普通人能胜任的『面向场景和摄制』问题域的差距,才能在人类的辅助下释放最大潜力。严格限制计算机可解部分而得到更高的计算效率,通过良好的UI 把其它交给人类解决。这也是 UI 设计的意义,精致 UI 的作用不光是让人类用户享有更好的用户体验,也是为了释放计算机自动处理部分的最大潜力。
注释:
- Viewport 可以理解为 OpenGL 中虚拟摄像机的底片在操作系统的窗口上的实际呈现。
- 这里的『无异』是在硬件呈现能力的范围内而言。不过今天的硬件也已经进入了 ratinal screen 的时代,可以说在人的感知能力范围内也可以做到『无异』了。
- 很多三维设计师的自我感觉更像摄影师或者场景布置师,这正是 3DS Max 或者 AutoCAD 等软件在 OpenGL 之上提供的附加值。
- 这种方法不一定是脱离计算机辅助的。比如上面提到的 AutoCAD 和 3DS Max 等软件的帮助。但是它们是 OpenGL 之外的。而且是通过人类主导的。
- 某些创造性工作或者人脑结构更适合解决的问题还能让人类保持一种优越感和尊严。
发表评论