improve skylight performance

This commit is contained in:
Bixilon 2022-09-18 19:20:43 +02:00
parent 692ede9439
commit 1ea2378473
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
2 changed files with 29 additions and 19 deletions

View File

@ -556,11 +556,14 @@ class Chunk(
val section = sections?.get(sectionHeight - lowestSection) ?: continue
section.light.update = true
// ToDo: bare tracing
val baseY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
for (y in ProtocolDefinition.SECTION_MAX_Y downTo 0) {
section.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), Directions.UP, true)
section.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), null, baseY + y, true)
}
}
val sectionHeight = maxHeight.sectionHeight
val maxSection = sections?.get(maxHeight.sectionHeight - lowestSection)
val baseY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
if (maxSection != null) {
for (y in ProtocolDefinition.SECTION_MAX_Y downTo maxHeight.inSectionHeight) {
val index = (y shl 8) or heightmapIndex
@ -568,12 +571,15 @@ class Chunk(
if (block != null && !block.propagatesSkylight) {
continue
}
maxSection.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), Directions.UP, true)
maxSection.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), null, baseY + y, true)
}
maxSection.light.update = true
}
}
fun getMaxHeight(x: Int, z: Int): Int {
return skylightHeightmap[(z shl 4) or x]
}
}

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world.chunk.light
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.light.TransparentProperty
import de.bixilon.minosoft.data.world.chunk.ChunkNeighbours
import de.bixilon.minosoft.data.world.chunk.ChunkSection
import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.getIndex
@ -238,40 +239,43 @@ class SectionLight(
}
}
fun traceSkylight(x: Int, y: Int, z: Int, nextLevel: Int, direction: Directions, force: Boolean) {
fun traceSkylight(x: Int, y: Int, z: Int, nextLevel: Int, direction: Directions?, totalY: Int, force: Boolean) {
if (direction == Directions.UP && totalY >= section.chunk!!.getMaxHeight(x, z)) {
// this light level will be 15, don't care
return
}
val index = getIndex(x, y, z)
val currentLight = this[index].toInt()
val currentSkylight = (currentLight and SKY_LIGHT_MASK) shr 4
if (!force && currentSkylight >= nextLevel) {
if (!force && ((currentLight and SKY_LIGHT_MASK) shr 4) >= nextLevel) {
return
}
val light = section.blocks.unsafeGet(index)?.lightProperties
val light = section.blocks.unsafeGet(index)?.lightProperties ?: TransparentProperty
if (light != null && !light.propagatesLight) {
if (!light.propagatesLight) {
return
}
this.light[index] = ((currentLight and BLOCK_LIGHT_MASK) or (nextLevel shl 4)).toByte()
val nextNeighbourLevel = nextLevel - 1
// ToDo: Neighbours
if (y > 0 && (light == null || light.propagatesLight(direction, Directions.DOWN))) {
traceSkylight(x, y - 1, z, nextNeighbourLevel, Directions.DOWN, false)
if (y > 0 && direction != Directions.DOWN && (direction == null || light.propagatesLight(direction, Directions.DOWN))) {
traceSkylight(x, y - 1, z, nextNeighbourLevel, Directions.DOWN, totalY - 1, false)
}
if (y < ProtocolDefinition.SECTION_MAX_Y && (light == null || light.propagatesLight(direction, Directions.UP))) {
traceSkylight(x, y + 1, z, nextNeighbourLevel, Directions.UP, false)
if (y < ProtocolDefinition.SECTION_MAX_Y && direction != Directions.UP && direction != null && (light.propagatesLight(direction, Directions.UP))) {
traceSkylight(x, y + 1, z, nextNeighbourLevel, Directions.UP, totalY + 1, false)
}
if (z > 0 && (light == null || light.propagatesLight(direction, Directions.NORTH))) {
traceSkylight(x, y, z - 1, nextNeighbourLevel, Directions.NORTH, false)
if (z > 0 && direction != Directions.NORTH && (direction == null || light.propagatesLight(direction, Directions.NORTH))) {
traceSkylight(x, y, z - 1, nextNeighbourLevel, Directions.NORTH, totalY, false)
}
if (z < ProtocolDefinition.SECTION_MAX_Z && (light == null || light.propagatesLight(direction, Directions.SOUTH))) {
traceSkylight(x, y, z + 1, nextNeighbourLevel, Directions.SOUTH, false)
if (z < ProtocolDefinition.SECTION_MAX_Z && direction != Directions.SOUTH && (direction == null || light.propagatesLight(direction, Directions.SOUTH))) {
traceSkylight(x, y, z + 1, nextNeighbourLevel, Directions.SOUTH, totalY, false)
}
if (x > 0 && (light == null || light.propagatesLight(direction, Directions.WEST))) {
traceSkylight(x - 1, y, z, nextNeighbourLevel, Directions.WEST, false)
if (x > 0 && direction != Directions.WEST && (direction == null || light.propagatesLight(direction, Directions.WEST))) {
traceSkylight(x - 1, y, z, nextNeighbourLevel, Directions.WEST, totalY, false)
}
if (x < ProtocolDefinition.SECTION_MAX_X && (light == null || light.propagatesLight(direction, Directions.EAST))) {
traceSkylight(x + 1, y, z, nextNeighbourLevel, Directions.EAST, false)
if (x < ProtocolDefinition.SECTION_MAX_X && direction != Directions.EAST && (direction == null || light.propagatesLight(direction, Directions.EAST))) {
traceSkylight(x + 1, y, z, nextNeighbourLevel, Directions.EAST, totalY, false)
}
}