From 2914d380592235ec0985595677633c6b94039d2a Mon Sep 17 00:00:00 2001 From: douira Date: Sat, 12 Oct 2024 01:14:21 +0200 Subject: [PATCH 1/2] add angle-based section visibility path occlusion --- .../chunk/occlusion/OcclusionCuller.java | 33 ++++++++++++++++++- .../chunk/occlusion/VisibilityEncoding.java | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java index 3bd0376297..7b2743f348 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java @@ -61,10 +61,17 @@ private static void processQueue(Visitor visitor, { if (useOcclusionCulling) { + var incomingDirections = section.getIncomingDirections(); + var sectionVisibilityData = section.getVisibilityData(); + + // occlude paths through the section if it's being viewed at an angle where + // the other side can't possibly be seen + sectionVisibilityData &= getAngleVisibilityMask(viewport, section); + // When using occlusion culling, we can only traverse into neighbors for which there is a path of // visibility through this chunk. This is determined by taking all the incoming paths to this chunk and // creating a union of the outgoing paths from those. - connections = VisibilityEncoding.getConnections(section.getVisibilityData(), section.getIncomingDirections()); + connections = VisibilityEncoding.getConnections(sectionVisibilityData, incomingDirections); } else { // Not using any occlusion culling, so traversing in any direction is legal. connections = GraphDirectionSet.ALL; @@ -79,6 +86,30 @@ private static void processQueue(Visitor visitor, } } + private static final long UP_DOWN_OCCLUDED = (1L << VisibilityEncoding.bit(GraphDirection.DOWN, GraphDirection.UP)) | (1L << VisibilityEncoding.bit(GraphDirection.UP, GraphDirection.DOWN)); + private static final long NORTH_SOUTH_OCCLUDED = (1L << VisibilityEncoding.bit(GraphDirection.NORTH, GraphDirection.SOUTH)) | (1L << VisibilityEncoding.bit(GraphDirection.SOUTH, GraphDirection.NORTH)); + private static final long WEST_EAST_OCCLUDED = (1L << VisibilityEncoding.bit(GraphDirection.WEST, GraphDirection.EAST)) | (1L << VisibilityEncoding.bit(GraphDirection.EAST, GraphDirection.WEST)); + + private static long getAngleVisibilityMask(Viewport viewport, RenderSection section) { + var transform = viewport.getTransform(); + var dx = Math.abs(transform.x - section.getCenterX()); + var dy = Math.abs(transform.y - section.getCenterY()); + var dz = Math.abs(transform.z - section.getCenterZ()); + + var angleOcclusionMask = 0L; + if (dx > dy || dz > dy) { + angleOcclusionMask |= UP_DOWN_OCCLUDED; + } + if (dx > dz || dy > dz) { + angleOcclusionMask |= NORTH_SOUTH_OCCLUDED; + } + if (dy > dx || dz > dx) { + angleOcclusionMask |= WEST_EAST_OCCLUDED; + } + + return ~angleOcclusionMask; + } + private static boolean isSectionVisible(RenderSection section, Viewport viewport, float maxDistance) { return isWithinRenderDistance(viewport.getTransform(), section, maxDistance) && isWithinFrustum(viewport, section); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/VisibilityEncoding.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/VisibilityEncoding.java index db7e9e88f7..cf184efde0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/VisibilityEncoding.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/VisibilityEncoding.java @@ -21,7 +21,7 @@ public static long encode(@NotNull VisibilitySet occlusionData) { return visibilityData; } - private static int bit(int from, int to) { + public static int bit(int from, int to) { return (from * 8) + to; } From 8125f13cc0b54b2d0a8dd4f84551927afadc7f4e Mon Sep 17 00:00:00 2001 From: douira Date: Sat, 12 Oct 2024 01:27:00 +0200 Subject: [PATCH 2/2] cleanup unused variable --- .../sodium/client/render/chunk/occlusion/OcclusionCuller.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java index 7b2743f348..95288386bb 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/occlusion/OcclusionCuller.java @@ -61,7 +61,6 @@ private static void processQueue(Visitor visitor, { if (useOcclusionCulling) { - var incomingDirections = section.getIncomingDirections(); var sectionVisibilityData = section.getVisibilityData(); // occlude paths through the section if it's being viewed at an angle where @@ -71,7 +70,7 @@ private static void processQueue(Visitor visitor, // When using occlusion culling, we can only traverse into neighbors for which there is a path of // visibility through this chunk. This is determined by taking all the incoming paths to this chunk and // creating a union of the outgoing paths from those. - connections = VisibilityEncoding.getConnections(sectionVisibilityData, incomingDirections); + connections = VisibilityEncoding.getConnections(sectionVisibilityData, section.getIncomingDirections()); } else { // Not using any occlusion culling, so traversing in any direction is legal. connections = GraphDirectionSet.ALL;