斜视角图形引擎的设计

深入了解物体精灵

[上篇:让场景更生动][下篇:精灵的影子处理]


放下两个多月,才来继续这组文章,几乎不知道怎么下笔. 这个系列的中断,一是由于学校的考试,二是需要更多的精力投入到实际代码的编写, 三是想多谈些细节.这组文章不仅仅是供大家来探讨我对 2D 图形引擎的突破做的一些尝试, 和引导想做游戏而不知道从何出下手的朋友们, 而且对我自己的相关代码的编写做了 有用的引导, 我感觉自己的那部分代码写起来头脑中条理非常清晰, 所以完成的很顺利, 简直是一气呵成 (记得也就花了一周多的业余时间吧). 现在考试结束了; 引擎的代码部分, 前面文章中提到的都实现了; 而前不久的北京一行, 回来后感觉收益不小, 发现了一些细节的处理问题. 现在, 我将从游戏中将运用到的精灵,静止/运动的物体,这些对象的图象处理的细节问题上 展开讨论,继续这个系列,希望大家感兴趣.

轮廓处理

  游戏的画面不同别的美术作品, 它是由各个单独的小图片拼合起来的, 而让玩家感觉到屏幕上的所有东西是一个整体是我们游戏设计者的目标. 在处理这个问题上, 可见游戏画面和其他诸如广告图片/动画等的不同. 此类引擎不同 3D Engine, 光线, 对象, 都是实时计算渲染的, 画面浑然一体. 2D Engine, 所有的对象都是事先绘制好, 临时拼成场景, 单独制作单一对象时, 我们无法考虑四周环境对对象的影响, 所以环境的色调不能完全体现在对象上. 所以直接将对象贴在整个场景里时, 对象图形的边缘部分和场景交界, 可能会产生不协调. 最明显的是锯齿现象, 这个是由于屏幕上的图形是非线形造成的. 可以发现, 用 3D MAX 等对整个场景连同上面的物体/人物一同渲染, 便不会产生锯齿, 放大渲染后的图形观察可以发现, 在对象间的交界处, 有些过度的颜色点. 可惜, 过度的色彩点有可能不适合所有的情况, 边缘处理过的图形在动态的游戏中,有时过度的很自然, 有时却成了难看的轮廓线.

  负有经验的游戏美工, 在处理此类情况时可以做的相当的漂亮, 我对此没有太多的了解, 简单的推测可能是色系的选择(人眼对暗的颜色的色彩 区别感觉要迟钝些), 或是图形上的点保持一定的"脏乱"的色彩干扰, 使其没有大片的纯色而更自然. 仔细研究老外的游戏精品中图象, 我想是我们的游戏美工应当多尝试的.

  当美工此方面的能力尚缺乏时,我们程序员是否应该试着去弥补呢? 诚然, 实时处理这个问题, 会给系统带来本不必要的负担 (如果我们有世界一流经验丰富的游戏美工的话... 可惜我们没有 :-( ) 但为了我们游戏的视觉秒度个效果, 我们在游戏设定这么一个轮廓实时处理的 开关也未尝不可.

  消除锯齿, 比较常用且简单的方法是运用 Wu-Pixel, 这个在机械工业出版社 的《高性能图形程序设计》一书中有详细介绍.点是有大小的, 假设我们在黑色背景的(100,100)处画一个点, 就可以看成是画一个 (100,100)~(101,101) 间的矩形(不包括坐标 101,101). 矩形的大小为 1x1, 即点的大小. 如果在 (100,100.5) 处画一个点呢? 这个矩形便是 (100,100.5)~(101,101.5) 可惜屏幕上做坐标不可能是小数, 常规的方法只能将点画在 (100,100) 或 (100,101) 处, 使用 Wu-Pixel, 我们将使用亮度值来表现点的位置离整数坐标的偏差. (100,100.5) 是介于 (100,100) 和 (100,101) 间的, 即要绘的这个矩形在 (100,100) (100,101) 两个点构成的矩形中间. 我们便可以在 (100,100) 和 (100,101) 上分别绘制一个亮度一半的点, 两个点来反映这个处于两个物理点间的点. 同理,点 (100,100.3) 可以在 (100,100) 上绘制亮度 70%, (100,101) 上绘制亮度 30% 的点. 将这个方法从点推广到线, 屏幕上的斜线正是因为无法在小数坐标上绘点而造成的, 使用这个思路去绘制 斜线上的所有点, 我们将得到一条平缓的线条.

  线形坐标系上的所有点, 反映在屏幕坐标上都将涉及到四个点. 点的大小可以和屏幕上的一样, 但屏幕上每个物理点都应该是四个线形坐标系上的四个点 构成的了. 我们应该将其融合再绘制,根据四个元素点在屏幕物理点中所占比例不同, 我们也应当做相应的混合处理. 这个就是对上面提到的黑色背景上绘制亮色线条方法的加深. 游戏中真正需要处理的是物体的轮廓线. 为了得到一个线形的物体轮廓, 我有个简单的方法, 就是将物体缩小到 1/4 在运用. 每四个点融合成一个点. (将四个点的 RGB 分别取平均值在组合起来及可:-) 如果四个点中有点是透明色, 又有点不是, 则是在轮廓上. (但反过来不对, 四个点都不透明, 虽然也可能是轮廓上的点, 但不必特殊处理)我们在处理的同时, 也得到了轮廓线上点最小刻度为 0.5 的坐标值. 为过度打下基础. 处理轮廓, 我们将轮廓线上的点分为 3 级,如果四个点中有 1 个不是透明色, 则 Alpha 值为 25%; 两个不是透明色, Alpha=50%; 三个不是透明色, Alpha=75%. 在绘制这个物体时, 轮廓部分以相应的 Alpha 值背景做 alpha 混合, 即可得到满意的效果, 你将发现锯齿没有了 ^_^

  实时去计算轮廓当然不合适, 尤其使用这个方法, 需要 4 倍原图的图形, 未免浪费. 实际运用时, 应当在计算完后, 将轮廓数据和图形保存在一起.

  这个方法不算很好, 实际上, 用 3D MAX 渲染图形时, 可以同时生成一张带 Alpha 通道的图形, 实际描述的就是轮廓信息, 还包括了轮廓上点的透明度. 能够使用这些信息, 应该比上面的方法更好.

  关于程序, 我在北京时曾经用 VC 写了一个, 走时匆忙, 忘了带回来 :-( 家里的系统放假回家来一直很乱,加上换了块主板, 重装了 Win95, 没想到 VC 和我的主板 /显卡有冲突 (我一点选菜单, 不出 5 秒就 S 机, 这个 M$ 出的烂东东 @#$%!, 其它软件都运行良好) 一直头痛, 也没有再写. 如果用 Allegro 怕许多朋友 没有机会编译, 就暂且搁下, 过两天一定补上, 另为此文加配插图 ^_^