From ba69b893c8d532c8b01edd8d092629ea59ab1fc8 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 29 Mar 2023 20:17:00 -0700 Subject: [PATCH] We have planes at home - Don't use FrustumIntersection as intermediary for writing planes in indirect rendering. - Move all computation and writing to FlwUtil. - Remove corresponding methods from JOML class. --- .../core/uniform/FlwShaderUniforms.java | 6 +- .../com/jozufozu/flywheel/util/FlwUtil.java | 118 ++++++++++++++++++ .../util/joml/FrustumIntersection.java | 54 -------- 3 files changed, 122 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/FlwShaderUniforms.java b/src/main/java/com/jozufozu/flywheel/core/uniform/FlwShaderUniforms.java index 17c7ec3e9..0890650d4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/uniform/FlwShaderUniforms.java +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/FlwShaderUniforms.java @@ -9,6 +9,7 @@ import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.event.BeginFrameEvent; +import com.jozufozu.flywheel.util.FlwUtil; import com.jozufozu.flywheel.util.MatrixUtil; import com.mojang.blaze3d.systems.RenderSystem; @@ -128,9 +129,10 @@ public class FlwShaderUniforms implements ShaderUniforms { return; } - var shiftedCuller = RenderContext.createCuller(context.viewProjection(), -camX, -camY, -camZ); + var projection = MatrixUtil.toJoml(context.viewProjection()); + projection.translate(-camX, -camY, -camZ); - shiftedCuller.getJozuPackedPlanes(ptr + 128); + FlwUtil.writePackedFrustumPlanes(ptr + 128, projection); FRUSTUM_CAPTURE = false; } diff --git a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java index 1f45c196d..c8e31702a 100644 --- a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java @@ -6,6 +6,10 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.stream.Stream; +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.util.joml.Math; +import com.jozufozu.flywheel.util.joml.Matrix4f; import com.mojang.blaze3d.vertex.PoseStack; public class FlwUtil { @@ -74,4 +78,118 @@ public class FlwUtil { public static Set createWeakHashSet() { return Collections.newSetFromMap(new WeakHashMap<>()); } + + /** + * Writes the frustum planes of the given projection matrix to the given buffer.

+ * Uses a different format that is friendly towards an optimized instruction-parallel + * implementation of sphere-frustum intersection.

+ * The format is as follows:

+ * {@code vec4(nxX, pxX, nyX, pyX)}
+ * {@code vec4(nxY, pxY, nyY, pyY)}
+ * {@code vec4(nxZ, pxZ, nyZ, pyZ)}
+ * {@code vec4(nxW, pxW, nyW, pyW)}
+ * {@code vec2(nzX, pzX)}
+ * {@code vec2(nzY, pzY)}
+ * {@code vec2(nzZ, pzZ)}
+ * {@code vec2(nzW, pzW)}
+ *

