Skip to content

Commit

Permalink
add angle-based section visibility path occlusion, cherry picked from…
Browse files Browse the repository at this point in the history
… douira:sharp-angle-traversal-occlusion
  • Loading branch information
douira committed Oct 11, 2024
1 parent d574dab commit b1388e4
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,16 @@ private void processQueue(ReadQueue<RenderSection> readQueue,

{
if (this.useOcclusionCulling) {
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(this.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, section.getIncomingDirections());
} else {
// Not using any occlusion culling, so traversing in any direction is legal.
connections = GraphDirectionSet.ALL;
Expand All @@ -127,6 +133,30 @@ private void processQueue(ReadQueue<RenderSection> readQueue,
}
}

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 isWithinRenderDistance(CameraTransform camera, RenderSection section, float maxDistance) {
// origin point of the chunk's bounding box (in view space)
int ox = section.getOriginX() - camera.intX;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit b1388e4

Please sign in to comment.