Skip to content

Commit

Permalink
fix sorting by using correct section pos calculation and improve frus…
Browse files Browse the repository at this point in the history
…tum task list update
  • Loading branch information
douira committed Dec 7, 2024
1 parent b3d4b7c commit df32670
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class RenderSectionManager {
private boolean needsGraphUpdate = true;
private boolean needsRenderListUpdate = true;
private boolean cameraChanged = false;
private boolean needsFrustumTaskListUpdate = true;

private @Nullable BlockPos cameraBlockPos;
private @Nullable Vector3dc cameraPosition;
Expand Down Expand Up @@ -154,6 +155,7 @@ public void updateRenderLists(Camera camera, Viewport viewport, boolean spectato

this.frame += 1;
this.needsRenderListUpdate |= this.cameraChanged;
this.needsFrustumTaskListUpdate |= this.needsRenderListUpdate;

// do sync bfs based on update immediately (flawless frames) or if the camera moved too much
var shouldRenderSync = this.cameraTimingControl.getShouldRenderSync(camera);
Expand Down Expand Up @@ -186,11 +188,15 @@ public void updateRenderLists(Camera camera, Viewport viewport, boolean spectato

this.scheduleAsyncWork(camera, viewport, spectator);

if (this.needsFrustumTaskListUpdate) {
this.updateFrustumTaskList(viewport);
}
if (this.needsRenderListUpdate) {
processRenderListUpdate(viewport);
}

this.needsRenderListUpdate = false;
this.needsFrustumTaskListUpdate = false;
this.needsGraphUpdate = false;
this.cameraChanged = false;
}
Expand Down Expand Up @@ -341,7 +347,7 @@ private CullType[] getScheduleOrder() {

private static final LongArrayList timings = new LongArrayList();

private void processRenderListUpdate(Viewport viewport) {
private void updateFrustumTaskList(Viewport viewport) {
// schedule generating a frustum task list if there's no frustum tree task running
if (this.globalTaskTree != null) {
var frustumTaskListPending = false;
Expand All @@ -359,7 +365,9 @@ private void processRenderListUpdate(Viewport viewport) {
this.pendingTasks.add(task);
}
}
}

private void processRenderListUpdate(Viewport viewport) {
// pick the narrowest up-to-date tree, if this tree is insufficiently up to date we would've switched to sync bfs earlier
SectionTree bestTree = null;
boolean bestTreeValid = false;
Expand Down Expand Up @@ -907,7 +915,6 @@ public int getVisibleChunkCount() {
// TODO: this fixes very delayed tasks, but it still regresses on same-frame tasks that don't get to run in time because the frustum task collection task takes at least one (and usually only one) frame to run
// maybe intercept tasks that are scheduled in zero- or one-frame defer mode?
// collect and prioritize regardless of visibility if it's an important defer mode?
// TODO: vertical sorting seems to be broken?
private ChunkUpdateType upgradePendingUpdate(RenderSection section, ChunkUpdateType type) {
var current = section.getPendingUpdate();
type = ChunkUpdateType.getPromotionUpdateType(current, type);
Expand All @@ -917,6 +924,7 @@ private ChunkUpdateType upgradePendingUpdate(RenderSection section, ChunkUpdateT
// if the section received a new task, mark in the task tree so an update can happen before a global cull task runs
if (this.globalTaskTree != null && type != null && current == null) {
this.globalTaskTree.markSectionTask(section);
this.needsFrustumTaskListUpdate = true;
}

return type;
Expand Down Expand Up @@ -955,13 +963,7 @@ public void scheduleRebuild(int x, int y, int z, boolean important) {
pendingUpdate = ChunkUpdateType.REBUILD;
}

pendingUpdate = ChunkUpdateType.getPromotionUpdateType(section.getPendingUpdate(), pendingUpdate);
if (pendingUpdate != null) {
section.setPendingUpdate(pendingUpdate, this.lastFrameAtTime);

// force update to schedule rebuild task on this section
this.markGraphDirty();
}
this.upgradePendingUpdate(section, pendingUpdate);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,22 @@ public PendingTaskCollector(Viewport viewport, float buildDistance, boolean frus
this.isFrustumTested = frustumTested;
var offsetDistance = Mth.ceil(buildDistance / 16.0f) + 1;

var transform = viewport.getTransform();

// the offset applied to section coordinates to encode their position in the octree
var cameraSectionX = transform.intX >> 4;
var cameraSectionY = transform.intY >> 4;
var cameraSectionZ = transform.intZ >> 4;
var sectionPos = viewport.getChunkCoord();
var cameraSectionX = sectionPos.getX();
var cameraSectionY = sectionPos.getY();
var cameraSectionZ = sectionPos.getZ();
this.baseOffsetX = cameraSectionX - offsetDistance;
this.baseOffsetY = cameraSectionY - offsetDistance;
this.baseOffsetZ = cameraSectionZ - offsetDistance;

this.invMaxDistance = PROXIMITY_FACTOR / buildDistance;

if (frustumTested) {
this.cameraX = transform.intX;
this.cameraY = transform.intY;
this.cameraZ = transform.intZ;
var blockPos = viewport.getBlockCoord();
this.cameraX = blockPos.getX();
this.cameraY = blockPos.getY();
this.cameraZ = blockPos.getZ();
} else {
this.cameraX = (cameraSectionX << 4);
this.cameraY = (cameraSectionY << 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,10 @@ public int getFrame() {
}

public boolean isValidFor(Viewport viewport, float searchDistance) {
var transform = viewport.getTransform();
var cameraSectionX = transform.intX >> 4;
var cameraSectionY = transform.intY >> 4;
var cameraSectionZ = transform.intZ >> 4;
return this.cameraX >> 4 == cameraSectionX &&
this.cameraY >> 4 == cameraSectionY &&
this.cameraZ >> 4 == cameraSectionZ &&
var cameraPos = viewport.getChunkCoord();
return this.cameraX >> 4 == cameraPos.getX() &&
this.cameraY >> 4 == cameraPos.getY() &&
this.cameraZ >> 4 == cameraPos.getZ() &&
this.buildDistance >= searchDistance;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public void calculateReduced() {

@Override
public void traverse(SectionTree.VisibleSectionVisitor visitor, Viewport viewport, float distanceLimit) {
var transform = viewport.getTransform();
var cameraSectionX = transform.intX >> 4;
var cameraSectionY = transform.intY >> 4;
var cameraSectionZ = transform.intZ >> 4;
var cameraPos = viewport.getChunkCoord();
var cameraSectionX = cameraPos.getX();
var cameraSectionY = cameraPos.getY();
var cameraSectionZ = cameraPos.getZ();

// sort the trees by distance from the camera by sorting a packed index array.
var items = new int[this.trees.length];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ public void traverse(SectionTree.VisibleSectionVisitor visitor, Viewport viewpor
this.viewport = viewport;
this.distanceLimit = distanceLimit;

var transform = viewport.getTransform();

// + 1 to offset section position to compensate for shifted global offset
// adjust camera block position to account for fractional part of camera position
this.cameraOffsetX = ((transform.intX + (int) Math.signum(transform.fracX)) >> 4) - this.offsetX + 1;
this.cameraOffsetY = ((transform.intY + (int) Math.signum(transform.fracY)) >> 4) - this.offsetY + 1;
this.cameraOffsetZ = ((transform.intZ + (int) Math.signum(transform.fracZ)) >> 4) - this.offsetZ + 1;
var sectionPos = viewport.getChunkCoord();
this.cameraOffsetX = sectionPos.getX() - this.offsetX + 1;
this.cameraOffsetY = sectionPos.getY() - this.offsetY + 1;
this.cameraOffsetZ = sectionPos.getZ() - this.offsetZ + 1;

// everything is already inside the distance limit if the build distance is smaller
var initialInside = this.distanceLimit >= buildDistance ? INSIDE_DISTANCE : 0;
Expand Down

0 comments on commit df32670

Please sign in to comment.