I am using C# and XNA. My current algorithm for lighting is a recursive method. However, it is expensive, to the point where one 8x128x8 chunk calculated every 5 seconds.
- Are there other lighting methods that will make variable-darkness shadows?
- Or is the recursive method good, and maybe I am just doing it wrong?
It just seems like recursive stuff is fundamentally expensive (forced to go through around 25k blocks per chunk). I was thinking about using a method similar to ray tracing, but I have no idea how this would work. Another thing I tried was storing light sources in a List, and for each block getting the distance to each light source, and using that to light it to the correct level, but then lighting would go through walls.
My current recursion code is below. This is called from any place in the chunk that does not have a light level of zero, after clearing and re-adding sunlight and torchlight.
world.get___at
is a function that can get blocks outside of this chunk (this is inside the chunk class). Location
is my own structure that is like a Vector3
, but uses integers instead of floating point values. light[,,]
is the lightmap for the chunk.
private void recursiveLight(int x, int y, int z, byte lightLevel)
{
Location loc = new Location(x + chunkx * 8, y, z + chunky * 8);
if (world.getBlockAt(loc).BlockData.isSolid)
return;
lightLevel--;
if (world.getLightAt(loc) >= lightLevel || lightLevel <= 0)
return;
if (y < 0 || y > 127 || x < -8 || x > 16 || z < -8 || z > 16)
return;
if (x >= 0 && x < 8 && z >= 0 && z < 8)
light[x, y, z] = lightLevel;
recursiveLight(x + 1, y, z, lightLevel);
recursiveLight(x - 1, y, z, lightLevel);
recursiveLight(x, y + 1, z, lightLevel);
recursiveLight(x, y - 1, z, lightLevel);
recursiveLight(x, y, z + 1, lightLevel);
recursiveLight(x, y, z - 1, lightLevel);
}