This commit is contained in:
mcrcortex
2024-04-15 01:08:32 +10:00
parent cce96fc867
commit 6ebc4739b9
9 changed files with 149 additions and 5 deletions

View File

@@ -11,7 +11,11 @@ public class GlFramebuffer extends TrackedObject {
}
public GlFramebuffer bind(int attachment, GlTexture texture) {
glNamedFramebufferTexture(this.id, attachment, texture.id, 0);
return this.bind(attachment, texture, 0);
}
public GlFramebuffer bind(int attachment, GlTexture texture, int lvl) {
glNamedFramebufferTexture(this.id, attachment, texture.id, lvl);
return this;
}

View File

@@ -5,11 +5,13 @@ 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.util.UploadStream;
import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.opengl.ARBDirectStateAccess.glGetNamedFramebufferAttachmentParameteriv;
import static org.lwjgl.opengl.ARBIndirectParameters.GL_PARAMETER_BUFFER_ARB;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate;
@@ -56,9 +58,10 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
private final GlBuffer glDrawIndirect;
private final GlBuffer meshletBuffer;
private final HiZBuffer hiZBuffer = new HiZBuffer();
public Gl46MeshletsFarWorldRenderer(int geometrySize, int maxSections) {
super(new DefaultGeometryManager(alignUp(geometrySize*8L, 8*64), maxSections, 8*64));
super(new DefaultGeometryManager(alignUp(geometrySize*8L, 8*32), maxSections, 8*32));
this.glDrawIndirect = new GlBuffer(4*5);
this.meshletBuffer = new GlBuffer(4*1000000);//TODO: Make max meshlet count configurable, not just 1 million (even tho thats a max of 126 million quads per frame)
}
@@ -147,6 +150,14 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
var i = new int[1];
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, i);
this.hiZBuffer.buildMipChain(i[0], MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight);
glBindVertexArray(0);
glBindSampler(0, 0);
glBindTextureUnit(0, 0);
@@ -173,6 +184,8 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
this.glDrawIndirect.free();
this.meshletBuffer.free();
this.hiZBuffer.free();
}
public static long alignUp(long n, long alignment) {

View File

@@ -0,0 +1,98 @@
package me.cortex.voxy.client.core.rendering;
import me.cortex.voxy.client.core.gl.GlFramebuffer;
import me.cortex.voxy.client.core.gl.GlTexture;
import me.cortex.voxy.client.core.gl.shader.Shader;
import me.cortex.voxy.client.core.gl.shader.ShaderType;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.ARBDirectStateAccess.*;
import static org.lwjgl.opengl.GL11C.*;
import static org.lwjgl.opengl.GL30C.*;
import static org.lwjgl.opengl.GL33.glBindSampler;
import static org.lwjgl.opengl.GL33.glGenSamplers;
import static org.lwjgl.opengl.GL33C.glDeleteSamplers;
import static org.lwjgl.opengl.GL45C.glNamedFramebufferTexture;
public class HiZBuffer {
private final Shader hiz = Shader.make()
.add(ShaderType.VERTEX, "voxy:hiz/blit.vsh")
.add(ShaderType.FRAGMENT, "voxy:hiz/blit.fsh")
.compile();
private final GlFramebuffer fb = new GlFramebuffer();
private final int sampler = glGenSamplers();
private GlTexture texture;
private int levels;
private int width;
private int height;
public HiZBuffer() {
glNamedFramebufferDrawBuffer(this.fb.id, GL_NONE);
}
private void alloc(int width, int height) {
this.levels = (int)Math.ceil(Math.log(Math.max(width, height))/Math.log(2));
//We dont care about e.g. 1x1 size texture since you dont get meshlets that big to cover such a large area
this.levels -= 3;//Arbitrary size, shinks the max level by alot and saves a significant amount of processing time
// (could probably increase it to be defined by a max meshlet coverage computation thing)
//We do a hack where we assume (which is probably wrong) that we will on average never
// get a meshlet that uses 0 mipping
this.levels--;
this.texture = new GlTexture().store(GL_DEPTH_COMPONENT32, this.levels, width/2, height/2);
glTextureParameteri(this.texture.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameteri(this.texture.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(this.texture.id, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTextureParameteri(this.texture.id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(this.texture.id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
this.width = width;
this.height = height;
}
public void buildMipChain(int srcDepthTex, int width, int height) {
if (this.width != width || this.height != height) {
if (this.texture != null) {
this.texture.free();
this.texture = null;
}
this.alloc(width, height);
}
glBindVertexArray(AbstractFarWorldRenderer.STATIC_VAO);
int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING);
this.hiz.bind();
this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, 0).verify();
glBindFramebuffer(GL_FRAMEBUFFER, this.fb.id);
glDepthFunc(GL_ALWAYS);
glBindTextureUnit(0, srcDepthTex);
glBindSampler(0, this.sampler);
glUniform1i(0, 0);
int cw = this.width /2;
int ch = this.height/2;
for (int i = 0; i < this.levels; i++) {
this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, i);
glViewport(0, 0, cw, ch); cw /= 2; ch /= 2;
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (i == 0) {
glBindTextureUnit(0, this.texture.id);
}
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, i);
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, i+1);
}
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, 0);
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, this.levels-1);//TODO: CHECK IF ITS -1 or -0
glDepthFunc(GL_LEQUAL);
glBindFramebuffer(GL_FRAMEBUFFER, boundFB);
glViewport(0, 0, width, height);
glBindVertexArray(0);
}
public void free() {
this.fb.free();
this.texture.free();
this.texture = null;
glDeleteSamplers(this.sampler);
}
}

