From a25447a92b096b7c4b1feaafd5d9eb2b0c747573 Mon Sep 17 00:00:00 2001 From: mcrcortex <{ID}+{username}@users.noreply.github.com> Date: Sun, 14 Apr 2024 02:09:39 +1000 Subject: [PATCH] It dobedobedoba be partially working --- .../Gl46MeshletsFarWorldRenderer.java | 19 ++- .../rendering/building/RenderDataFactory.java | 142 +++++++++++++++--- .../voxy/shaders/lod/gl46mesh/bindings.glsl | 3 +- .../voxy/shaders/lod/gl46mesh/cull.frag | 13 +- .../voxy/shaders/lod/gl46mesh/cull.vert | 29 +++- .../voxy/shaders/lod/gl46mesh/quads.vert | 47 +++++- 6 files changed, 220 insertions(+), 33 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46MeshletsFarWorldRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46MeshletsFarWorldRenderer.java index 8019bb72..99b79e2a 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46MeshletsFarWorldRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46MeshletsFarWorldRenderer.java @@ -63,17 +63,17 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer>32)); + MemoryUtil.memPutInt(ptr + 4, (int)pos); + } + } //section is already acquired and gets released by the parent public BuiltSection generateMesh(WorldSection section) { @@ -76,38 +86,122 @@ public class RenderDataFactory { this.generateMeshForAxis(section, 1);//Direction.Axis.Z this.generateMeshForAxis(section, 2);//Direction.Axis.X - int quadCount = this.doubleSidedQuadCollector.size() + this.translucentQuadCollector.size(); - for (var collector : this.directionalQuadCollectors) { - quadCount += collector.size(); + int bufferSize; + if (this.generateMeshlets) { + bufferSize = getMeshletHoldingCount(this.doubleSidedQuadCollector.size(), 126, 128) + + getMeshletHoldingCount(this.translucentQuadCollector.size(), 126, 128); + for (var collector : this.directionalQuadCollectors) { + bufferSize += getMeshletHoldingCount(collector.size(), 126, 128); + } + } else { + bufferSize = this.doubleSidedQuadCollector.size() + this.translucentQuadCollector.size(); + for (var collector : this.directionalQuadCollectors) { + bufferSize += collector.size(); + } } - if (quadCount == 0) { + if (bufferSize == 0) { return new BuiltSection(section.key); } //TODO: generate the meshlets here - - var buff = new MemoryBuffer(quadCount*8L); - long ptr = buff.address; + MemoryBuffer buff; int[] offsets = new int[8]; - int coff = 0; + if (this.generateMeshlets) { + long key = section.key; + buff = new MemoryBuffer(bufferSize * 8L); + long ptr = buff.address; + MemoryUtil.memSet(ptr, -1, bufferSize * 8L); + int meshlet = 0; + int innerQuadCount = 0; - //Ordering is: translucent, double sided quads, directional quads - offsets[0] = coff; - for (long data : this.translucentQuadCollector) { - MemoryUtil.memPutLong(ptr + ((coff++)*8L), data); - } + //Ordering is: translucent, double sided quads, directional quads + offsets[0] = meshlet; + for (long data : this.translucentQuadCollector) { + if (innerQuadCount == 0) { + //Write out meshlet header - offsets[1] = coff; - for (long data : this.doubleSidedQuadCollector) { - MemoryUtil.memPutLong(ptr + ((coff++)*8L), data); - } + //Write out the section position + writePos(ptr + meshlet * 8L * 128L, key); + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0); + } + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data); + if (innerQuadCount == 126) { + innerQuadCount = 0; + meshlet++; + } + } - for (int face = 0; face < 6; face++) { - offsets[face+2] = coff; - for (long data : this.directionalQuadCollectors[face]) { + if (innerQuadCount != 0) { + meshlet++; + innerQuadCount = 0; + } + + offsets[1] = meshlet; + for (long data : this.doubleSidedQuadCollector) { + if (innerQuadCount == 0) { + //Write out meshlet header + + //Write out the section position + writePos(ptr + meshlet * 8L * 128L, key); + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0); + } + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data); + if (innerQuadCount == 126) { + innerQuadCount = 0; + meshlet++; + } + } + + if (innerQuadCount != 0) { + meshlet++; + innerQuadCount = 0; + } + + for (int face = 0; face < 6; face++) { + offsets[face + 2] = meshlet; + for (long data : this.directionalQuadCollectors[face]) { + if (innerQuadCount == 0) { + //Write out meshlet header + + //Write out the section position + writePos(ptr + meshlet * 8L * 128L, key); + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0); + } + MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data); + if (innerQuadCount == 126) { + innerQuadCount = 0; + meshlet++; + } + } + + if (innerQuadCount != 0) { + meshlet++; + innerQuadCount = 0; + } + } + } else { + buff = new MemoryBuffer(bufferSize * 8L); + long ptr = buff.address; + int coff = 0; + + //Ordering is: translucent, double sided quads, directional quads + offsets[0] = coff; + for (long data : this.translucentQuadCollector) { MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data); } + + offsets[1] = coff; + for (long data : this.doubleSidedQuadCollector) { + MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data); + } + + for (int face = 0; face < 6; face++) { + offsets[face + 2] = coff; + for (long data : this.directionalQuadCollectors[face]) { + MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data); + } + } } int aabb = 0; @@ -323,4 +417,12 @@ public class RenderDataFactory { } } } + + private static int getMeshletHoldingCount(int quads, int quadsPerMeshlet, int meshletSize) { + return ((quads+(quadsPerMeshlet-1))/quadsPerMeshlet)*meshletSize; + } + + public static int alignUp(int n, int alignment) { + return (n + alignment - 1) & -alignment; + } } \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/bindings.glsl b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/bindings.glsl index f222c5a6..68767a12 100644 --- a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/bindings.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/bindings.glsl @@ -1,3 +1,4 @@ +#line 1 struct Frustum { vec4 planes[6]; }; @@ -51,7 +52,7 @@ layout(binding = 2, std430) restrict buffer DrawBuffer { DrawCommand drawCmd; }; -#ifndef Quad +#ifndef MESHLET_ACCESS #define MESHLET_ACCESS readonly writeonly #endif layout(binding = 3, std430) MESHLET_ACCESS restrict buffer MeshletListData { diff --git a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.frag b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.frag index 542def86..45e78654 100644 --- a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.frag +++ b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.frag @@ -1,3 +1,14 @@ -#version 450 +#version 460 core +#extension GL_ARB_gpu_shader_int64 : enable +#define VISIBILITY_ACCESS writeonly +#import +layout(early_fragment_tests) in; + +flat in uint id; +flat in uint value; +out vec4 colour; + void main() { + visibilityData[id] = value; + colour = vec4(float(id&7u)/7, float((id>>3)&7u)/7, float((id>>6)&7u)/7, 1); } \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.vert b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.vert index 542def86..9cf57195 100644 --- a/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.vert +++ b/src/main/resources/assets/voxy/shaders/lod/gl46mesh/cull.vert @@ -1,3 +1,30 @@ -#version 450 +#version 460 core +#extension GL_ARB_gpu_shader_int64 : enable +#define VISIBILITY_ACCESS writeonly +#import +#import + +flat out uint id; +flat out uint value; + void main() { + uint sid = gl_InstanceID; + + SectionMeta section = sectionData[sid]; + + uint detail = extractDetail(section); + ivec3 ipos = extractPosition(section); + ivec3 aabbOffset = extractAABBOffset(section); + ivec3 size = extractAABBSize(section); + + //Transform ipos with respect to the vertex corner + ivec3 pos = (((ipos<>2)&1, (gl_VertexID>>1)&1)*(size+2))*(1< #import -#import -#define GEOMETRY_FMT Quad +#define PosHeader Quad -GEOMETRY_FMT meshletPosition; + +#ifdef GL_ARB_gpu_shader_int64 +ivec3 extractPosition(PosHeader pos64) { + //((long)lvl<<60)|((long)(y&0xFF)<<52)|((long)(z&((1<<24)-1))<<28)|((long)(x&((1<<24)-1))<<4); + //return ivec3((pos64<<4)&uint64_t(0xFFFFFFFF),(pos64>>28)&uint64_t(0xFFFFFFFF),(pos64>>24)&uint64_t(0xFFFFFFFF))>>ivec3(8,24,8); + return (ivec3(int(pos64>>4)&((1<<24)-1), int(pos64>>52)&0xFF, int(pos64>>28)&((1<<24)-1))<>ivec3(8,24,8); +} +uint extractDetail(PosHeader pos64) { + return uint(pos64>>60); +} +#else +ivec3 extractPosition(PosHeader pos) { + int y = ((int(pos.x)<<4)>>24); + int x = (int(pos.y)<<4)>>8; + int z = int((pos.x&((1<<20)-1))<<4); + z |= int(pos.y>>28)&0xF; + z <<= 8; + z >>= 8; + return ivec3(x,y,z); +} + +uint extractDetail(PosHeader pos) { + return uint(pos.x)>>28; +} +#endif + +PosHeader meshletPosition; Quad quad; bool setupMeshlet() { gl_CullDistance[0] = 1; @@ -23,7 +48,7 @@ bool setupMeshlet() { return true; } - uint baseId = (data*QUADS_PER_MESHLET); + uint baseId = (data*MESHLET_SIZE); uint quadIndex = baseId + (gl_VertexID>>2) + 2; meshletPosition = geometryPool[baseId]; quad = geometryPool[quadIndex]; @@ -35,7 +60,21 @@ bool setupMeshlet() { } void main() { + if (setupMeshlet()) { + gl_Position = vec4(1.0f/0.0f); return; } + if ((gl_VertexID>>2)!=0) { + gl_Position = vec4(1.0f/0.0f); + return; + } + + uint detail = extractDetail(meshletPosition); + ivec3 sectionPos = extractPosition(meshletPosition); + + ivec3 pos = (((sectionPos<>1)&1)*(1<