diff --git a/src/main/java/me/cortex/voxy/client/core/VoxelCore.java b/src/main/java/me/cortex/voxy/client/core/VoxelCore.java index 46ef2c3d..0a00d78c 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxelCore.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxelCore.java @@ -115,21 +115,6 @@ public class VoxelCore { System.out.println("Voxy core initialized"); } - private IRenderInterface createRenderBackend() { - if (false) { - return new Gl46HierarchicalRenderer(this.modelManager); - } else if (true) { - return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); - } else { - if (VoxyConfig.CONFIG.useMeshShaders()) { - return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); - } else { - return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); - } - } - } - - public void enqueueIngest(WorldChunk worldChunk) { this.world.ingestService.enqueueIngest(worldChunk); } @@ -275,4 +260,20 @@ public class VoxelCore { public WorldEngine getWorldEngine() { return this.world; } + + + + private IRenderInterface createRenderBackend() { + if (true) { + return new Gl46HierarchicalRenderer(this.modelManager); + } else if (true) { + return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); + } else { + if (VoxyConfig.CONFIG.useMeshShaders()) { + return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); + } else { + return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); + } + } + } } 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 aee12f30..ef5b9c4c 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 @@ -62,17 +62,17 @@ public class Gl46HierarchicalRenderer implements IRenderInterface> { public int width; public int height; int frameId; - Matrix4f projection; - Matrix4f modelView; - double cameraX; - double cameraY; - double cameraZ; + public Matrix4f projection; + public Matrix4f modelView; + public double cameraX; + public double cameraY; + public double cameraZ; protected Viewport() { } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/HierarchicalOcclusionRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/HierarchicalOcclusionRenderer.java index 0a641d74..2bac563d 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/HierarchicalOcclusionRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/HierarchicalOcclusionRenderer.java @@ -6,13 +6,12 @@ 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.Gl46HierarchicalViewport; import me.cortex.voxy.client.core.rendering.HiZBuffer; -import me.cortex.voxy.client.core.rendering.building.BuiltSection; -import me.cortex.voxy.client.core.rendering.hierarchical.INodeInteractor; -import me.cortex.voxy.client.core.rendering.hierarchical.MeshManager; -import me.cortex.voxy.client.core.rendering.hierarchical.NodeManager; import me.cortex.voxy.client.core.rendering.util.UploadStream; - -import java.util.function.Consumer; +import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection; +import net.minecraft.util.math.MathHelper; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.system.MemoryUtil; import static org.lwjgl.opengl.GL30.glBindBufferBase; import static org.lwjgl.opengl.GL33.glBindSampler; @@ -44,14 +43,32 @@ public class HierarchicalOcclusionRenderer { .compile(); } - private void uploadUniform() { + private void uploadUniform(Gl46HierarchicalViewport viewport) { long ptr = UploadStream.INSTANCE.upload(this.uniformBuffer, 0, 1024); + int sx = MathHelper.floor(viewport.cameraX)>>5; + int sy = MathHelper.floor(viewport.cameraY)>>5; + int sz = MathHelper.floor(viewport.cameraZ)>>5; + new Matrix4f(viewport.projection).mul(viewport.modelView).getToAddress(ptr); ptr += 4*4*4; + + MemoryUtil.memPutInt(ptr, sx); ptr += 4; + MemoryUtil.memPutInt(ptr, sy); ptr += 4; + MemoryUtil.memPutInt(ptr, sz); ptr += 4; + MemoryUtil.memPutInt(ptr, viewport.width); ptr += 4; + + var innerTranslation = new Vector3f((float) (viewport.cameraX-(sx<<5)), (float) (viewport.cameraY-(sy<<5)), (float) (viewport.cameraZ-(sz<<5))); + innerTranslation.getToAddress(ptr); ptr += 4*3; + + MemoryUtil.memPutInt(ptr, viewport.height); ptr += 4; + + MemoryUtil.memPutInt(ptr, NodeManager.REQUEST_QUEUE_SIZE); ptr += 4; + MemoryUtil.memPutInt(ptr, 1000000); ptr += 4; } public void doHierarchicalTraversalSelection(Gl46HierarchicalViewport viewport, int depthBuffer, GlBuffer renderSelectionResult) { - this.uploadUniform(); + this.uploadUniform(viewport); this.nodeManager.upload(); + UploadStream.INSTANCE.commit(); //Make hiz this.hiz.buildMipChain(depthBuffer, viewport.width, viewport.height); @@ -75,6 +92,8 @@ public class HierarchicalOcclusionRenderer { glDispatchCompute(1,1,1); } + glBindSampler(0, 0); + glBindTextureUnit(0, 0); this.nodeManager.download(); } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java index 94cff137..37c9fb3e 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java @@ -129,7 +129,7 @@ public class NodeManager { Arrays.fill(this.localNodeData, 0); - this.setNodePosition(0, WorldEngine.getWorldSectionId(0, 0,5,0)); + this.setNodePosition(0, WorldEngine.getWorldSectionId(2, 0,0,0)); this.setChildPtr(0, NODE_MSK, 0); this.setMeshId(0, MESH_MSK); this.pushNode(0); @@ -165,7 +165,7 @@ public class NodeManager { private boolean isLeafNode(int node) { //TODO: maybe make this flag based instead of checking the child ptr? - return this.getNodeChildPtr(node) != NODE_MSK; + return this.getNodeChildPtr(node) == NODE_MSK; } //Its ment to return if the node is just an empty mesh or if all the children are also empty diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/util/MarkedObjectList.java b/src/main/java/me/cortex/voxy/client/core/rendering/util/MarkedObjectList.java index e4a20c79..e822500d 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/util/MarkedObjectList.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/util/MarkedObjectList.java @@ -10,7 +10,7 @@ public class MarkedObjectList { private final Int2ObjectFunction arrayGenerator; private final Supplier nullSupplier; - private final HierarchicalBitSet bitSet = new HierarchicalBitSet(-1); + private final HierarchicalBitSet bitSet = new HierarchicalBitSet(); private T[] objects;//Should maybe make a getter function instead public MarkedObjectList(Int2ObjectFunction arrayGenerator, Supplier nullSupplier) { diff --git a/src/main/java/me/cortex/voxy/common/util/HierarchicalBitSet.java b/src/main/java/me/cortex/voxy/common/util/HierarchicalBitSet.java index 39f15d69..4a44202a 100644 --- a/src/main/java/me/cortex/voxy/common/util/HierarchicalBitSet.java +++ b/src/main/java/me/cortex/voxy/common/util/HierarchicalBitSet.java @@ -15,6 +15,10 @@ public class HierarchicalBitSet { } } + public HierarchicalBitSet() { + this(1<<(6*4)); + } + public int allocateNext() { if (this.A==-1) { return -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 f81b2198..7aec7c4b 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -50,14 +50,25 @@ void setupScreenspace(in UnpackedNode node) { vec4 pPoint = (VP*vec4(vec3((i&1)!=0,(i&2)!=0,(i&4)!=0)*32,1));//Size of section is 32x32x32 (need to change it to a bounding box in the future) pPoint += base; vec3 point = pPoint.xyz/pPoint.w; + //TODO: CLIP TO VIEWPORT minBB = min(minBB, point); maxBB = max(maxBB, point); } + //printf("Screenspace MIN: %f, %f, %f MAX: %f, %f, %f", minBB.x,minBB.y,minBB.z, maxBB.x,maxBB.y,maxBB.z); size = maxBB.xy - minBB.xy; + +} + +//Checks if the node is implicitly culled (outside frustum) +bool outsideFrustum() { + return any(lessThanEqual(maxBB, vec3(-1f, -1f, 0f))) || any(lessThanEqual(vec3(1f, 1f, 1f), minBB)); } bool isCulledByHiz() { + if (minBB.z < 0) {//Minpoint is behind the camera, its always going to pass + return false; + } vec2 ssize = size.xy * vec2(ivec2(screenW, screenH)); float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1))); vec2 midpoint = (maxBB.xy + minBB.xy)*0.5; @@ -66,5 +77,6 @@ bool isCulledByHiz() { //Returns if we should decend into its children or not bool shouldDecend() { - return (size.x*size.y) > (64*64F); + //printf("Screen area %f: %f, %f", (size.x*size.y*float(screenW)*float(screenH)), float(screenW), float(screenH)); + return (size.x*size.y*screenW*screenH) > (64*64F); } \ No newline at end of file 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 0984eb3e..bb1dd982 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp @@ -77,8 +77,8 @@ layout(binding = 2, std430) restrict buffer QueueData { void addRequest(inout UnpackedNode node) { - printf("requested"); if (!hasRequested(node)) { + printf("requested"); //TODO: maybe try using only 1 variable and it being <0 being bad if (requestQueueIndex < requestQueueMaxSize) { //Mark node as having a request submitted to prevent duplicate submissions @@ -113,7 +113,7 @@ void main() { //debugDumpNode(node); - if (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?