View File

@@ -53,7 +53,7 @@ public class RenderDataFactory {
// can do funny stuff like double rendering
private static final boolean USE_UINT64 = false;//FIXME: replace with automatic detection of uint64 shader extension support
private static final int QUADS_PER_MESHLET = 62;
private static final int QUADS_PER_MESHLET = 30;
private static void writePos(long ptr, long pos) {
if (USE_UINT64) {
MemoryUtil.memPutLong(ptr, pos);

View File

@@ -0,0 +1,9 @@
#version 450
layout(location = 0) in vec2 uv;
layout(binding = 0) uniform sampler2D depthTex;
void main() {
vec4 depths = textureGather(depthTex, uv, 0); // Get depth values from all surrounding texels.
gl_FragDepth = max(max(depths.x, depths.y), max(depths.z, depths.w)); // Write conservative depth.
}

View File

@@ -0,0 +1,8 @@
#version 450
layout(location = 0) out vec2 uv;
void main() {
vec2 corner = vec2[](vec2(0,0), vec2(1,0), vec2(1,1),vec2(0,1))[gl_VertexID];
uv = corner;
gl_Position = vec4(corner*2-1, 0, 1);
}

View File

@@ -7,7 +7,7 @@
#import <voxy:lod/section.glsl>
#define extractMeshletStart extractQuadStart
layout(local_size_x = 64) in;
#define QUADS_PER_MESHLET 62
#define QUADS_PER_MESHLET 30
void emitMeshlets(inout uint mli, inout uint meshletPtr, uint mskedCnt, uint cnt) {
for (;mskedCnt != 0; mskedCnt--,mli++) {

View File

@@ -10,6 +10,7 @@ layout(location = 2) in flat vec4 tinting;
layout(location = 3) in flat vec4 addin;
layout(location = 4) in flat uint flags;
layout(location = 5) in flat vec4 conditionalTinting;
layout(location = 6) in flat uint meshlet;
//layout(location = 6) in flat vec4 solidColour;
layout(location = 0) out vec4 outColour;
@@ -29,4 +30,13 @@ void main() {
outColour = (colour * tinting) + addin;
//outColour = vec4(uv + baseUV, 0, 1);
/*
uint hash = meshlet*1231421+123141;
hash ^= hash>>16;
hash = hash*1231421+123141;
hash ^= hash>>16;
outColour = vec4(float(hash&15u)/15, float((hash>>4)&15u)/15, float((hash>>8)&15u)/15, 1);
*/
}

View File

@@ -1,6 +1,6 @@
#version 450
#extension GL_ARB_gpu_shader_int64 : enable
#define QUADS_PER_MESHLET 62
#define QUADS_PER_MESHLET 30
#define MESHLET_ACCESS readonly
//There are 16 bytes of metadata at the start of the meshlet
@@ -36,6 +36,7 @@ uint extractDetail(PosHeader pos) {
}
#endif
layout(location = 6) out flat uint meshlet;
PosHeader meshletPosition;
Quad quad;
bool setupMeshlet() {
@@ -49,6 +50,7 @@ bool setupMeshlet() {
return true;
}
meshlet = data;
uint baseId = (data*MESHLET_SIZE);
uint quadIndex = baseId + (gl_VertexID>>2) + 2;
meshletPosition = geometryPool[baseId];