I'm implementing a pure Minecraft clone, and I want to implement sunlight. I have a basic sunlight algorithm working perfectly in 2D, and I understand how to scale it to 3D. But how do I make it so I don't have to recompute the entire sunlight every time I place a block?
Pseudocode, because the actual algorithm is not written very well :)
FUNC propogateSunlight(x,y,z):
IF (x,y,z) is out of bounds then RETURN
IF light_at(x,y,z) is <= 0 then RETURN
# PROPOGATE
IF light_can_spread(x,y-1,z) AND light_at(x,y-1,z)<light_at(x,y,z) then:
set_light_at(x,y-1,z) to light_at(x,y,z)
propogateSunlight(x,y-1,z)
IF light_can_spread(x-1,y,z) AND light_at(x-1,y,z)<light_at(x,y,z) then:
set_light_at(x-1,y,z) to light_at(x,y,z)-1
propogateSunlight(x-1,y,z)
*repeat above IF statement for (x-1,y,z), (x+1,y,z), (x,y,z-1), (x,y,z+1) and (x,y+1,z)
Then it sets the top layer to 16 (the max light level) and calls propogateSunlight
on the top level.
This algorithm does what I want it to PERFECTLY. The only downside is that it is really really slow.
So what (psuedocode) algorithm is there to place / remove blocks (without transparency) that make it so I don't have to recalculate the entire world?
P.S. The coordinate system is standard 3d graphics, XZ is ground plane, +Y is up and -Y is down.