some block light fixes

This commit is contained in:
Moritz Zwerger 2025-03-26 16:48:29 +01:00
parent 25e8fbbde8
commit 44a7601f48
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 20 additions and 20 deletions

View File

@ -43,5 +43,4 @@ class GeneralHeightmapTest {
chunk[InChunkPosition(2, 255, 3)] = GlassTest0.state chunk[InChunkPosition(2, 255, 3)] = GlassTest0.state
assertEquals(chunk.light.heightmap[2, 3], Int.MIN_VALUE) assertEquals(chunk.light.heightmap[2, 3], Int.MIN_VALUE)
} }
} }

View File

@ -204,9 +204,8 @@ class BlockLightPlaceIT {
chunk.assertLight(9, 256, 8, 0xFC) chunk.assertLight(9, 256, 8, 0xFC)
} }
@Test(enabled = false) // TODO: update heightmap of neighbours on change
fun bottomHeightmap() { fun bottomHeightmap() {
val world = SessionTestUtil.createSession(4).world val world = SessionTestUtil.createSession(4, light = true).world
world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1) world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1)
world.assertLight(8, -1, 8, 0x00) world.assertLight(8, -1, 8, 0x00)
@ -218,9 +217,8 @@ class BlockLightPlaceIT {
world.assertLight(+8, -1, -4, 0x00) world.assertLight(+8, -1, -4, 0x00)
} }
@Test(enabled = false) // TODO: update heightmap of neighbours on change
fun bottomPropagation() { fun bottomPropagation() {
val world = SessionTestUtil.createSession(4).world val world = SessionTestUtil.createSession(4, light = true).world
world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1) world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1)
world[BlockPosition(8, 0, 8)] = TorchTest0.state world[BlockPosition(8, 0, 8)] = TorchTest0.state
@ -228,7 +226,7 @@ class BlockLightPlaceIT {
world.assertLight(9, -1, 8, 0x0C) world.assertLight(9, -1, 8, 0x0C)
world.assertLight(+20, -1, +8, 0x01) world.assertLight(+20, -1, +8, 0x01)
world.assertLight(+8, -1, +8, 0x01) world.assertLight(+8, -1, +20, 0x01)
world.assertLight(-4, -1, +8, 0x01) world.assertLight(-4, -1, +8, 0x01)
world.assertLight(+8, -1, -4, 0x01) world.assertLight(+8, -1, -4, 0x01)
} }

View File

@ -153,7 +153,7 @@ class SectionLight(
} }
val height = section.chunk.light.heightmap[position.xz] val height = section.chunk.light.heightmap[position.xz]
if (position.y + section.height * SECTION_HEIGHT_Y >= height) { // TODO: > or >= if (section.height * SECTION_HEIGHT_Y + position.y >= height) {
level = level.with(sky = 0) // level is set with heightmap, no need to trace anything level = level.with(sky = 0) // level is set with heightmap, no need to trace anything
} }
@ -180,7 +180,7 @@ class SectionLight(
event = true event = true
} }
fun calculate() { private fun calculateBlocks() {
if (section.blocks.isEmpty) return if (section.blocks.isEmpty) return
val min = section.blocks.minPosition val min = section.blocks.minPosition
val max = section.blocks.maxPosition val max = section.blocks.maxPosition
@ -197,11 +197,15 @@ class SectionLight(
} }
} }
} }
// TODO: Start skylight tracing from heightmap start max per xz }
fun calculate() {
calculateBlocks()
// TODO: Start skylight tracing from (top of the world (max neighbour heightmap) to heightmap start) per xz
} }
protected fun getNeighbour(direction: Directions): SectionLight? { protected fun getNeighbour(direction: Directions): SectionLight? {
return section.chunk.neighbours[direction]?.sections?.get(section.height)?.light return section.chunk.neighbours[direction]?.get(section.height)?.light
} }
private fun propagateVertical() { private fun propagateVertical() {

View File

@ -39,14 +39,14 @@ class BottomSectionLight(
val height = chunk.light.heightmap[position.xz] val height = chunk.light.heightmap[position.xz]
if (position.y + chunk.minSection * SECTION_HEIGHT_Y >= height) { // TODO: > or >= if ((chunk.minSection - 1) * SECTION_HEIGHT_Y + SECTION_MAX_Y >= height) {
level = level.with(sky = 0) // level is set with heightmap, no need to trace anything level = level.with(sky = 0) // level is set with heightmap, no need to trace anything
} }
light[position.xz] = level.raw light[position.xz] = level.raw
if (level.block <= 1 && level.sky <= 1) return // can not increase further if (level.block <= 1 && level.sky <= 1) return // can not decrease any further
val next = current.decrease() val next = level.decrease()
chunk.getOrPut(chunk.minSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.UP) chunk.getOrPut(chunk.minSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.UP)
traceVertical(position, next) traceVertical(position, next)
@ -59,7 +59,7 @@ class BottomSectionLight(
override fun propagate() { override fun propagate() {
super.propagateVertical() super.propagateVertical()
val section = chunk.sections.first()?.light ?: return val section = chunk[chunk.minSection]?.light ?: return
for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) { for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) {
val position = InSectionPosition(xz).with(y = 0) val position = InSectionPosition(xz).with(y = 0)
section.traceFrom(position, Directions.DOWN) section.traceFrom(position, Directions.DOWN)

View File

@ -36,9 +36,9 @@ class TopSectionLight(
if (current.block >= level.block) return if (current.block >= level.block) return
light[position.xz] = level.raw light[position.xz] = level.raw
if (current.block <= 1) return // can not increase further if (level.block <= 1) return // can not decrease any further
val next = LightLevel(block = current.block - 1, sky = 0) // remove sky light, its always max val next = LightLevel(block = level.block - 1, sky = 0) // remove sky light, its always max
chunk.getOrPut(chunk.maxSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.DOWN) chunk.getOrPut(chunk.maxSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.DOWN)
traceVertical(position, next) traceVertical(position, next)
@ -48,11 +48,10 @@ class TopSectionLight(
System.arraycopy(array.array, InSectionPosition(0, 0, 0).index, this.light, 0, SECTION_WIDTH_X * SECTION_WIDTH_Z) System.arraycopy(array.array, InSectionPosition(0, 0, 0).index, this.light, 0, SECTION_WIDTH_X * SECTION_WIDTH_Z)
} }
override fun propagate() { override fun propagate() {
super.propagateVertical() super.propagateVertical()
val section = chunk.sections.last()?.light ?: return val section = chunk[chunk.maxSection]?.light ?: return
for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) { for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) {
val position = InSectionPosition(xz).with(y = SECTION_MAX_Y) val position = InSectionPosition(xz).with(y = SECTION_MAX_Y)
section.traceFrom(position, Directions.UP) section.traceFrom(position, Directions.UP)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger * Copyright (C) 2020-2025 Moritz Zwerger
* *
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* *
@ -40,7 +40,7 @@ class RenderLight(val context: RenderContext) {
) )
) { ) {
DefaultThreadPool += { DefaultThreadPool += {
session.world.recalculateLight() session.world.recalculateLight(heightmap = true)
session.util.sendDebugMessage("Light recalculated and chunk cache cleared!") session.util.sendDebugMessage("Light recalculated and chunk cache cleared!")
} }
} }