From 78f84f17cd2a731bc025f933604e8eae7462ba3e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 18 May 2026 22:24:27 -0500 Subject: [PATCH] Fix holes on LOD borders --- .../render/bufferBuilding/ColumnBox.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java index 91116a745..c0e1c8727 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java @@ -321,18 +321,34 @@ public class ColumnBox if (!adjTransparent) { // Adjacent is opaque - boolean adjacentCoversThis = - !adjacentIsSameDetailLevel - && RenderDataPointUtil.getYMax(adjPoint) >= caveCullingMaxY - && - ( - (x == 0 && direction == EDhDirection.WEST) - || (z == 0 && direction == EDhDirection.NORTH) - || (x == 256 && direction == EDhDirection.EAST) - || (z == 256 && direction == EDhDirection.SOUTH) - ); - lightToApply = adjacentCoversThis ? adjSkyLight : SKYLIGHT_COVERED; + // The following logic is done to provide a little bit of overdraw to + // prevent holes when low detail LODs are replaced by higher-detail ones + // when moving. + // If not done higher quality LODs can cause holes due to not + // covering the whole face like the lower detail LODs they replaced, + // while still culling most LODs that are covered by other blocks. + + boolean onBorder = + (direction == EDhDirection.WEST && x == 0) + || (direction == EDhDirection.NORTH && z == 0) + || (direction == EDhDirection.EAST && x == ((horizontalBlockWidth) * (ColumnRenderSource.WIDTH))) + || (direction == EDhDirection.SOUTH && z == ((horizontalBlockWidth) * (ColumnRenderSource.WIDTH))); + + boolean isLit = + RenderDataPointUtil.getLightSky(adjPoint) != LodUtil.MIN_MC_LIGHT + || RenderDataPointUtil.getLightBlock(adjPoint) != LodUtil.MIN_MC_LIGHT; + + // render the face if... + boolean useAdjLighting = + // we're on the border... (holes can only happen on LOD borders since faces inside an LOD will always be the same detail level) + onBorder + // ...this face has some sort of lighting... (0 light generally means the face is covered by other blocks) + && isLit + // ...and is above the culling height + && RenderDataPointUtil.getYMax(adjPoint) >= caveCullingMaxY; + + lightToApply = useAdjLighting ? adjSkyLight : SKYLIGHT_COVERED; } else {