我可以在2D游戏中实现手电筒效果(光源周围较亮的区域)吗?


16

我正在考虑为自己编写一个简单的2D游戏。起初它不会以完美的图形或游戏玩法发光,但我认为这是我进行PC游戏开发的第一步。因此,请想象一下这样简单的基于Sprite的2D游戏(例如Heroes IV或Startcraft BroodWar)。

我希望游戏能够支持白天/夜晚进行相应的灯光更改,同时又不得不为每个灯光细微差别创建子画面。因此,我决定在其他对象之上添加一个半透明层就足够了。

该解决方案的问题是,如果我在游戏中有一个光源对象(例如戴着火炬的英雄或正在燃烧的建筑物),那么它周围一定有一个较亮的区域,对吗?由于我将我的半透明层覆盖在所有内容上,您如何建议实现我想要的火炬视觉效果?也许根据光照效果重画该图层以添加“空白”或不同颜色的区域?


2
面具可能是必去之路
Gustavo Maciel 2012年

5
由于游戏名为Torchlight,标题中的“ Torchlight”可能会造成混淆。
Tetrad 2012年

4
只要没有大写,@ Tetrad应该可以。对于我来说,直到阅读您的评论,Torchlight才完全浮现在脑海。
2012年

尽管如此,我还是建议进行修改以使标题更具体。
2012年

Answers:


12

我不知道您在编程什么,但这就是我在XNA中处理它的方式:

  1. 在绘图调用中,将List<Light>创建/清除对象。
  2. 在图块绘制循环期间,将检查每个图块以查看是否有任何与之关联的灯光。如果是这样,则将Light对象附加到List<Light>
  3. 瓷砖绘制在自己的瓷砖上RenderTarget2D
  4. 瓷砖循环后,列表LightS通过迭代和自己绘制RenderTarget2D使用纹理我做的,看起来像这样:
    轻质感(注:我这里使用的R,G和B值,但你应该使用Alpha通道在实际纹理。)
  5. 使用自定义着色器,我将瓷砖表面渲染到屏幕上,并将照明表面作为参数传递给每个像素,以获取“暗度”值的参数。


现在,有几件事要注意:

关于第4点:

我实际上有两个自定义着色器,一个用于将灯光绘制到照明渲染目标(步骤4),另一个用于使用照明渲染目标将平铺渲染目标绘制到屏幕(步骤5)。
在第4点使用的着色器允许我添加(称为)“亮度”值。该值是一个float在与纹理中的每个像素相乘之前将其相乘的值,这样我就可以从本质上使光源更亮或更暗。
在这一点上,我还考虑了光源的“比例”值,这意味着仅使用一种纹理就可以使用大型或小型光源。

关于第5点:

可以将照明渲染目标视为每个像素从0(黑色)到1(白色)的值。着色器实质上是将该值与图块渲染目标中像素的RGB值相乘,以生成最终绘制的图像。

我在这里还有一些其他代码,在其中我将(一个值)用作日夜覆盖色传递给着色器。这也将乘以RGB值,并包含在照明渲染目标计算中。


现在,这将不允许您执行诸如阻止光线绕过对象之类的操作,但至少出于我的目的,它很简单并且效果很好。

我在这里这里都写了更详细的博客文章,可能会对您有所帮助。我现在没有时间,但是如果您愿意,我可以在这里详细介绍gamedev。

哦,这是我的地图编辑器中的内容:在此处输入图片说明


生成并清除每个帧的列表可能不会花费太多吗?
Gustavo Maciel 2012年

@Gtoknu在我的游戏中没有任何明显的不同。该列表只是保存对内存中已经存在的对象的引用,因此它并不像在重新创建每一个光源或进行任何操作,而只是一个列表。
理查德·马斯克

你可能是正确的,不是完全正确的,但是你是正确的。当然,您不是在创建完整的对象,而是在添加指向引用的指针,尽管使用率仍然很低,但是仍然很消耗。您的工作方式不错,但我认为将列表放在draw方法之外可能会更好,因为更新逻辑比绘制逻辑快得多
Gustavo Maciel 2012年

@Gtoknu当然,您可以在任意位置声明列表,但要点是灯光与图块相关联。瓷砖Draw方法是您查找瓷砖是否有灯光的地方。我不会遍历该Update方法中所有绘制的图块,因此会为此增加额外的开销。此外,XNA试图保证Update每秒将调用60次,因此可能会Draw为此牺牲调用次数,这意味着该代码实际上很少被调用。
理查德·马斯克

话虽如此,这是有争议的,因为我最终根据空间划分将灯光移到了自己的列表中,并只是将所有灯光绘制在与屏幕相交的部分中。我没有因为时间不足而在帖子中谈论这一点,但是在我链接的第二篇博客文章中提到了这一点。
理查德·马斯克

9

通常,2D游戏中的照明是通过 为所有精灵创建法线贴图,然后计算2D精灵上的3D照明效果。俗称“ 2.5D”。但是,我建议您在第一个游戏中这样做,因为它很复杂。

以下是在XNA中完成此操作的人的精彩视频:http : //www.youtube.com/watch?v= -Q6ISVaM5Ww

就是说,可能有很多方法可以欺骗并获得可以在各种假设下工作的伪照明系统。


之前已经看过此视频,+ 1提到了这种令人难以置信的技术。
Gustavo Maciel

感谢您的建议和视频链接。确实,地图似乎是一种解决方案。我本人将尝试使用顶层的贴图来创建“间隙”,或更改其对基础对象的影响。
Ivaylo Slavov

5

如果您对要达到的效果不完全明确,则很难提出一种方法。细节,例如灯光是否应被环境遮挡,游戏的观点如何以及灯光应与环境互动的程度等。

我会掉两分钱。查看Catalin Zima的标题为Dynamic 2D Shadows的本教程是否适合您的要求。如您所见,光线有一个半径并且不会穿过障碍物。您可以对半径和颜色进行动画处理,使其看起来更接近真实的手电筒。

在此处输入图片说明

在这种情况下,尽管光线确实考虑了障碍,但它就像场景上的叠加层一样,但与John的示例交互作用的程度不同。

编辑

Catalin链接到他用作参考的另一篇文章,但该链接已断开。这是更新的链接


谢谢,我认为这不是我想要的效果,但仍然感谢您的分享:)
Ivaylo Slavov'1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.