基于网格的2D照明问题

时间:2013-10-24 03:11:33

标签: c# xna 2d lighting

我知道之前已经问过这个问题,但不幸的是我不熟悉这种语言,所以我发现的复杂解释至少对我没有帮助。

我的游戏需要一个照明引擎,我尝试了一些程序照明系统。这种方法效果最好:

if (light[xx - 1, yy] > light[xx, yy]) light[xx, yy] = light[xx - 1, yy] - lightPass;
if (light[xx, yy - 1] > light[xx, yy]) light[xx, yy] = light[xx, yy - 1] - lightPass;
if (light[xx + 1, yy] > light[xx, yy]) light[xx, yy] = light[xx + 1, yy] - lightPass;
if (light[xx, yy + 1] > light[xx, yy]) light[xx, yy] = light[xx, yy + 1] - lightPass;

(如果它们更亮,则通过'lightPass'变量减去相邻值) (它在for()循环中)

除了几个显而易见的原因外,这一切都很好而且花花公子:

  1. 系统支持首先出现的任何内容,在这种情况下是左边的值(x - 1)
  2. 删除光源时,系统无法用较暗的值替换较亮的值
  3. 以上代码适用于我的游戏: Light

    如果我能在创建新程序或其他照明系统方面获得一些帮助,我将非常感激!

1 个答案:

答案 0 :(得分:0)

首先,我喜欢你的艺术风格:)

基于网格的照明是我正在寻找的一个难点,最终我找到了一种方法。基本上每个块都有Light值,它发出的光量是多少。和Absorb值,吸收多少光。

白天的空白区块可能包含:

Light = 1; (Or Color.White for color)
Absorb = 15; //Light flows for 15 blocks through blank tiles

污垢块,将有:

Light = 0; (Or Color.Black for color) //Emits nothing
Absorb = 6; //Light flows for 6 blocks

有了这个,您可以轻松配置任何块。对于这个例子,我假设你有一个某种类的tile数组,比如Tile,其中包含BlockLightAbsorb

我还要说,在重新计算光照之前,每个帧都必须将所有光照重置为默认值(空白为1,污垢为0)(除非当然没有任何变化,否则会跳过重置和照明)

在我展示代码之前,让我解释一下执行此操作所需的步骤:

基本上我们所做的是遍历所有切片,从顶部开始,如果切片为空白,则将CurrentLight变量设置为最大亮度,如果找到实体切片,则将其设置为{{ 1}}变量并从CurrentLight中减去“吸收”量。这样,在我们的下一个实体图块上,当我们将图块设置为CurrentLight值时,它会略微减少。重复此过程,直到迭代数组。

Demo

现在,这将创建一个从上到下的灯光效果,循环必须重复,从右到左,从左到右,从下到上。

循环中每个图块使用的代码是:

CurrentLight

您还可以看到我如何制作“平滑”灯光,here