Bake chunk lighting so generated worlds load lit#1055
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds baked per-chunk lighting data (SkyLight + BlockLight) to Java Anvil chunks at write time, and marks chunks as pre-lit (isLightOn=1) so generated worlds load with lighting already present (including for off-disk renderers like Voxy/Chunky).
Changes:
- Compute SkyLight via a vertical cast from the top of the chunk volume followed by a flood-fill.
- Compute BlockLight via a flood-fill seeded from detected light-emitting blocks in each section palette.
- Write
SkyLight/BlockLightByteArrays into each section NBT and set rootisLightOnto 1.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
⏱️ Benchmark run finished in 0m 56s 📈 Compared against baseline: 27s time, 900 MB memory 🟢 Generation time is unchanged. 📅 Last benchmark: 2026-05-21 23:11:22 UTC You can retrigger the benchmark by commenting |
|
retrigger-benchmark |
Chunks were written as Status=full but without lighting, so off-disk LOD/pre-gen tools (Voxy, Chunky) rendered them dark until visited and relit in-game. Compute SkyLight (vertical cast + flood-fill) and BlockLight (flood-fill from emitters) per section and set isLightOn=1 so the light engine loads them as LIGHT_AND_DATA immediately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- tinted_glass blocks all light: exclude it from the glass transparency rule - honour `lit` blockstate for campfire/soul_campfire/redstone_torch emission - seed the skylight queue during the vertical cast, dropping the second scan Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- restrict skylight flood-fill to the occupied band; bulk-fill open sky above the highest opaque block (empty/low chunks become near-free) - return ordered Vec and move light arrays into NBT instead of cloning - treat fences/walls/bars/doors as light-transparent (slabs/stairs stay opaque due to shape occlusion) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Model light opacity as 0 (passes) / 1 (attenuates) / 15 (blocks) instead of a transparent/opaque boolean, and reduce the skylight cast by 1 per attenuating block. Fixes over-bright underwater columns and gives natural soft shade under tree canopies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0a8cb3b to
eeb06f7
Compare
| queue: &mut std::collections::VecDeque<(usize, usize, usize, u8)>| { | ||
| let g = idx(nx, ny, nz); | ||
| if opacity[g] < 15 && light[g] < next { | ||
| light[g] = next; | ||
| queue.push_back((nx, ny, nz, next)); |
Baked lighting is only needed for off-disk LOD renderers (Voxy/Chunky); vanilla relights on load. Gate it behind a `--bake-lighting` CLI flag and a GUI toggle (translated into all locales), defaulting off so standard generation keeps its prior speed and behavior (isLightOn=0, no light arrays). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests cover: baked chunks carry 2048-byte SkyLight/BlockLight per section with isLightOn=1, the no-bake path omits them with isLightOn=0, and an all-air chunk is fully skylit. Also give the Legacy terrain toggle the same yellow accent as the other toggles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Chunks were written as Status=full but without lighting, so off-disk LOD/pre-gen tools (Voxy, Chunky) rendered them dark until visited and relit in-game. Compute SkyLight (vertical cast + flood-fill) and BlockLight (flood-fill from emitters) per section and set isLightOn=1 so the light engine loads them as LIGHT_AND_DATA immediately.