From 26825e358f485bc04ad166790fc4079b65fc6caf Mon Sep 17 00:00:00 2001 From: mcrcortex <{ID}+{username}@users.noreply.github.com> Date: Tue, 16 Jul 2024 20:47:49 +1000 Subject: [PATCH] Fixes and tweeks --- build.gradle | 2 +- .../rendering/Gl46HierarchicalRenderer.java | 12 +++- .../HierarchicalOcclusionRenderer.java | 23 ++++--- .../rendering/hierarchical/NodeManager.java | 65 ++++++++++++------- .../lod/hierarchical/debug/node_outline.vert | 4 +- .../voxy/shaders/lod/hierarchical/node.glsl | 4 ++ .../shaders/lod/hierarchical/traversal.comp | 10 +-- 7 files changed, 79 insertions(+), 41 deletions(-) diff --git a/build.gradle b/build.gradle index ea17aea3..ed469386 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,7 @@ dependencies { //modRuntimeOnly "maven.modrinth:nvidium:0.2.6-beta" modCompileOnly "maven.modrinth:nvidium:0.2.8-beta" - modImplementation("maven.modrinth:cloth-config:13.0.121+fabric") + modImplementation("maven.modrinth:cloth-config:15.0.127+fabric") modImplementation("maven.modrinth:modmenu:11.0.1") diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java index 661e77e7..a47e39f7 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java @@ -174,6 +174,7 @@ public class Gl46HierarchicalRenderer implements IRenderInterface debug) { debug.add("Printf Queue: "); debug.addAll(this.printfQueue); + this.printfQueue.clear(); } @@ -210,8 +211,15 @@ public class Gl46HierarchicalRenderer implements IRenderInterface NODE_MSK || (childPtr!=NODE_MSK&&count < 1)) { + if (childPtr > NODE_MSK || ((childPtr!=NODE_MSK&&childPtr!=EMPTY_MESH_ID)&&count < 1)) { throw new IllegalArgumentException(); } long val = this.localNodeData[node*3+1]; @@ -217,7 +221,8 @@ public class NodeManager { } - //IDEA, since a graph node can be in effectivly only 3 states, if inner node -> may or may not have mesh, and, if leaf node -> has mesh, no children + + //The idea is, since a graph node can be in effectivly only 3 states, if inner node -> may or may not have mesh, and, if leaf node -> has mesh, no children // the request queue only needs to supply the node id, since if its an inner node, it must be requesting for a mesh, while if its a leaf node, it must be requesting for children private void processRequestQueue(long ptr, long size) { int count = MemoryUtil.memGetInt(ptr); ptr += 4; @@ -264,7 +269,7 @@ public class NodeManager { //If its not a leaf node, it must be missing the inner mesh so request it if (this.getNodeMesh(node) != MESH_MSK) { //Node already has a mesh, ignore it, but might be a sign that an error has occured - System.err.println("Requested a mesh for node, however the node already has a mesh"); + throw new IllegalStateException("Requested a mesh for node, however the node already has a mesh"); //TODO: need to unmark the node that requested it, either that or only clear node data when a mesh has been removed @@ -289,6 +294,7 @@ public class NodeManager { // the map should be identical to the currently watched set of sections //NOTE: that if the id is negative its part of a mesh request private final Long2IntOpenHashMap pos2meshId = new Long2IntOpenHashMap(); + private final LongOpenHashSet rootPosRequests = new LongOpenHashSet();// private static final int NO_NODE = -1; //The request queue should be like some array that can reuse objects to prevent gc nightmare + like a bitset to find an avalible free slot @@ -310,10 +316,10 @@ public class NodeManager { //TODO: FIXME: CRITICAL: if a section is empty when created, it wont get allocated a slot, however, the section might // become unempty due to an update!!! THIS IS REALLY BAD. since it doesnt have an allocation - - //TODO: test and fix the possible race condition of if a section is not empty then becomes empty in the same tick // that is, there is a request that is satisfied bar 1 section, that section is supplied as non emptpty but then becomes empty in the same tick + + //TODO: Fixme: need to fix/make it so that the system can know if every child (to lod0) is empty or if its just the current section private void meshUpdate(BuiltSection mesh) { int id = this.pos2meshId.get(mesh.position); //TODO: FIXME!! if we get a node that has an update and is watched but no id for it, it could be an update state from @@ -321,11 +327,22 @@ public class NodeManager { // then also update the parent pointer //TODO: Also need a way to remove sections, requires shuffling stuff around if (id == NO_NODE) { - //The built mesh section is no longer needed, discard it - // TODO: could probably?? cache the mesh in ram that way if its requested? it can be immediatly fetched while a newer mesh is built?? - - //This might be a warning? or maybe info? - mesh.free(); + //If its a top level node insertion request, insert the node + if (this.rootPosRequests.remove(mesh.position)) { + if (!mesh.isEmpty()) { + int top = this.nodeAllocations.allocateNext(); + this.rootPos2Id.put(mesh.position, top); + this.setNodePosition(top, mesh.position); + this.setChildPtr(top, NODE_MSK, 0); + this.setMeshId(top, this.meshManager.uploadMesh(mesh)); + this.pushNode(top); + } + } else { + //The built mesh section is no longer needed, discard it + // TODO: could probably?? cache the mesh in ram that way if its requested? it can be immediatly fetched while a newer mesh is built?? + //This might be a warning? or maybe info? + mesh.free(); + } return; } @@ -401,7 +418,8 @@ public class NodeManager { private void completeLeafRequest(LeafRequest request) { - //TODO: need to actually update all of the pos2meshId of the children to point to there new nodes + //TODO: FIXME: need to make it so that if a nodes mesh is empty but there are children that exist that arnt empty + // then it needs to still add the node, but just with an empty mesh flag int msk = Byte.toUnsignedInt(request.nonAirMask()); int baseIdx = this.nodeAllocations.allocateNextConsecutiveCounted(Integer.bitCount(msk)); int cnt = 0; @@ -425,11 +443,12 @@ public class NodeManager { } } if (cnt == 0) { - throw new IllegalStateException("Should not reach here"); + //This means that every child node didnt have a mesh, this is not good + throw new IllegalStateException("Every child node empty for node at " + request.position); + } else { + //Set the ptr + this.setChildPtr(request.nodeId, baseIdx, cnt); } - - //Actually signal the update - this.setChildPtr(request.nodeId, baseIdx, cnt); this.pushNode(request.nodeId); } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/debug/node_outline.vert b/src/main/resources/assets/voxy/shaders/lod/hierarchical/debug/node_outline.vert index bd27fb72..11de85cc 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/debug/node_outline.vert +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/debug/node_outline.vert @@ -29,10 +29,12 @@ void main() { gl_Position = pos; + //node.nodeId uint hash = node.nodeId*1231421+123141; hash ^= hash>>16; hash = hash*1231421+123141; hash ^= hash>>16; hash = hash * 1827364925 + 123325621; - colour = vec4(float(hash&15u)/15, float((hash>>4)&15u)/15, float((hash>>8)&15u)/15, 1); + //colour = vec4(vec3(float(hash&15u)/15, float((hash>>4)&15u)/15, float((hash>>8)&15u)/15), 1); + colour = vec4(vec3(float(hash&31u)/31, float(node.lodLevel)/4, float(node.lodLevel)/4), 1); } \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl index 4eab6acb..4dac8a4c 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl @@ -52,6 +52,10 @@ bool hasMesh(in UnpackedNode node) { return node.meshPtr != NULL_MESH; } +bool isEmptyMesh(in UnpackedNode node) { + return node.meshPtr == (NULL_MESH-1);//Specialcase +} + bool hasChildren(in UnpackedNode node) { return node.childPtr != NULL_NODE; } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp index f661a08d..1715b85c 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp @@ -105,8 +105,8 @@ void enqueueChildren(in UnpackedNode node) { } void enqueueSelfForRender(in UnpackedNode node) { - printf("render %d@[%d,%d,%d]", node.lodLevel, node.pos.x, node.pos.y, node.pos.z); - if (renderQueueIndex < renderQueueMaxSize) { + //printf("render %d@[%d,%d,%d]", node.lodLevel, node.pos.x, node.pos.y, node.pos.z); + if ((!isEmptyMesh(node)) && renderQueueIndex < renderQueueMaxSize) { renderQueue[atomicAdd(renderQueueIndex, 1)] = getMesh(node); } } @@ -128,11 +128,13 @@ void main() { //debugDumpNode(node); - if (outsideFrustum() || isCulledByHiz()) { + if (outsideFrustum()) {// || isCulledByHiz() //printf("HizCulled"); //We are done here, dont do any more, the issue is the shader barriers maybe // its culled, maybe just mark it as culled? - printf("Cull"); + + + //printf("Cull"); } else { //It is visible, TODO: maybe do a more detailed hiz test? (or make it so that )