wip hiz
This commit is contained in:
@@ -11,7 +11,11 @@ public class GlFramebuffer extends TrackedObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GlFramebuffer bind(int attachment, GlTexture texture) {
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.gl.shader.ShaderType;
|
||||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection;
|
import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
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.ARBIndirectParameters.GL_PARAMETER_BUFFER_ARB;
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate;
|
import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate;
|
||||||
@@ -56,9 +58,10 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
|
|||||||
|
|
||||||
private final GlBuffer glDrawIndirect;
|
private final GlBuffer glDrawIndirect;
|
||||||
private final GlBuffer meshletBuffer;
|
private final GlBuffer meshletBuffer;
|
||||||
|
private final HiZBuffer hiZBuffer = new HiZBuffer();
|
||||||
|
|
||||||
public Gl46MeshletsFarWorldRenderer(int geometrySize, int maxSections) {
|
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.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)
|
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);
|
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);
|
glBindVertexArray(0);
|
||||||
glBindSampler(0, 0);
|
glBindSampler(0, 0);
|
||||||
glBindTextureUnit(0, 0);
|
glBindTextureUnit(0, 0);
|
||||||
@@ -173,6 +184,8 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
|
|||||||
|
|
||||||
this.glDrawIndirect.free();
|
this.glDrawIndirect.free();
|
||||||
this.meshletBuffer.free();
|
this.meshletBuffer.free();
|
||||||
|
|
||||||
|
this.hiZBuffer.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long alignUp(long n, long alignment) {
|
public static long alignUp(long n, long alignment) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ public class RenderDataFactory {
|
|||||||
// can do funny stuff like double rendering
|
// 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 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) {
|
private static void writePos(long ptr, long pos) {
|
||||||
if (USE_UINT64) {
|
if (USE_UINT64) {
|
||||||
MemoryUtil.memPutLong(ptr, pos);
|
MemoryUtil.memPutLong(ptr, pos);
|
||||||
|
|||||||
9
src/main/resources/assets/voxy/shaders/hiz/blit.fsh
Normal file
9
src/main/resources/assets/voxy/shaders/hiz/blit.fsh
Normal 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.
|
||||||
|
}
|
||||||
8
src/main/resources/assets/voxy/shaders/hiz/blit.vsh
Normal file
8
src/main/resources/assets/voxy/shaders/hiz/blit.vsh
Normal 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);
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#import <voxy:lod/section.glsl>
|
#import <voxy:lod/section.glsl>
|
||||||
#define extractMeshletStart extractQuadStart
|
#define extractMeshletStart extractQuadStart
|
||||||
layout(local_size_x = 64) in;
|
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) {
|
void emitMeshlets(inout uint mli, inout uint meshletPtr, uint mskedCnt, uint cnt) {
|
||||||
for (;mskedCnt != 0; mskedCnt--,mli++) {
|
for (;mskedCnt != 0; mskedCnt--,mli++) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ layout(location = 2) in flat vec4 tinting;
|
|||||||
layout(location = 3) in flat vec4 addin;
|
layout(location = 3) in flat vec4 addin;
|
||||||
layout(location = 4) in flat uint flags;
|
layout(location = 4) in flat uint flags;
|
||||||
layout(location = 5) in flat vec4 conditionalTinting;
|
layout(location = 5) in flat vec4 conditionalTinting;
|
||||||
|
layout(location = 6) in flat uint meshlet;
|
||||||
//layout(location = 6) in flat vec4 solidColour;
|
//layout(location = 6) in flat vec4 solidColour;
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColour;
|
layout(location = 0) out vec4 outColour;
|
||||||
@@ -29,4 +30,13 @@ void main() {
|
|||||||
outColour = (colour * tinting) + addin;
|
outColour = (colour * tinting) + addin;
|
||||||
|
|
||||||
//outColour = vec4(uv + baseUV, 0, 1);
|
//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);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_gpu_shader_int64 : enable
|
#extension GL_ARB_gpu_shader_int64 : enable
|
||||||
#define QUADS_PER_MESHLET 62
|
#define QUADS_PER_MESHLET 30
|
||||||
|
|
||||||
#define MESHLET_ACCESS readonly
|
#define MESHLET_ACCESS readonly
|
||||||
//There are 16 bytes of metadata at the start of the meshlet
|
//There are 16 bytes of metadata at the start of the meshlet
|
||||||
@@ -36,6 +36,7 @@ uint extractDetail(PosHeader pos) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
layout(location = 6) out flat uint meshlet;
|
||||||
PosHeader meshletPosition;
|
PosHeader meshletPosition;
|
||||||
Quad quad;
|
Quad quad;
|
||||||
bool setupMeshlet() {
|
bool setupMeshlet() {
|
||||||
@@ -49,6 +50,7 @@ bool setupMeshlet() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meshlet = data;
|
||||||
uint baseId = (data*MESHLET_SIZE);
|
uint baseId = (data*MESHLET_SIZE);
|
||||||
uint quadIndex = baseId + (gl_VertexID>>2) + 2;
|
uint quadIndex = baseId + (gl_VertexID>>2) + 2;
|
||||||
meshletPosition = geometryPool[baseId];
|
meshletPosition = geometryPool[baseId];
|
||||||
|
|||||||
Reference in New Issue
Block a user