From a00eec69b77bef4edbf5bb5a0a240a8fb2f33ba7 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Fri, 13 Jun 2025 23:19:23 +1000 Subject: [PATCH 01/18] a --- .../HierarchicalOcclusionTraverser.java | 6 ++---- .../shaders/lod/hierarchical/screenspace.glsl | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index cc203ad7..02a4e779 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -103,12 +103,10 @@ public class HierarchicalOcclusionTraverser { this.nodeBuffer = new GlBuffer(nodeManager.maxNodeCount*16L).fill(-1); - glSamplerParameteri(this.hizSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glSamplerParameteri(this.hizSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(this.hizSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glSamplerParameteri(this.hizSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(this.hizSampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glSamplerParameteri(this.hizSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); this.traversal .ubo("SCENE_UNIFORM_BINDING", this.uniformBuffer) diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index c1ed54b0..fbf78835 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -12,7 +12,7 @@ // substantually for performance (for both persistent threads and incremental) -layout(binding = HIZ_BINDING) uniform sampler2DShadow hizDepthSampler; +layout(binding = HIZ_BINDING) uniform sampler2D hizDepthSampler; //TODO: maybe do spher bounds aswell? cause they have different accuracies but are both over estimates (liberals (non conservative xD)) // so can do && @@ -147,13 +147,23 @@ bool isCulledByHiz() { //the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves) testAgainst = testAgainst*2.0f-1.0f; - bool culled = textureLod(hizDepthSampler, clamp(vec3(midpoint, testAgainst), vec3(0), vec3(1)), miplevel) < 0.0001f; + + /* + ivec2 msize = textureSize(hizDepthSampler, int(miplevel)); + ivec2 mxbb = ivec2(maxBB.xy); + ivec2 mnbb = ivec2(minBB.xy);*/ + + float pointSample = textureLod(hizDepthSampler, maxBB.xy, miplevel).x; + pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(maxBB.x, minBB.y), miplevel).x); + pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(minBB.x, maxBB.y), miplevel).x); + pointSample = max(pointSample, textureLod(hizDepthSampler, minBB.xy, miplevel).x); + //printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z); //if ((culled) && node22.lodLevel == 0) { // printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f)); //} - return culled; + return pointSample<=testAgainst; } From 2027cb064cea93c79af928d705342076dec971b5 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sat, 14 Jun 2025 00:14:18 +1000 Subject: [PATCH 02/18] works --- .../assets/voxy/shaders/hiz/blit.fsh | 2 +- .../shaders/lod/hierarchical/screenspace.glsl | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/resources/assets/voxy/shaders/hiz/blit.fsh b/src/main/resources/assets/voxy/shaders/hiz/blit.fsh index 4fa79954..80b346b4 100644 --- a/src/main/resources/assets/voxy/shaders/hiz/blit.fsh +++ b/src/main/resources/assets/voxy/shaders/hiz/blit.fsh @@ -6,7 +6,7 @@ layout(binding = 0) uniform sampler2D depthTex; void main() { vec4 depths = textureGather(depthTex, uv, 0); // Get depth values from all surrounding texels. - bvec4 cv = lessThanEqual(vec4(0.999999f), depths); + bvec4 cv = lessThanEqual(vec4(0.999999999f), depths); if (any(cv)) {//Patch holes (its very dodgy but should work :tm:, should clamp it to the first 3 levels) depths = mix(vec4(0.0f), depths, cv); } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index fbf78835..8e4b4741 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -134,7 +134,7 @@ bool isCulledByHiz() { //TODO: make a path for if the miplevel would result in the textureSampler sampling a size of 1 - miplevel = ceil(miplevel); + miplevel = floor(miplevel)-1; miplevel = clamp(miplevel, 0, 20); if (miplevel >= 10.0f) {//Level 9 or 10// TODO: FIX THIS JANK SHIT @@ -145,18 +145,26 @@ bool isCulledByHiz() { float testAgainst = minBB.z; //the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves) - testAgainst = testAgainst*2.0f-1.0f; - + //testAgainst = testAgainst*2.0f-1.0f; + int ml = int(miplevel); + ivec2 msize = textureSize(hizDepthSampler, ml); + ivec2 mxbb = clamp(ivec2(ceil(maxBB.xy*msize)), ivec2(0), msize); + ivec2 mnbb = clamp(ivec2(floor(minBB.xy*msize)), ivec2(0), msize); + float pointSample = 0.0f; + for (int x = mnbb.x; x<=mxbb.x; x++) { + for (int y = mnbb.y; y<=mxbb.y; y++) { + float sp = texelFetch(hizDepthSampler, ivec2(x, y), ml).x; + //sp = mix(sp, pointSample, 1.0f<=sp); + pointSample = max(sp, pointSample); + } + } /* - ivec2 msize = textureSize(hizDepthSampler, int(miplevel)); - ivec2 mxbb = ivec2(maxBB.xy); - ivec2 mnbb = ivec2(minBB.xy);*/ - float pointSample = textureLod(hizDepthSampler, maxBB.xy, miplevel).x; pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(maxBB.x, minBB.y), miplevel).x); pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(minBB.x, maxBB.y), miplevel).x); pointSample = max(pointSample, textureLod(hizDepthSampler, minBB.xy, miplevel).x); + */ //printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z); From 4ed9199e1c15cbb3224c64712f6b50ce09787dc8 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sat, 14 Jun 2025 00:20:23 +1000 Subject: [PATCH 03/18] attempt improvments is not :( --- .../assets/voxy/shaders/lod/hierarchical/screenspace.glsl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 8e4b4741..7eeb425e 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -152,13 +152,16 @@ bool isCulledByHiz() { ivec2 mxbb = clamp(ivec2(ceil(maxBB.xy*msize)), ivec2(0), msize); ivec2 mnbb = clamp(ivec2(floor(minBB.xy*msize)), ivec2(0), msize); float pointSample = 0.0f; + //float pointSample2 = 0.0f; for (int x = mnbb.x; x<=mxbb.x; x++) { for (int y = mnbb.y; y<=mxbb.y; y++) { - float sp = texelFetch(hizDepthSampler, ivec2(x, y), ml).x; - //sp = mix(sp, pointSample, 1.0f<=sp); + float sp = texelFetch(hizDepthSampler, ivec2(x, y), ml).r; + //pointSample2 = max(sp, pointSample2); + //sp = mix(sp, pointSample, 0.9999999f<=sp); pointSample = max(sp, pointSample); } } + //pointSample = mix(pointSample, pointSample2, pointSample<=0.000001f); /* float pointSample = textureLod(hizDepthSampler, maxBB.xy, miplevel).x; pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(maxBB.x, minBB.y), miplevel).x); From 1c3019834718ec6669f38788333168e40435de54 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sat, 14 Jun 2025 13:54:31 +1000 Subject: [PATCH 04/18] Remove an info log --- .../voxy/client/core/rendering/hierachical/NodeManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeManager.java index 1e560753..37a27d7c 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeManager.java @@ -1213,7 +1213,8 @@ public class NodeManager { if (!this.nodeData.isNodeGeometryInFlight(nodeId)) { if (!this.watcher.watch(pos, WorldEngine.UPDATE_TYPE_BLOCK_BIT)) { - Logger.info("Node: " + nodeId + " at pos: " + WorldEngine.pprintPos(pos) + " got update request, but geometry was already being watched"); + //Logger.info("Node: " + nodeId + " at pos: " + WorldEngine.pprintPos(pos) + " got update request, but geometry was already being watched"); + this.invalidateNode(nodeId);//Who knows why but just invalidate the data just to keep in sync } else { this.nodeData.markNodeGeometryInFlight(nodeId); } From ee6d171ef6020e8de2192e4e2dfe565477fbe74c Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:21:37 +1000 Subject: [PATCH 05/18] Note --- .../voxy/client/core/rendering/hierachical/AsyncNodeManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java index 344fa886..f8c367b6 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java @@ -179,6 +179,7 @@ public class AsyncNodeManager { private void run() { if (this.workCounter.get() <= 0) { + //TODO: here, instead of parking, we can do more work on other sub-tasks such as filtering the mesh build queue LockSupport.park(); if (this.workCounter.get() <= 0 || !this.running) {//No work return; From b79923de3df9cfe95c62798a27a9dd510a19999a Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:22:26 +1000 Subject: [PATCH 06/18] Remove setup --- .../voxy/client/core/VoxyRenderSystem.java | 37 ++----------------- .../mixin/minecraft/MixinWorldRenderer.java | 7 ---- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java index 68be89ed..73bfbfec 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java @@ -100,40 +100,6 @@ public class VoxyRenderSystem { } - //private static final ModelTextureBakery mtb = new ModelTextureBakery(16, 16); - //private static final RawDownloadStream downstream = new RawDownloadStream(1<<20); - public void renderSetup(Frustum frustum, Camera camera) { - TimingStatistics.resetSamplers(); - - /* - if (false) { - int allocation = downstream.download(2 * 4 * 6 * 16 * 16, ptr -> { - ColourDepthTextureData[] textureData = new ColourDepthTextureData[6]; - final int FACE_SIZE = 16 * 16; - for (int face = 0; face < 6; face++) { - long faceDataPtr = ptr + (FACE_SIZE * 4) * face * 2; - int[] colour = new int[FACE_SIZE]; - int[] depth = new int[FACE_SIZE]; - - //Copy out colour - for (int i = 0; i < FACE_SIZE; i++) { - //De-interpolate results - colour[i] = MemoryUtil.memGetInt(faceDataPtr + (i * 4 * 2)); - depth[i] = MemoryUtil.memGetInt(faceDataPtr + (i * 4 * 2) + 4); - } - - textureData[face] = new ColourDepthTextureData(colour, depth, 16, 16); - } - if (textureData[0].colour()[0] == 0) { - int a = 0; - } - }); - mtb.renderFacesToStream(Blocks.AIR.getDefaultState(), 123456, false, downstream.getBufferId(), allocation); - downstream.submit(); - downstream.tick(); - }*/ - } - private void autoBalanceSubDivSize() { //only increase quality while there are very few mesh queues, this stops, // e.g. while flying and is rendering alot of low quality chunks @@ -176,6 +142,9 @@ public class VoxyRenderSystem { if (IrisUtil.irisShadowActive()) { return; } + TimingStatistics.resetSamplers(); + + //Do some very cheeky stuff for MiB if (false) { int sector = (((int)Math.floor(cameraX)>>4)+512)>>10; diff --git a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java index fea51c57..f9b31047 100644 --- a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java +++ b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java @@ -26,13 +26,6 @@ public abstract class MixinWorldRenderer implements IGetVoxyRenderSystem { @Shadow private @Nullable ClientWorld world; @Unique private VoxyRenderSystem renderer; - @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;setupTerrain(Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;ZZ)V", shift = At.Shift.AFTER)) - private void injectSetup(ObjectAllocator allocator, RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) { - if (this.renderer != null) { - this.renderer.renderSetup(this.frustum, camera); - } - } - @Override public VoxyRenderSystem getVoxyRenderSystem() { return this.renderer; From caf270310263423ea91fb6de6e04fd953586f92d Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:41:29 +1000 Subject: [PATCH 07/18] small thing --- .../voxy/client/core/rendering/RenderService.java | 14 ++++++++------ .../HierarchicalOcclusionTraverser.java | 5 +---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index b6fc2339..01b1c3a4 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -121,6 +121,13 @@ public class RenderService, J extends Vi this.sectionRenderer.renderOpaque(viewport, depthBoundTexture); TimingStatistics.G.stop(); + { + int depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); + + //Compute the mip chain + viewport.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height); + } + do { //NOTE: need to do the upload and download tick here, after the section renderer renders the world, to ensure "stable" // sections @@ -157,13 +164,8 @@ public class RenderService, J extends Vi glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT); - int depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - //if (depthBuffer == 0) { - // depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - //} - TimingStatistics.I.start(); - this.traversal.doTraversal(viewport, depthBuffer); + this.traversal.doTraversal(viewport); TimingStatistics.I.stop(); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index 02a4e779..e2ab3152 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -201,10 +201,7 @@ public class HierarchicalOcclusionTraverser { glBindBufferBase(GL_SHADER_STORAGE_BUFFER, RENDER_QUEUE_BINDING, viewport.getRenderList().id); } - public void doTraversal(Viewport viewport, int depthBuffer) { - //Compute the mip chain - viewport.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height); - + public void doTraversal(Viewport viewport) { this.uploadUniform(viewport); //UploadStream.INSTANCE.commit(); //Done inside traversal From 0e98f5258044e9693505f31163166595564c6b97 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 19:28:32 +1000 Subject: [PATCH 08/18] improved logger --- .../java/me/cortex/voxy/common/Logger.java | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/cortex/voxy/common/Logger.java b/src/main/java/me/cortex/voxy/common/Logger.java index 79255d56..a18a9934 100644 --- a/src/main/java/me/cortex/voxy/common/Logger.java +++ b/src/main/java/me/cortex/voxy/common/Logger.java @@ -14,6 +14,30 @@ public class Logger { public static boolean SHUTUP = false; private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger("Voxy"); + + private static String callClsName() { + String className = ""; + if (INSERT_CLASS) { + var stackEntry = new Throwable().getStackTrace()[2]; + className = stackEntry.getClassName(); + var builder = new StringBuilder(); + var parts = className.split("\\."); + for (int i = 0; i < parts.length; i++) { + var part = parts[i]; + if (i < parts.length-1) {//-2 + builder.append(part.charAt(0)).append(part.charAt(part.length()-1)); + } else { + builder.append(part); + } + if (i!=parts.length-1) { + builder.append("."); + } + } + className = builder.toString(); + } + return className; + } + public static void error(Object... args) { if (SHUTUP) { return; @@ -24,8 +48,8 @@ public class Logger { throwable = (Throwable) i; } } - var stackEntry = new Throwable().getStackTrace()[1]; - String error = (INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")); + + String error = (INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")); LOGGER.error(error, throwable); if (VoxyCommon.IS_IN_MINECRAFT && !VoxyCommon.IS_DEDICATED_SERVER) { var instance = MinecraftClient.getInstance(); @@ -48,8 +72,7 @@ public class Logger { throwable = (Throwable) i; } } - var stackEntry = new Throwable().getStackTrace()[1]; - LOGGER.warn((INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable); + LOGGER.warn((INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable); } public static void info(Object... args) { @@ -62,8 +85,7 @@ public class Logger { throwable = (Throwable) i; } } - var stackEntry = new Throwable().getStackTrace()[1]; - LOGGER.info((INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable); + LOGGER.info((INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable); } private static String objToString(Object obj) { From 950e92d7c7ac7e10979c32eb8a0e951297fb5dcb Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 20:03:12 +1000 Subject: [PATCH 09/18] h --- .../voxy/client/core/VoxyRenderSystem.java | 53 ++++++++++--------- .../client/core/rendering/RenderService.java | 2 +- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java index 73bfbfec..528efba8 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java @@ -64,35 +64,40 @@ public class VoxyRenderSystem { //Keep the world loaded, NOTE: this is done FIRST, to keep and ensure that even if the rest of loading takes more // than timeout, we keep the world acquired world.acquireRef(); + try { + //wait for opengl to be finished, this should hopefully ensure all memory allocations are free + glFinish(); + glFinish(); - //wait for opengl to be finished, this should hopefully ensure all memory allocations are free - glFinish();glFinish(); + //Trigger the shared index buffer loading + SharedIndexBuffer.INSTANCE.id(); + Capabilities.init();//Ensure clinit is called - //Trigger the shared index buffer loading - SharedIndexBuffer.INSTANCE.id(); - Capabilities.init();//Ensure clinit is called + this.worldIn = world; + this.renderer = new RenderService(world, threadPool); + this.postProcessing = new PostProcessing(); + int minSec = MinecraftClient.getInstance().world.getBottomSectionCoord() >> 5; + int maxSec = (MinecraftClient.getInstance().world.getTopSectionCoord() - 1) >> 5; - this.worldIn = world; - this.renderer = new RenderService(world, threadPool); - this.postProcessing = new PostProcessing(); - int minSec = MinecraftClient.getInstance().world.getBottomSectionCoord()>>5; - int maxSec = (MinecraftClient.getInstance().world.getTopSectionCoord()-1)>>5; + //Do some very cheeky stuff for MiB + if (false) { + minSec = -8; + maxSec = 7; + } - //Do some very cheeky stuff for MiB - if (false) { - minSec = -8; - maxSec = 7; + this.renderDistanceTracker = new RenderDistanceTracker(20, + minSec, + maxSec, + this.renderer::addTopLevelNode, + this.renderer::removeTopLevelNode); + + this.renderDistanceTracker.setRenderDistance(VoxyConfig.CONFIG.sectionRenderDistance); + + this.chunkBoundRenderer = new ChunkBoundRenderer(); + } catch (RuntimeException e) { + world.releaseRef();//If something goes wrong, we must release the world first + throw e; } - - this.renderDistanceTracker = new RenderDistanceTracker(20, - minSec, - maxSec, - this.renderer::addTopLevelNode, - this.renderer::removeTopLevelNode); - - this.renderDistanceTracker.setRenderDistance(VoxyConfig.CONFIG.sectionRenderDistance); - - this.chunkBoundRenderer = new ChunkBoundRenderer(); } public void setRenderDistance(int renderDistance) { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index 01b1c3a4..fc0f8ba4 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -56,7 +56,7 @@ public class RenderService, J extends Vi geometryCapacity = Math.min(geometryCapacity, limit); } - //geometryCapacity = 1<<24; + //geometryCapacity = 1<<28; //geometryCapacity = 1<<30;//1GB test return geometryCapacity; } From 1575d7319ca0ac25dc876876d6b343a14ee42b9e Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 20:03:28 +1000 Subject: [PATCH 10/18] big progress in fixing culling --- .../client/core/rendering/util/HiZBuffer.java | 9 ++++-- .../shaders/lod/hierarchical/screenspace.glsl | 29 ++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java index 6f5780dc..4616dfdd 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java @@ -69,12 +69,12 @@ public class HiZBuffer { } public void buildMipChain(int srcDepthTex, int width, int height) { - if (this.width != width || this.height != height) { + if (this.width != Integer.highestOneBit(width*2) || this.height != Integer.highestOneBit(height*2)) { if (this.texture != null) { this.texture.free(); this.texture = null; } - this.alloc(width, height); + this.alloc(Integer.highestOneBit(width*2), Integer.highestOneBit(height*2)); } glBindVertexArray(RenderService.STATIC_VAO); int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING); @@ -92,7 +92,7 @@ public class HiZBuffer { width, height, 1); - glBindTextureUnit(0, this.texture.id); + glBindTextureUnit(0, srcDepthTex); glBindSampler(0, this.sampler); glUniform1i(0, 0); int cw = this.width; @@ -106,6 +106,9 @@ public class HiZBuffer { glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glTextureBarrier(); glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_FETCH_BARRIER_BIT); + if (i==0) { + glBindTextureUnit(0, this.texture.id); + } } glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, 1000);//TODO: CHECK IF ITS -1 or -0 diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 7eeb425e..3e8acb38 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -117,6 +117,9 @@ void setupScreenspace(in UnpackedNode node) { minBB = min(min(min(p000, p100), min(p001, p101)), min(min(p010, p110), min(p011, p111))); maxBB = max(max(max(p000, p100), max(p001, p101)), max(max(p010, p110), max(p011, p111))); + minBB = clamp(minBB, vec3(0), vec3(1)); + maxBB = clamp(maxBB, vec3(0), vec3(1)); + size = clamp(maxBB.xy - minBB.xy, vec2(0), vec2(1)); } @@ -128,18 +131,14 @@ bool outsideFrustum() { } bool isCulledByHiz() { - vec2 ssize = size * vec2(screenW, screenH); - float miplevel = log2(max(max(ssize.x, ssize.y),1)); + vec2 asize = size * vec2(screenW, screenH); + float miplevel = log2(max(max(asize.x, asize.y),1)); //TODO: make a path for if the miplevel would result in the textureSampler sampling a size of 1 miplevel = floor(miplevel)-1; - miplevel = clamp(miplevel, 0, 20); - - if (miplevel >= 10.0f) {//Level 9 or 10// TODO: FIX THIS JANK SHIT - //return false; - } + miplevel = clamp(miplevel, 0, textureQueryLevels(hizDepthSampler)-1); vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f; @@ -147,11 +146,11 @@ bool isCulledByHiz() { //the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves) //testAgainst = testAgainst*2.0f-1.0f; - int ml = int(miplevel); - ivec2 msize = textureSize(hizDepthSampler, ml); - ivec2 mxbb = clamp(ivec2(ceil(maxBB.xy*msize)), ivec2(0), msize); - ivec2 mnbb = clamp(ivec2(floor(minBB.xy*msize)), ivec2(0), msize); - float pointSample = 0.0f; + int ml = 4;//int(miplevel); + ivec2 msize = ivec2(128,64);//textureSize(hizDepthSampler, ml);//max(ivec2(1),ivec2(screenW, screenH)>>ml); + ivec2 mxbb = clamp(ivec2(maxBB.xy*msize), ivec2(0), msize); + ivec2 mnbb = clamp(ivec2(minBB.xy*msize), ivec2(0), msize); + float pointSample = -1.0f; //float pointSample2 = 0.0f; for (int x = mnbb.x; x<=mxbb.x; x++) { for (int y = mnbb.y; y<=mxbb.y; y++) { @@ -174,7 +173,11 @@ bool isCulledByHiz() { //if ((culled) && node22.lodLevel == 0) { // printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f)); //} - return pointSample<=testAgainst; + if (pointSample==0.0f) { + //return false; + } + + return pointSample Date: Mon, 16 Jun 2025 20:17:44 +1000 Subject: [PATCH 11/18] poc --- .../client/core/rendering/util/HiZBuffer.java | 21 +++++++------------ .../shaders/lod/hierarchical/screenspace.glsl | 13 ++++-------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java index 4616dfdd..0cb5b79d 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java @@ -69,12 +69,12 @@ public class HiZBuffer { } public void buildMipChain(int srcDepthTex, int width, int height) { - if (this.width != Integer.highestOneBit(width*2) || this.height != Integer.highestOneBit(height*2)) { + if (this.width != Integer.highestOneBit(width) || this.height != Integer.highestOneBit(height)) { if (this.texture != null) { this.texture.free(); this.texture = null; } - this.alloc(Integer.highestOneBit(width*2), Integer.highestOneBit(height*2)); + this.alloc(Integer.highestOneBit(width), Integer.highestOneBit(height)); } glBindVertexArray(RenderService.STATIC_VAO); int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING); @@ -86,26 +86,19 @@ public class HiZBuffer { glEnable(GL_DEPTH_TEST); - //System.err.println("SRC: " + GlTexture.getRawTextureType(srcDepthTex) + " DST: " + this.texture.id); - glCopyImageSubData(srcDepthTex, GL_TEXTURE_2D, 0,0,0,0, - this.texture.id, GL_TEXTURE_2D, 0,0,0,0, - width, height, 1); - - glBindTextureUnit(0, srcDepthTex); glBindSampler(0, this.sampler); glUniform1i(0, 0); int cw = this.width; int ch = this.height; - glViewport(0, 0, cw, ch); - for (int i = 0; i < this.levels-1; i++) { - glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, i); - glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, i); - this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, i+1); - cw = Math.max(cw/2, 1); ch = Math.max(ch/2, 1); glViewport(0, 0, cw, ch); + for (int i = 0; i < this.levels; i++) { + this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, i); + glViewport(0, 0, cw, ch); cw = Math.max(cw/2, 1); ch = Math.max(ch/2, 1); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glTextureBarrier(); glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_FETCH_BARRIER_BIT); + glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, i); + glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, i); if (i==0) { glBindTextureUnit(0, this.texture.id); } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 3e8acb38..167e4db1 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -131,7 +131,7 @@ bool outsideFrustum() { } bool isCulledByHiz() { - vec2 asize = size * vec2(screenW, screenH); + vec2 asize = size * vec2(1024, 512); float miplevel = log2(max(max(asize.x, asize.y),1)); //TODO: make a path for if the miplevel would result in the textureSampler sampling a size of 1 @@ -140,14 +140,12 @@ bool isCulledByHiz() { miplevel = floor(miplevel)-1; miplevel = clamp(miplevel, 0, textureQueryLevels(hizDepthSampler)-1); - vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f; - float testAgainst = minBB.z; //the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves) //testAgainst = testAgainst*2.0f-1.0f; - int ml = 4;//int(miplevel); - ivec2 msize = ivec2(128,64);//textureSize(hizDepthSampler, ml);//max(ivec2(1),ivec2(screenW, screenH)>>ml); + int ml = int(miplevel); + ivec2 msize = textureSize(hizDepthSampler, ml);//max(ivec2(1),ivec2(screenW, screenH)>>ml); ivec2 mxbb = clamp(ivec2(maxBB.xy*msize), ivec2(0), msize); ivec2 mnbb = clamp(ivec2(minBB.xy*msize), ivec2(0), msize); float pointSample = -1.0f; @@ -173,11 +171,8 @@ bool isCulledByHiz() { //if ((culled) && node22.lodLevel == 0) { // printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f)); //} - if (pointSample==0.0f) { - //return false; - } - return pointSample Date: Mon, 16 Jun 2025 20:45:49 +1000 Subject: [PATCH 12/18] it works --- .../HierarchicalOcclusionTraverser.java | 12 ++++--- .../client/core/rendering/util/HiZBuffer.java | 4 +++ .../shaders/lod/hierarchical/screenspace.glsl | 36 +++++-------------- .../lod/hierarchical/traversal_dev.comp | 5 ++- 4 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index e2ab3152..2ad6f6d1 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -173,20 +173,22 @@ public class HierarchicalOcclusionTraverser { viewport.section.getToAddress(ptr); ptr += 4*3; - MemoryUtil.memPutFloat(ptr, viewport.width); ptr += 4; + //MemoryUtil.memPutFloat(ptr, viewport.width); ptr += 4; + MemoryUtil.memPutInt(ptr, viewport.hiZBuffer.getPackedLevels()); ptr += 4; viewport.innerTranslation.getToAddress(ptr); ptr += 4*3; - MemoryUtil.memPutFloat(ptr, viewport.height); ptr += 4; + //MemoryUtil.memPutFloat(ptr, viewport.height); ptr += 4; + + final float screenspaceAreaDecreasingSize = VoxyConfig.CONFIG.subDivisionSize*VoxyConfig.CONFIG.subDivisionSize; + //Screen space size for descending + MemoryUtil.memPutFloat(ptr, (float) (screenspaceAreaDecreasingSize) /(viewport.width*viewport.height)); ptr += 4; setFrustum(viewport, ptr); ptr += 4*4*6; MemoryUtil.memPutInt(ptr, (int) (viewport.getRenderList().size()/4-1)); ptr += 4; - final float screenspaceAreaDecreasingSize = VoxyConfig.CONFIG.subDivisionSize*VoxyConfig.CONFIG.subDivisionSize; - //Screen space size for descending - MemoryUtil.memPutFloat(ptr, (float) (screenspaceAreaDecreasingSize) /(viewport.width*viewport.height)); ptr += 4; //VisibilityId MemoryUtil.memPutInt(ptr, this.nodeCleaner.visibilityId); ptr += 4; diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java index 0cb5b79d..538b30ba 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/util/HiZBuffer.java @@ -126,4 +126,8 @@ public class HiZBuffer { public int getHizTextureId() { return this.texture.id; } + + public int getPackedLevels() { + return ((Integer.numberOfTrailingZeros(this.width))<<16)|(Integer.numberOfTrailingZeros(this.height));//+1 + } } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 167e4db1..37a93367 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -39,7 +39,6 @@ bool checkPointInView(vec4 point) { vec3 minBB = vec3(0.0f); vec3 maxBB = vec3(0.0f); -vec2 size = vec2(0.0f); bool insideFrustum = false; float screenSize = 0.0f; @@ -119,8 +118,6 @@ void setupScreenspace(in UnpackedNode node) { minBB = clamp(minBB, vec3(0), vec3(1)); maxBB = clamp(maxBB, vec3(0), vec3(1)); - - size = clamp(maxBB.xy - minBB.xy, vec2(0), vec2(1)); } //Checks if the node is implicitly culled (outside frustum) @@ -131,23 +128,18 @@ bool outsideFrustum() { } bool isCulledByHiz() { - vec2 asize = size * vec2(1024, 512); - float miplevel = log2(max(max(asize.x, asize.y),1)); - - //TODO: make a path for if the miplevel would result in the textureSampler sampling a size of 1 - + ivec2 ssize = ivec2(1)<>16)&0xFFFF,packedHizSize&0xFFFF); + vec2 size = (maxBB.xy-minBB.xy)*ssize; + float miplevel = log2(max(max(size.x, size.y),1)); miplevel = floor(miplevel)-1; miplevel = clamp(miplevel, 0, textureQueryLevels(hizDepthSampler)-1); - float testAgainst = minBB.z; - //the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves) - //testAgainst = testAgainst*2.0f-1.0f; - int ml = int(miplevel); - ivec2 msize = textureSize(hizDepthSampler, ml);//max(ivec2(1),ivec2(screenW, screenH)>>ml); - ivec2 mxbb = clamp(ivec2(maxBB.xy*msize), ivec2(0), msize); - ivec2 mnbb = clamp(ivec2(minBB.xy*msize), ivec2(0), msize); + ssize = ssize>>ml; + ivec2 mxbb = ivec2(maxBB.xy*ssize); + ivec2 mnbb = ivec2(minBB.xy*ssize); + float pointSample = -1.0f; //float pointSample2 = 0.0f; for (int x = mnbb.x; x<=mxbb.x; x++) { @@ -159,20 +151,8 @@ bool isCulledByHiz() { } } //pointSample = mix(pointSample, pointSample2, pointSample<=0.000001f); - /* - float pointSample = textureLod(hizDepthSampler, maxBB.xy, miplevel).x; - pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(maxBB.x, minBB.y), miplevel).x); - pointSample = max(pointSample, textureLod(hizDepthSampler, vec2(minBB.x, maxBB.y), miplevel).x); - pointSample = max(pointSample, textureLod(hizDepthSampler, minBB.xy, miplevel).x); - */ - - //printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z); - //if ((culled) && node22.lodLevel == 0) { - // printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f)); - //} - - return pointSample<=testAgainst; + return pointSample<=minBB.z; } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp index 642a339e..960cb916 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp @@ -10,12 +10,11 @@ layout(local_size_x=LOCAL_SIZE) in;//, local_size_y=1 layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform { mat4 VP; ivec3 camSecPos; - float screenW; + int packedHizSize; vec3 camSubSecPos; - float screenH; + float minSSS; Frustum frustum; uint renderQueueMaxSize; - float minSSS; uint frameId; }; From 22d557ed013cf97b684d117887dee24b77ca175a Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 21:33:48 +1000 Subject: [PATCH 13/18] am stupid --- .../lod/hierarchical/cleaner/sort_visibility.comp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/sort_visibility.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/sort_visibility.comp index 82e1eaab..ca362796 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/sort_visibility.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/sort_visibility.comp @@ -93,10 +93,9 @@ void bubbleSortInital(uint vis, uint id) { bool shouldSortId(uint id) { UnpackedNode node; - if (unpackNode(node, gl_GlobalInvocationID.x)==uvec4(-1)) { + if (unpackNode(node, id)==uvec4(-1)) { return false;//Unallocated node } - if (isEmptyMesh(node) || (!hasMesh(node))) {//|| (!hasChildren(node)) return false; } @@ -105,6 +104,9 @@ bool shouldSortId(uint id) { return false;//Cannot remove geometry from top level node } + if (hasRequested(node)) {//If a node has a request its not valid to remove + return false; + } /*THIS IS COMPLETLY WRONG, we need to check if all the children of the parent of the child are leaf nodes // not this node @@ -130,7 +132,7 @@ void main() { // this means that insertion into the local buffer can be accelerated W.R.T global for (uint i = 0; i < OPS_PER_THREAD; i++) { //Copy in with warp size batch fetch - uint id = gl_LocalInvocationID.x + (i*WORK_SIZE); + uint id = (gl_LocalInvocationID.x*OPS_PER_THREAD) + i; initalSort[id] = minVisIds[id]|(1u<<31);//Flag the id as being external } barrier(); @@ -158,7 +160,7 @@ void main() { //Work size batching for (uint i = 0; i < OPS_PER_THREAD; i++) { barrier();//Probably unneeded, was just to keep warp coheriancy - uint id = gl_LocalInvocationID.x+(i*WORK_SIZE); + uint id = (gl_LocalInvocationID.x*OPS_PER_THREAD)+i; uint sid = initalSort[id]; if ((sid&(1u<<31)) != 0) { //The flag being external was set, meaning we should NOT insert this element From 072ece7a3dbbbb9dfc65eeea8859da43ee777ad8 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 21:36:39 +1000 Subject: [PATCH 14/18] add max --- .../assets/voxy/shaders/lod/hierarchical/screenspace.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 37a93367..b77f2d63 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -136,7 +136,7 @@ bool isCulledByHiz() { miplevel = clamp(miplevel, 0, textureQueryLevels(hizDepthSampler)-1); int ml = int(miplevel); - ssize = ssize>>ml; + ssize = max(ivec2(1), ssize>>ml); ivec2 mxbb = ivec2(maxBB.xy*ssize); ivec2 mnbb = ivec2(minBB.xy*ssize); From 84482e8998de5dd00aceef0e96546bff14887d4f Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:39:36 +1000 Subject: [PATCH 15/18] Make the request queue dynamically capped, greatly increasing snappyness --- .../client/core/rendering/RenderService.java | 2 +- .../HierarchicalOcclusionTraverser.java | 21 +++++++++++++------ .../lod/hierarchical/traversal_dev.comp | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index fc0f8ba4..fca8ac4c 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -84,7 +84,7 @@ public class RenderService, J extends Vi this.nodeManager = new AsyncNodeManager(1<<21, this.geometryData, this.renderGen); this.nodeCleaner = new NodeCleaner(this.nodeManager); - this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, this.nodeCleaner); + this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, this.nodeCleaner, this.renderGen); world.setDirtyCallback(this.nodeManager::worldEvent); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index 2ad6f6d1..35038fb8 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -7,6 +7,7 @@ import me.cortex.voxy.client.core.gl.GlBuffer; import me.cortex.voxy.client.core.gl.shader.AutoBindingShader; import me.cortex.voxy.client.core.gl.shader.Shader; import me.cortex.voxy.client.core.gl.shader.ShaderType; +import me.cortex.voxy.client.core.rendering.building.RenderGenerationService; import me.cortex.voxy.client.core.rendering.util.PrintfDebugUtil; import me.cortex.voxy.client.core.rendering.util.HiZBuffer; import me.cortex.voxy.client.core.rendering.Viewport; @@ -30,7 +31,7 @@ import static org.lwjgl.opengl.GL45.*; public class HierarchicalOcclusionTraverser { public static final boolean HIERARCHICAL_SHADER_DEBUG = System.getProperty("voxy.hierarchicalShaderDebug", "false").equals("true"); - public static final int REQUEST_QUEUE_SIZE = 50; + public static final int MAX_REQUEST_QUEUE_SIZE = 50; public static final int MAX_QUEUE_SIZE = 200_000; @@ -39,6 +40,7 @@ public class HierarchicalOcclusionTraverser { private final AsyncNodeManager nodeManager; private final NodeCleaner nodeCleaner; + private final RenderGenerationService meshGen; private final GlBuffer requestBuffer; @@ -73,7 +75,7 @@ public class HierarchicalOcclusionTraverser { .defineIf("DEBUG", HIERARCHICAL_SHADER_DEBUG) .define("MAX_ITERATIONS", MAX_ITERATIONS) .define("LOCAL_SIZE_BITS", LOCAL_WORK_SIZE_BITS) - .define("REQUEST_QUEUE_SIZE", REQUEST_QUEUE_SIZE) + .define("MAX_REQUEST_QUEUE_SIZE", MAX_REQUEST_QUEUE_SIZE) .define("HIZ_BINDING", 0) @@ -96,10 +98,11 @@ public class HierarchicalOcclusionTraverser { .compile(); - public HierarchicalOcclusionTraverser(AsyncNodeManager nodeManager, NodeCleaner nodeCleaner) { + public HierarchicalOcclusionTraverser(AsyncNodeManager nodeManager, NodeCleaner nodeCleaner, RenderGenerationService meshGen) { this.nodeCleaner = nodeCleaner; this.nodeManager = nodeManager; - this.requestBuffer = new GlBuffer(REQUEST_QUEUE_SIZE*8L+8).zero(); + this.meshGen = meshGen; + this.requestBuffer = new GlBuffer(MAX_REQUEST_QUEUE_SIZE*8L+8).zero(); this.nodeBuffer = new GlBuffer(nodeManager.maxNodeCount*16L).fill(-1); @@ -188,10 +191,16 @@ public class HierarchicalOcclusionTraverser { MemoryUtil.memPutInt(ptr, (int) (viewport.getRenderList().size()/4-1)); ptr += 4; - - //VisibilityId MemoryUtil.memPutInt(ptr, this.nodeCleaner.visibilityId); ptr += 4; + + { + final double TARGET_COUNT = 4000;//TODO: make this configurable, or at least dynamically computed based on throughput rate of mesh gen + double iFillness = Math.max(0, (TARGET_COUNT - this.meshGen.getTaskCount()) / TARGET_COUNT); + iFillness = Math.pow(iFillness, 2); + final int requestSize = (int) Math.ceil(iFillness * MAX_REQUEST_QUEUE_SIZE); + MemoryUtil.memPutInt(ptr, Math.max(0, Math.min(MAX_REQUEST_QUEUE_SIZE, requestSize)));ptr += 4; + } } private void bindings(Viewport viewport) { diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp index 960cb916..db1faa01 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp @@ -16,6 +16,7 @@ layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform { Frustum frustum; uint renderQueueMaxSize; uint frameId; + uint requestQueueSize; }; #import @@ -48,9 +49,9 @@ layout(binding = STATISTICS_BUFFER_BINDING, std430) restrict buffer statisticsBu void addRequest(inout UnpackedNode node) { //printf("Put node decend request"); if (!hasRequested(node)) { - if (requestQueueIndex.x < REQUEST_QUEUE_SIZE) { + if (requestQueueIndex.x < requestQueueSize) {//Soft limit uint atomRes = atomicAdd(requestQueueIndex.x, 1); - if (atomRes < REQUEST_QUEUE_SIZE) { + if (atomRes < MAX_REQUEST_QUEUE_SIZE) {//Hard limit //Mark node as having a request submitted to prevent duplicate submissions requestQueue[atomRes] = getRawPos(node); markRequested(node); From dc6dd4bb11c1d11cdb3162970bae2abe955427e4 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:40:10 +1000 Subject: [PATCH 16/18] remove pow for now --- .../rendering/hierachical/HierarchicalOcclusionTraverser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index 35038fb8..8eefde3c 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -197,7 +197,7 @@ public class HierarchicalOcclusionTraverser { { final double TARGET_COUNT = 4000;//TODO: make this configurable, or at least dynamically computed based on throughput rate of mesh gen double iFillness = Math.max(0, (TARGET_COUNT - this.meshGen.getTaskCount()) / TARGET_COUNT); - iFillness = Math.pow(iFillness, 2); + //iFillness = Math.pow(iFillness, 2); final int requestSize = (int) Math.ceil(iFillness * MAX_REQUEST_QUEUE_SIZE); MemoryUtil.memPutInt(ptr, Math.max(0, Math.min(MAX_REQUEST_QUEUE_SIZE, requestSize)));ptr += 4; } From 144faf5b21be4cfe74adc51ff04f44168a226e4e Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:52:55 +1000 Subject: [PATCH 17/18] move frex check loop --- .../client/core/rendering/RenderService.java | 21 ++++++++++++------- .../hierachical/AsyncNodeManager.java | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index fca8ac4c..8df7988b 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -106,6 +106,18 @@ public class RenderService, J extends Vi this.modelService.tick(budget); } + private boolean frexStillHasWork() { + if (!VoxyClient.isFrexActive()) { + return false; + } + //If frex is running we must tick everything to ensure correctness + UploadStream.INSTANCE.tick(); + //Done here as is allows less gl state resetup + this.modelService.tick(100_000_000); + glFinish(); + return this.nodeManager.hasWork() || this.renderGen.getTaskCount()!=0 || !this.modelService.areQueuesEmpty(); + } + public void renderFarAwayOpaque(J viewport, GlTexture depthBoundTexture) { //LightMapHelper.tickLightmap(); @@ -168,14 +180,7 @@ public class RenderService, J extends Vi this.traversal.doTraversal(viewport); TimingStatistics.I.stop(); - - if (VoxyClient.isFrexActive()) {//If frex is running we must tick everything to ensure correctness - UploadStream.INSTANCE.tick(); - //Done here as is allows less gl state resetup - this.tickModelService(100_000_000); - glFinish(); - } - } while (VoxyClient.isFrexActive() && (this.nodeManager.hasWork() || this.renderGen.getTaskCount()!=0 || !this.modelService.areQueuesEmpty())); + } while (this.frexStillHasWork()); TimingStatistics.H.start(); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java index f8c367b6..daaaa499 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java @@ -754,7 +754,7 @@ public class AsyncNodeManager { } public boolean hasWork() { - return this.workCounter.get()!=0 && RESULT_HANDLE.get(this) != null; + return this.workCounter.get()!=0 || RESULT_HANDLE.get(this) != null; } public void worldEvent(WorldSection section, int flags) { From 2327c6baf8d6a65cf856ef7b2e64321cf14d6b52 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Wed, 18 Jun 2025 08:53:32 +1000 Subject: [PATCH 18/18] thing --- .../rendering/hierachical/HierarchicalOcclusionTraverser.java | 2 +- .../voxy/client/core/rendering/section/MDICSectionRenderer.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java index 8eefde3c..35038fb8 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/HierarchicalOcclusionTraverser.java @@ -197,7 +197,7 @@ public class HierarchicalOcclusionTraverser { { final double TARGET_COUNT = 4000;//TODO: make this configurable, or at least dynamically computed based on throughput rate of mesh gen double iFillness = Math.max(0, (TARGET_COUNT - this.meshGen.getTaskCount()) / TARGET_COUNT); - //iFillness = Math.pow(iFillness, 2); + iFillness = Math.pow(iFillness, 2); final int requestSize = (int) Math.ceil(iFillness * MAX_REQUEST_QUEUE_SIZE); MemoryUtil.memPutInt(ptr, Math.max(0, Math.min(MAX_REQUEST_QUEUE_SIZE, requestSize)));ptr += 4; } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java index e1a68ed1..34b89a58 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java @@ -172,6 +172,7 @@ public class MDICSectionRenderer extends AbstractSectionRenderer