xxb 发表于 2007-8-14 09:34:00

2D 游戏中的光照

<table cellspacing="0" cellpadding="0" width="95%" border="0"><tbody><tr><td width="100%"><font face="Tahoma" color="#c0c0c0" size="2"><br/></font><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td width="50%"><font face="Tahoma" size="2"><img height="300" src="UploadFile/2007-8/200781493411734.jpg" width="400" border="0" alt=""/></font></td><td width="50%"><font face="Tahoma" size="2">一般说来, 最简易的光照算法就是将光圈位图 ADDTIVE 混合到目标图上了. 这个在</font><font face="Tahoma" color="#c0c0c0" size="2">风魂</font><font face="Tahoma" size="2">里可以方便的实现. 效果可以参考其例子程序.</font>
                                                                        <p><font face="Tahoma" size="2">16 bit 色下的ADDITVE混合无法用到 MMX 优化.(如果使用真彩, MMX 的饱和处理 就有用武之地了) 当屏幕上有多个光源时, 多次混合就极大的影响了速度. 而且简单的将多个光源的光线相加, 得到的效果呵实际并不相同. 进几天仔细观看了 Diablo II 的演示, 深为其中的光影效果(尤其多个动态光源)叹服, 如果我的 Engine 的质量要达到这个级数, 必须找到一个优秀的算法实现.</font>
                                                                        </p><p><font face="Tahoma" size="2">问题的关键点集中在, 我们最常用的颜色格式是 RGB 的, 对它进行光线运算势必牵扯 到多个数值的处理, 而 16bit 色还牵扯到色素的拆分问题, 导致了对图象光照运算的复杂. 而将点描述成 HSL 这样的格式, 虽然亮度被单独出来, 其格式不利于处理(无法实现半透明等常用效果), 色彩格式间的转换牵扯到了浮点运算, 且公式复杂, 最后整屏幕转换成 16bit RGB 再显示严重的影响了速度. 云风在仔细考虑后, 放弃了这条路.</font></p><p><font face="Tahoma" size="2"> </font></p></td></tr><tr><td width="100%" colspan="2"><font face="Tahoma" size="2"><br/>思考再三, 比较合理的做法是再屏幕 Buffer 外另建一个亮度 Buffer, 再更新屏幕的同时, 将亮度Buffer 和 色彩 Buffer 的数据组合得出将显示数据显示. 游戏中得点光源配合一张事先做好的圆或椭圆光圈绘制到亮度图上. 环境光则相当于整屏的亮度 Buffer 的处理. 而绘制在屏幕上的物体则可以根据游戏中的远近 将其掩图按一定的亮度绘制在亮度图上. 以此类推, 利用这张亮度 Buffer, 可以派生出许多的巧妙作用, 而速度比起直接对 RGB 逐点运算要快的多 ;-)</font>
                                                                        <p><font face="Tahoma" size="2">对于光照图Buffer, 我不打算和色彩信息叠加, 那样很容易饱和, 采取衰减的方式更好点. Buffer 中一个点占 1 字节, 但只使用低 5 位. 0~31 的数值表示了从 0 ~ 31/32 的衰减度. 运算很简单, 将 RGB 分别乘上衰减值除以个 32 就 OK 了.</font>
                                                                        </p><p><font face="Tahoma" size="2">最后来谈谈光线的叠加, 衰减度为 10 的光线和衰减度为 20 的光线叠加起来是多少? 当然不是 30. 正确的算法是 32-10*20/32=26 (10 实际是 31.3% 的衰减, 20 是 62.5% 的衰减, 合成值是 1-(1-31.3%)(1-62.5%)) 推导过程略.<br/></font></p></td></tr></tbody></table></td></tr></tbody></table>
页: [1]
查看完整版本: 2D 游戏中的光照