Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort render regions by distance from camera #2133

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private void createTerrainRenderList(Camera camera, Viewport viewport, int frame

this.occlusionCuller.findVisible(visitor, viewport, searchDistance, useOcclusionCulling, frame);

this.renderLists = visitor.createRenderLists();
this.renderLists = visitor.createRenderLists(camera.getPos());
this.rebuildLists = visitor.getRebuildLists();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class ChunkRenderList {

private int lastVisibleFrame;

private double distanceFromCamera;

public ChunkRenderList(RenderRegion region) {
this.region = region;
}
Expand Down Expand Up @@ -101,4 +103,14 @@ public RenderRegion getRegion() {
return this.region;
}

/**
* Get the squared distance of this region from the camera.
*/
public double getDistanceFromCamera() {
embeddedt marked this conversation as resolved.
Show resolved Hide resolved
return this.distanceFromCamera;
}

public void setDistanceFromCamera(double d) {
this.distanceFromCamera = d;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import me.jellysquid.mods.sodium.client.render.chunk.RenderSection;
import me.jellysquid.mods.sodium.client.util.iterator.ReversibleObjectArrayIterator;
import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegion;
import net.minecraft.util.math.Vec3d;

import java.util.Comparator;

public class SortedRenderLists implements ChunkRenderListIterable {
private static final SortedRenderLists EMPTY = new SortedRenderLists(ObjectArrayList.of());
Expand All @@ -24,6 +27,7 @@ public static SortedRenderLists empty() {
}

public static class Builder {
private static final Comparator<ChunkRenderList> LIST_DISTANCE_COMPARATOR = Comparator.comparingDouble(ChunkRenderList::getDistanceFromCamera);
private final ObjectArrayList<ChunkRenderList> lists = new ObjectArrayList<>();
private final int frame;

Expand All @@ -44,7 +48,17 @@ public void add(RenderSection section) {
list.add(section);
}

public SortedRenderLists build() {
public SortedRenderLists build(Vec3d cameraPos) {
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < this.lists.size(); i++) {
ChunkRenderList renderList = this.lists.get(i);
RenderRegion region = renderList.getRegion();
double dx = cameraPos.x - region.getCenterX();
double dy = cameraPos.y - region.getCenterY();
double dz = cameraPos.z - region.getCenterZ();
renderList.setDistanceFromCamera((dx * dx) + (dy * dy) + (dz * dz));
}
this.lists.sort(LIST_DISTANCE_COMPARATOR);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be faster to use unstableSort here because that can use quicksort which is allocation free. I can't think of a reason for a stable sort to be necessary. ObjectArrayList does a stable sort by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this implementation of quicksort O(n) on sorted inputs? I think sort uses timsort which should have that behavior.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah the default Arrays.sort that it uses for stable sort might just be better. The quicksort is kinda hard to read so I'm not sure it'd actually fare better.

return new SortedRenderLists(this.lists);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import me.jellysquid.mods.sodium.client.render.chunk.ChunkUpdateType;
import me.jellysquid.mods.sodium.client.render.chunk.RenderSection;
import net.minecraft.util.math.Vec3d;

import java.util.ArrayDeque;
import java.util.EnumMap;
Expand Down Expand Up @@ -43,8 +44,8 @@ private void addToRebuildLists(RenderSection section) {
}
}

public SortedRenderLists createRenderLists() {
return this.sortedRenderLists.build();
public SortedRenderLists createRenderLists(Vec3d cameraPos) {
return this.sortedRenderLists.build(cameraPos);
}

public Map<ChunkUpdateType, ArrayDeque<RenderSection>> getRebuildLists() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ public int getOriginZ() {
return this.getChunkZ() << 4;
}

public int getCenterX() {
return (this.getChunkX() + REGION_WIDTH / 2) << 4;
}

public int getCenterY() {
return (this.getChunkY() + REGION_HEIGHT / 2) << 4;
}

public int getCenterZ() {
return (this.getChunkZ() + REGION_LENGTH / 2) << 4;
}

public void delete(CommandList commandList) {
for (var storage : this.sectionRenderData.values()) {
storage.delete();
Expand Down