简体   繁体   English

在基于图块的游戏中更新照明

[英]Updating lighting in a tile-based game

I've been working on a lighting system for a block-based game I'm developing (think Terraria), and I'm a bit stumped on one point of it. 我一直在为我正在开发的基于块的游戏开发照明系统(想想Terraria),但我对此感到有些困惑。 When a block is updated, its light level is also updated based on that of its neighboring (adjacent) blocks. 当更新一个块时,其亮度也会根据其相邻(相邻)块的亮度进行更新。

Now consider this situation: a player digs a hole into the ground, exposing a block that is far down in the Earth to the sun. 现在考虑这种情况:玩家在地面上挖了一个洞,将地球深处的障碍物暴露在阳光下。 This gives it a light level of 16 out of 16, and its neighbors a light level of 15. However, if the player fills in the hole again, the block will remain with a light level of 16. My first thought was to "audit" a block's light level when it is updated by checking that it doesn't have a difference of more than one unit from that of its neighbors, but that proved ineffective. 这样,它的亮度为16(16个亮度),其邻居的亮度为15。但是,如果玩家再次填充该洞,该方块的亮度将保持为16。我的第一个想法是“审核通过检查方块的亮度水平与相邻方块之间的差异不超过一个单位来进行更新,但事实证明效果不佳。

The only solution I could think of would be to specifically check if a placed block is exposed to sunlight, and if so, update the light level of the block below it to 15 out of 16. However, this would not be effective in fixing the issue in certain situations, and the neighboring blocks would fail to decrease in light level due to their neighboring blocks. 我唯一想到的解决方案是专门检查放置的块是否暴露在阳光下,如果这样,请将其下面的块的光照级别更新为16中的15。但是,这对于固定面板不起作用。在某些情况下会出现问题,并且相邻的块将由于相邻的块而无法降低光照水平。 Perhaps I just need to step back a bit and look at the problem again, but I thought I might post here in the meantime. 也许我只需要退后一步,然后再次查看问题,但是我想我可能同时在此发布。 Does anyone have suggestions as to how to work around this? 有人对如何解决这个问题有建议吗?

In my experience the least error prone and (strangely) fastest method is simply to clear all the blocks of light within the maximum range that could be affected (+-16 in your case) and recalculate them all. 以我的经验,最不容易出错(最快)的方法只是清除可能受影响的最大范围内的所有光线(在您的情况下为+ -16)并重新计算所有光线。

The iterative method when adding light gives nice results but I have found to be much slower; 加光时的迭代方法会产生不错的效果,但是我发现它的速度要慢得多。 presumably due to the overhead of maintaining lists of blocks that need updating and adding/removing from it as you run through the algorithm. 大概是由于维护运行算法时需要维护的块列表的开销,并且需要对其进行更新和添加/删除。 In removing light the iterative method is also bug prone as light can "leak back around" as you're finding; 在移除灯光时,迭代方法也容易出错,因为您会发现灯光会“泄漏回去”。 that a block previously at 14 light loses its connection to the sun and so is recalculated; 以前有14个光的块失去了与太阳的连接,因此需要重新计算; finds a block of light 13 nearby and sets its own light to 12 (rather than all of them being set to zero). 在附近找到一个灯光块13,并将其自己的灯光设置为12(而不是将所有灯光都设置为零)。

The solution I have used is to clear all the light levels then make a sweep downwards; 我使用的解决方案是清除所有光线,然后向下扫描。 Gathering light from the 9 blocks (in 3D, 3 blocks in 2D) above each block. 从每个块上方的9个块(3D,2D中的3个块)聚集光。 Light is decayed for the 8 (or 2 in 2D) blocks that aren't directly above and setting the light level to the maximum value from those 9 blocks. 对于不位于其正上方的8个(或2D的2D)块,光会衰减,并将这9个块中的亮度级别设置为最大值。 This allows light to travel downwards at up to a 45 degree angle; 这允许光线以最大45度角向下传播; this can give quite harsh shadows which may or may not be what you want. 这会产生非常刺眼的阴影,可能不是您想要的。 Repeating the sweep going upwards can alleviate the harsh shadows as can imposing a minimum light level that all blocks have regardless of sunlight. 重复向上扫描可以减轻阴影,因为无论阳光如何,所有块都可以施加最低的光照水平。

I think it would be easiest to explain with a flowchart: 我认为用流程图解释是最简单的:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM