1

我知道以前有人问过这个问题,但不幸的是我是这门语言的新手,所以我发现的复杂解释至少对我没有帮助。

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

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. 删除光源时,系统无法将较亮的值替换为较暗的值

这就是上面的代码应用于我的游戏的样子: 光

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

4

1 回答 1

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,它包含一个Block,LightAbsorb

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

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

基本上我们所做的是循环遍历所有的瓷砖,从顶部开始,如果瓷砖是空白的,则将CurrentLight变量设置为最大亮度,如果我们找到一个实心瓷砖,将其设置为CurrentLight变量并从中减去“吸收”量CurrentLight. 这样,在我们的下一个实心瓷砖上,当我们将瓷砖设置为该CurrentLight值时,它会稍微少一些。重复此过程,直到迭代数组。

演示

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

用于循环上每个图块的代码是:

if (tile.Light > CurrentLight) //If this tile is brighter than the last, set the current light to the tiles light
     CurrentLightR = tile.Light;
else if (CurrentLight != 0f) //If it is less, and isn't dark, then set the tile to the current light
     tile.Light = CurLightR;
if (tile.Light == CurLightR) //If it is the same, subtract absorb values
     CurrentLight -= tile.Absorb;

您还可以在这里看到我是如何制作“平滑”照明的:

于 2013-10-26T13:14:58.363 回答