afonsolage / projekto

Voxel game made with Bevy Engine
MIT License
59 stars 4 forks source link

Voxel Lighting implementation #30

Closed afonsolage closed 2 years ago

afonsolage commented 2 years ago

Closes #29

This PR implements voxel lighting inspired on links provided on issue #29. It's a BFS flood-fill algorithm which will propagate the light value across the chunks.

afonsolage commented 2 years ago

Before continuing the implementation, I think it's time to draw the current genesis flow, so I can have a better understanding where insert the light propagation algorithm, since this algorithm needs to run after all chunks neighborhood is built but before faces merging.

afonsolage commented 2 years ago

Ok the bedrock of natural light propagation is done. But before I go to artificial light, there's still things to be done:

afonsolage commented 2 years ago

Before adding light removal algorithm, I'll add more tests on natural light neighborhood propagation, since this code is a little complicated.

afonsolage commented 2 years ago

Finished natural light propagation and added some tests. Next is light removal algorithm.

image It will look better when AO is added.

Also, no performance reduction was noticed. Still takes around 45 seconds to generate 16^256^16^8^8 chunks.

afonsolage commented 2 years ago

Added natural light removal algorithm, but before continuing to add/remove/propagate artificial light, I would like to add one more complex example for light removal across neighbors.

afonsolage commented 2 years ago

While doing some in-game tests, I noticed a problem: Currently the genesis workflow is mainly focused on generated chunks. So there is no way for light_propagator know when the chunk was generated or just updated.

I'll have to rework this inside this PR, since light propagation is different from generated or just updated chunks.

afonsolage commented 2 years ago

Light propagation flow was reworked, but there are two issue to be solved:

This picture shows the two first issues:

image

afonsolage commented 2 years ago

image There is a bug on light when removing chunks: It seems only the last light value on the merged faces is used

afonsolage commented 2 years ago

Currently the logic behind the light propagation algorithm is using a logic to propagate inwards, in other words, it looks on the neighbor voxels and take the light if the outside is greater than inside.

This is due to how neighborhood works, but I'll rework this to a outwards flood fill algorithm

afonsolage commented 2 years ago

I made a lot of rework on natural light propagation, but there are still some bugs. I've managed finally to create a test which reproduce the last one I was hunting, so it should be easier to fix (I hope).

I feel like I should still make some rework on current function flow, since I think it's still a little mess, but not that much.

afonsolage commented 2 years ago

Ok, light propagation seems working fine now:

image

Now I I'll optimize it, since it's take too long and I still feel the code can be reorganized and optimized.

Maybe create a struct LightPropagator which can be generic over LightTy? Dunno, first I'll do some benchmarks to check which function is taking longer to run.

afonsolage commented 2 years ago

Here are some time measurements when generating 16^256^16^4^4 chunks (~1m voxels):

Step Duration (secs)
Chunk Generation (noise) <1
update_kind_neighborhoods 4
propagate_natural_light_on_new_chunks 29
faces_occlusion 9
faces_merger::merge 69
Write to disk 32
Total 144

Write to disk is out of scope of this PR, but I'll take a look on propagate_natural_light_on_new_chunks and faces_merger::merge

afonsolage commented 2 years ago

Reduced propagate_natural_light_on_new_chunks from 29 to 19, which as a 34% reduction!

afonsolage commented 2 years ago
Step Duration (secs)
Chunk Generation (noise) <1
update_kind_neighborhoods 1
propagate_natural_light_on_new_chunks 13
faces_occlusion 1
faces_merger::merge 12
Write to disk 5
Total 33

I think it's good now, reduced from 144s to 33s. Also when running on Release mode, it takes around 2s, so it's pretty fast.

Time to merge now!