2D 游戏中的光照 

2007-08-14 09:34 发布

2342 0 0

一般说来, 最简易的光照算法就是将光圈位图 ADDTIVE 混合到目标图上了. 这个在风魂里可以方便的实现. 效果可以参考其例子程序.

16 bit 色下的ADDITVE混合无法用到 MMX 优化.(如果使用真彩, MMX 的饱和处理 就有用武之地了) 当屏幕上有多个光源时, 多次混合就极大的影响了速度. 而且简单的将多个光源的光线相加, 得到的效果呵实际并不相同. 进几天仔细观看了 Diablo II 的演示, 深为其中的光影效果(尤其多个动态光源)叹服, 如果我的 Engine 的质量要达到这个级数, 必须找到一个优秀的算法实现.

问题的关键点集中在, 我们最常用的颜色格式是 RGB 的, 对它进行光线运算势必牵扯 到多个数值的处理, 而 16bit 色还牵扯到色素的拆分问题, 导致了对图象光照运算的复杂. 而将点描述成 HSL 这样的格式, 虽然亮度被单独出来, 其格式不利于处理(无法实现半透明等常用效果), 色彩格式间的转换牵扯到了浮点运算, 且公式复杂, 最后整屏幕转换成 16bit RGB 再显示严重的影响了速度. 云风在仔细考虑后, 放弃了这条路.

 


思考再三, 比较合理的做法是再屏幕 Buffer 外另建一个亮度 Buffer, 再更新屏幕的同时, 将亮度Buffer 和 色彩 Buffer 的数据组合得出将显示数据显示. 游戏中得点光源配合一张事先做好的圆或椭圆光圈绘制到亮度图上. 环境光则相当于整屏的亮度 Buffer 的处理. 而绘制在屏幕上的物体则可以根据游戏中的远近 将其掩图按一定的亮度绘制在亮度图上. 以此类推, 利用这张亮度 Buffer, 可以派生出许多的巧妙作用, 而速度比起直接对 RGB 逐点运算要快的多 ;-)

对于光照图Buffer, 我不打算和色彩信息叠加, 那样很容易饱和, 采取衰减的方式更好点. Buffer 中一个点占 1 字节, 但只使用低 5 位. 0~31 的数值表示了从 0 ~ 31/32 的衰减度. 运算很简单, 将 RGB 分别乘上衰减值除以个 32 就 OK 了.

最后来谈谈光线的叠加, 衰减度为 10 的光线和衰减度为 20 的光线叠加起来是多少? 当然不是 30. 正确的算法是 32-10*20/32=26 (10 实际是 31.3% 的衰减, 20 是 62.5% 的衰减, 合成值是 1-(1-31.3%)(1-62.5%)) 推导过程略.

TA的作品 TA的主页
B Color Smilies

你可能喜欢

2D 游戏中的光照 
联系
我们
快速回复 返回顶部 返回列表