Add proper frustum check
This commit is contained in:
@@ -1,18 +1,41 @@
|
||||
package me.cortex.voxy.client.core.rendering;
|
||||
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public abstract class Viewport <A extends Viewport<A>> {
|
||||
private static final Field planesField;
|
||||
static {
|
||||
try {
|
||||
planesField = FrustumIntersection.class.getDeclaredField("planes");
|
||||
planesField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
public int frameId;
|
||||
public Matrix4f projection;
|
||||
public Matrix4f modelView;
|
||||
public final FrustumIntersection frustum = new FrustumIntersection();
|
||||
public final Vector4f[] frustumPlanes;
|
||||
public double cameraX;
|
||||
public double cameraY;
|
||||
public double cameraZ;
|
||||
|
||||
protected Viewport() {
|
||||
Vector4f[] planes = null;
|
||||
try {
|
||||
planes = (Vector4f[]) planesField.get(this.frustum);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.frustumPlanes = planes;
|
||||
}
|
||||
|
||||
public final void delete() {
|
||||
@@ -43,4 +66,9 @@ public abstract class Viewport <A extends Viewport<A>> {
|
||||
this.height = height;
|
||||
return (A) this;
|
||||
}
|
||||
|
||||
public A updateFrustum() {
|
||||
this.frustum.set(new Matrix4f(this.projection).mul(this.modelView), false);
|
||||
return (A) this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,8 @@ public class VoxyRenderSystem {
|
||||
.setProjection(projection)
|
||||
.setModelView(matrices.peek().getPositionMatrix())
|
||||
.setCamera(cameraX, cameraY, cameraZ)
|
||||
.setScreenSize(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight);
|
||||
.setScreenSize(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight)
|
||||
.updateFrustum();
|
||||
viewport.frameId++;
|
||||
|
||||
|
||||
|
||||
@@ -12,10 +12,14 @@ import me.cortex.voxy.client.core.rendering.Viewport;
|
||||
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static me.cortex.voxy.client.core.rendering.PrintfDebugUtil.PRINTF_processor;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL12.GL_UNPACK_IMAGE_HEIGHT;
|
||||
@@ -116,6 +120,14 @@ public class HierarchicalOcclusionTraverser {
|
||||
.ssboIf("STATISTICS_BUFFER_BINDING", this.statisticsBuffer);
|
||||
}
|
||||
|
||||
|
||||
private static void setFrustum(Viewport<?> viewport, long ptr) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
var plane = viewport.frustumPlanes[i];
|
||||
plane.getToAddress(ptr); ptr += 4*4;
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadUniform(Viewport<?> viewport) {
|
||||
long ptr = UploadStream.INSTANCE.upload(this.uniformBuffer, 0, 1024);
|
||||
int sx = MathHelper.floor(viewport.cameraX)>>5;
|
||||
@@ -135,6 +147,8 @@ public class HierarchicalOcclusionTraverser {
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, viewport.height); ptr += 4;
|
||||
|
||||
setFrustum(viewport, ptr); ptr += 4*4*6;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, (int) (this.renderList.size()/4-1)); ptr += 4;
|
||||
|
||||
|
||||
|
||||
14
src/main/resources/assets/voxy/shaders/lod/frustum.glsl
Normal file
14
src/main/resources/assets/voxy/shaders/lod/frustum.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
struct Frustum {
|
||||
vec4 planes[6];
|
||||
};
|
||||
|
||||
bool testPlane(vec4 plane, vec3 base, float size) {
|
||||
return dot(plane.xyz, base+mix(vec3(size), vec3(0), lessThan(plane.xyz, vec3(0)))) >= -plane.w;
|
||||
}
|
||||
|
||||
//TODO: optimize this, this can be done by computing the base point value, then multiplying and adding a seperate value by the size
|
||||
bool outsideFrustum(in Frustum frustum, vec3 pos, float size) {
|
||||
return !(testPlane(frustum.planes[0], pos, size) && testPlane(frustum.planes[1], pos, size) &&
|
||||
testPlane(frustum.planes[2], pos, size) && testPlane(frustum.planes[3], pos, size) &&
|
||||
testPlane(frustum.planes[4], pos, size));//Dont need to test far plane
|
||||
}
|
||||
@@ -58,13 +58,16 @@ void setupScreenspace(in UnpackedNode node) {
|
||||
+ (transform.worldPos.xyz-camChunkPos))-camSubChunk);
|
||||
*/
|
||||
|
||||
//TODO: AABB SIZES not just a max cube
|
||||
|
||||
//vec3 minPos = minSize + basePos;
|
||||
//vec3 maxPos = maxSize + basePos;
|
||||
|
||||
vec3 basePos = vec3(((node.pos<<node.lodLevel)-camSecPos)<<5)-camSubSecPos;
|
||||
|
||||
insideFrustum = !outsideFrustum(frustum, basePos, float(32<<node.lodLevel));
|
||||
|
||||
//Fast exit
|
||||
if (!insideFrustum) {
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 P000 = VP * vec4(basePos, 1);
|
||||
mat3x4 Axis = mat3x4(VP) * float(32<<node.lodLevel);
|
||||
|
||||
@@ -76,13 +79,6 @@ void setupScreenspace(in UnpackedNode node) {
|
||||
vec4 P011 = Axis[1] + P001;
|
||||
vec4 P111 = Axis[1] + P101;
|
||||
|
||||
insideFrustum = checkPointInView(P000) || checkPointInView(P100) || checkPointInView(P001) || checkPointInView(P101) ||
|
||||
checkPointInView(P010) || checkPointInView(P110) || checkPointInView(P011) || checkPointInView(P111);
|
||||
|
||||
//Fast exit
|
||||
if (!insideFrustum) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Perspective divide + convert to screenspace (i.e. range 0->1 if within viewport)
|
||||
vec3 p000 = (P000.xyz/P000.w) * 0.5f + 0.5f;
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
#define LOCAL_SIZE (1<<LOCAL_SIZE_BITS)
|
||||
layout(local_size_x=LOCAL_SIZE) in;//, local_size_y=1
|
||||
|
||||
#import <voxy:lod/frustum.glsl>
|
||||
|
||||
layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform {
|
||||
mat4 VP;
|
||||
ivec3 camSecPos;
|
||||
float screenW;
|
||||
vec3 camSubSecPos;
|
||||
float screenH;
|
||||
Frustum frustum;
|
||||
uint renderQueueMaxSize;
|
||||
float minSSS;
|
||||
uint frameId;
|
||||
|
||||
Reference in New Issue
Block a user