+ * Writes 96 bytes to the buffer. + * + * @param ptr The buffer to write the planes to. + * @param m The projection matrix to compute the frustum planes for. + */ + public static void writePackedFrustumPlanes(long ptr, Matrix4f m) { + float nxX, nxY, nxZ, nxW; + float pxX, pxY, pxZ, pxW; + float nyX, nyY, nyZ, nyW; + float pyX, pyY, pyZ, pyW; + float nzX, nzY, nzZ, nzW; + float pzX, pzY, pzZ, pzW; + + float invl; + nxX = m.m03() + m.m00(); + nxY = m.m13() + m.m10(); + nxZ = m.m23() + m.m20(); + nxW = m.m33() + m.m30(); + invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ); + nxX *= invl; + nxY *= invl; + nxZ *= invl; + nxW *= invl; + + pxX = m.m03() - m.m00(); + pxY = m.m13() - m.m10(); + pxZ = m.m23() - m.m20(); + pxW = m.m33() - m.m30(); + invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ); + pxX *= invl; + pxY *= invl; + pxZ *= invl; + pxW *= invl; + + nyX = m.m03() + m.m01(); + nyY = m.m13() + m.m11(); + nyZ = m.m23() + m.m21(); + nyW = m.m33() + m.m31(); + invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ); + nyX *= invl; + nyY *= invl; + nyZ *= invl; + nyW *= invl; + + pyX = m.m03() - m.m01(); + pyY = m.m13() - m.m11(); + pyZ = m.m23() - m.m21(); + pyW = m.m33() - m.m31(); + invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ); + pyX *= invl; + pyY *= invl; + pyZ *= invl; + pyW *= invl; + + nzX = m.m03() + m.m02(); + nzY = m.m13() + m.m12(); + nzZ = m.m23() + m.m22(); + nzW = m.m33() + m.m32(); + invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ); + nzX *= invl; + nzY *= invl; + nzZ *= invl; + nzW *= invl; + + pzX = m.m03() - m.m02(); + pzY = m.m13() - m.m12(); + pzZ = m.m23() - m.m22(); + pzW = m.m33() - m.m32(); + invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ); + pzX *= invl; + pzY *= invl; + pzZ *= invl; + pzW *= invl; + + MemoryUtil.memPutFloat(ptr, nxX); + MemoryUtil.memPutFloat(ptr + 4, pxX); + MemoryUtil.memPutFloat(ptr + 8, nyX); + MemoryUtil.memPutFloat(ptr + 12, pyX); + MemoryUtil.memPutFloat(ptr + 16, nxY); + MemoryUtil.memPutFloat(ptr + 20, pxY); + MemoryUtil.memPutFloat(ptr + 24, nyY); + MemoryUtil.memPutFloat(ptr + 28, pyY); + MemoryUtil.memPutFloat(ptr + 32, nxZ); + MemoryUtil.memPutFloat(ptr + 36, pxZ); + MemoryUtil.memPutFloat(ptr + 40, nyZ); + MemoryUtil.memPutFloat(ptr + 44, pyZ); + MemoryUtil.memPutFloat(ptr + 48, nxW); + MemoryUtil.memPutFloat(ptr + 52, pxW); + MemoryUtil.memPutFloat(ptr + 56, nyW); + MemoryUtil.memPutFloat(ptr + 60, pyW); + MemoryUtil.memPutFloat(ptr + 64, nzX); + MemoryUtil.memPutFloat(ptr + 68, pzX); + MemoryUtil.memPutFloat(ptr + 72, nzY); + MemoryUtil.memPutFloat(ptr + 76, pzY); + MemoryUtil.memPutFloat(ptr + 80, nzZ); + MemoryUtil.memPutFloat(ptr + 84, pzZ); + MemoryUtil.memPutFloat(ptr + 88, nzW); + MemoryUtil.memPutFloat(ptr + 92, pzW); + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java b/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java index 4e4881aaf..30e9dc05a 100644 --- a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java +++ b/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java @@ -989,58 +989,4 @@ public class FrustumIntersection { return result.div(f); } - - /** - * Writes the planes of this frustum to the given buffer.

- * Uses a different format that is friendly towards an optimized instruction-parallel - * implementation of sphere-frustum intersection.

- * The format is as follows:

- * {@code vec4(nxX, pxX, nyX, pyX)}
- * {@code vec4(nxY, pxY, nyY, pyY)}
- * {@code vec4(nxZ, pxZ, nyZ, pyZ)}
- * {@code vec4(nxW, pxW, nyW, pyW)}
- * {@code vec2(nzX, pzX)}
- * {@code vec2(nzY, pzY)}
- * {@code vec2(nzZ, pzZ)}
- * {@code vec2(nzW, pzW)}
- * - * @param addr The buffer to write the planes to. - */ - public void getJozuPackedPlanes(long addr) { - MemoryUtil.memPutFloat(addr, nxX); - MemoryUtil.memPutFloat(addr + 4, pxX); - MemoryUtil.memPutFloat(addr + 8, nyX); - MemoryUtil.memPutFloat(addr + 12, pyX); - MemoryUtil.memPutFloat(addr + 16, nxY); - MemoryUtil.memPutFloat(addr + 20, pxY); - MemoryUtil.memPutFloat(addr + 24, nyY); - MemoryUtil.memPutFloat(addr + 28, pyY); - MemoryUtil.memPutFloat(addr + 32, nxZ); - MemoryUtil.memPutFloat(addr + 36, pxZ); - MemoryUtil.memPutFloat(addr + 40, nyZ); - MemoryUtil.memPutFloat(addr + 44, pyZ); - MemoryUtil.memPutFloat(addr + 48, nxW); - MemoryUtil.memPutFloat(addr + 52, pxW); - MemoryUtil.memPutFloat(addr + 56, nyW); - MemoryUtil.memPutFloat(addr + 60, pyW); - MemoryUtil.memPutFloat(addr + 64, nzX); - MemoryUtil.memPutFloat(addr + 68, pzX); - MemoryUtil.memPutFloat(addr + 72, nzY); - MemoryUtil.memPutFloat(addr + 76, pzY); - MemoryUtil.memPutFloat(addr + 80, nzZ); - MemoryUtil.memPutFloat(addr + 84, pzZ); - MemoryUtil.memPutFloat(addr + 88, nzW); - MemoryUtil.memPutFloat(addr + 92, pzW); - } - - public void getPlanes(ByteBuffer buffer) { - long addr = MemoryUtil.memAddress(buffer); - - planes[0].getToAddress(addr); - planes[1].getToAddress(addr + 16); - planes[2].getToAddress(addr + 32); - planes[3].getToAddress(addr + 48); - planes[4].getToAddress(addr + 64); - planes[5].getToAddress(addr + 80); - } }