上篇谈到U.Studio郭兄曾提到精灵的影子可以实时计算出来, 开始我很不以为然, 因为影子是 3D 世界的东西, 在 2D 下计算影子必然有相当的失真. 但是经过一番思考后, 又得到了一些可能性. 最近, 读到一篇 2D Engine 中动态光源的实现的文章, 其算法最大的缺陷在于无法生成影子, 这使我重新重视影子的实时运算问题. 本文将在此方便做些探讨, 把我曾经考虑过的问题记录下, 希望对朋友们和我自己以后的Engine 设计有所帮助.
2D 下, 生成影子最大的困难是, 所有的物体都是平面的, 有如一张纸片, 这是计算真实的影子的最大障碍. 设想下阳光照射到一张纸片上和一个立体模型上在地面投射下 的影子有多大的区别吧. 所以, 对于阳光照射角度能够变化的 2D Engine 中, 大多数物体的影子是必须 由美工人员做好的. 但唯一有可能例外的是精灵(这里是狭义的精灵, 专指游戏中运动的小人等, 具体描述见第2篇)
先来看看什么时候, 平面的图象也能运算出真实的影子. 对, 是当光线平行于精灵图象平面的法平面时(如图). 这个时候, 精灵的
厚度完全不影响影子的形状, 我们可以得到真实的影子. 而斜视角引擎中, 所有的精灵都有 8 个方向的图,
所以我们可以得到 8 个方向的真实形状的影子, 这可以满足大多数情况的需要. (2D 游戏中不需要精确
的 3D 效果, 不是吗?)
下面来看看影子是怎么(近似)运算出来的, 下图是一个精灵站立时的 8 个方向的图象.(特别感谢 devil网友友情制作精灵的图案)
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
0号 | 1号 | 2号 | 3号 | 4号 | 5号 | 6号 | 7号 |
---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
接下来如果光线从左上方照射过来呢? 实际上它就等于 2 号图的直射情况, 所以我们可以拿出 2 号图的倒影 压缩旋转来获得. (见下图示)
同理, 这 8 个方向的精灵分别 8 个方向的影子都可以近似的得到(和实际的还是有区别), 这里都没有考虑运算量, 而运算的速度关键应该是集中在旋转上面. 但是, 随着计算机运算速度的提高, 实时计算影子应该不会成为 Engine 的速度瓶颈, 但是这个方法最大的弊病出在精灵本身的不规则上面, 这里多谢沐枫网友的 email 来讨论这个, 比如本文中用到的精灵, 手中的长棍就是最糟糕的地方, 应该棍子本身和精灵的身体完全不在一个平面而且几乎垂直, 这样影子经过旋转后, 某些情况将和实际大相径庭, Sigh, 看来 2D 下运算出影子还是非常困难的, 如果您有好的方法, 请来 Email 讨论 ^_^