add frustum culling

This commit is contained in:
NULL511
2024-01-25 17:46:30 -05:00
parent 4cb2bb97a8
commit 7e287dab71
3 changed files with 74 additions and 17 deletions
@@ -0,0 +1,37 @@
package com.seibel.distanthorizons.core.pos;
import org.joml.Math;
import org.joml.Matrix4f;
import org.joml.Vector3f;
public class DhFrustumBounds
{
private final Vector3f boundsMin = new Vector3f();
private final Vector3f boundsMax = new Vector3f();
public DhFrustumBounds(Matrix4f matViewProjectionInv)
{
matViewProjectionInv.frustumAabb(this.boundsMin, this.boundsMax);
}
public boolean Intersects(DhLodPos lodBounds)
{
// TODO
float worldMinY = 0f;
float worldMaxY = 0f;
int lodPosX = lodBounds.getX().toBlockWidth();
int lodPosZ = lodBounds.getZ().toBlockWidth();
int lodSize = lodBounds.getBlockWidth();
Vector3f lodMin = new Vector3f(lodPosX, worldMinY, lodPosZ);
Vector3f lodMax = new Vector3f(lodPosX + lodSize, worldMaxY, lodPosZ + lodSize);
if (lodMax.x < boundsMin.x || lodMin.x > boundsMax.x) return false;
//if (lodMax.y < boundsMin.y || lodMin.y > boundsMax.y) return false;
if (lodMax.z < boundsMin.z || lodMin.z > boundsMax.z) return false;
return true;
}
}
@@ -23,14 +23,19 @@ import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.pos.DhFrustumBounds;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.pos.Pos2D;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
import org.apache.logging.log4j.Logger;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import java.util.Comparator;
import java.util.Iterator;
@@ -82,7 +87,7 @@ public class RenderBufferHandler implements AutoCloseable
* TODO: This might get locked by update() causing move() call. Is there a way to avoid this?
* Maybe dupe the base list and use atomic swap on render? Or is this not worth it?
*/
public void buildRenderListAndUpdateSections(Vec3f lookForwardVector)
public void buildRenderListAndUpdateSections(Matrix4f matViewProjectionInv, Vector3f lookForwardVector)
{
EDhDirection[] axisDirections = new EDhDirection[3];
@@ -187,6 +192,8 @@ public class RenderBufferHandler implements AutoCloseable
// Build the sorted list
this.loadedNearToFarBuffers = new SortedArraySet<>((a, b) -> -farToNearComparator.compare(a, b)); // TODO is the comparator named wrong?
DhFrustumBounds frustumBounds = new DhFrustumBounds(matViewProjectionInv);
// Update the sections
boolean rebuildAllBuffers = this.rebuildAllBuffers.getAndSet(false);
Iterator<QuadNode<LodRenderSection>> nodeIterator = this.lodQuadTree.nodeIterator();
@@ -196,26 +203,25 @@ public class RenderBufferHandler implements AutoCloseable
DhSectionPos sectionPos = node.sectionPos;
LodRenderSection renderSection = node.value;
if (renderSection == null) continue;
try
{
DhLodPos lodBounds = renderSection.pos.getSectionBBoxPos();
if (!frustumBounds.Intersects(lodBounds)) continue;
if (renderSection != null)
if (rebuildAllBuffers)
{
if (rebuildAllBuffers)
{
renderSection.markBufferDirty();
}
renderSection.tryBuildAndSwapBuffer();
if (renderSection.isRenderingEnabled())
{
AbstractRenderBuffer buffer = renderSection.activeRenderBufferRef.get();
if (buffer != null)
{
this.loadedNearToFarBuffers.add(new LoadedRenderBuffer(buffer, sectionPos));
}
}
renderSection.markBufferDirty();
}
renderSection.tryBuildAndSwapBuffer();
if (!renderSection.isRenderingEnabled()) continue;
AbstractRenderBuffer buffer = renderSection.activeRenderBufferRef.get();
if (buffer == null) continue;
this.loadedNearToFarBuffers.add(new LoadedRenderBuffer(buffer, sectionPos));
}
catch (Exception e)
{
@@ -47,6 +47,8 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
import org.apache.logging.log4j.LogManager;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL32;
import java.awt.*;
@@ -330,7 +332,19 @@ public class LodRenderer
if (renderingFirstPass)
{
this.bufferHandler.buildRenderListAndUpdateSections(this.getLookVector());
final Vector3f WorldUp = new Vector3f(0f, 1f, 0f);
Vec3f _lookAt = this.getLookVector();
Vector3f lookAt = new Vector3f(_lookAt.x, _lookAt.y, _lookAt.z);
Vec3d cameraPos = MC_RENDER.getCameraExactPosition();
Matrix4f matViewProjectionInv = new Matrix4f()
.setTransposed(projectionMatrix.getValuesAsArray())
.lookAlong(lookAt, WorldUp)
.translate(-(float)cameraPos.x, -(float)cameraPos.y, -(float)cameraPos.z)
.invert();
this.bufferHandler.buildRenderListAndUpdateSections(matViewProjectionInv, lookAt);
transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled;