Performance tinkering

This commit is contained in:
mcrcortex
2024-07-15 10:41:04 +10:00
parent 37b85057c3
commit 91e93dea2b
10 changed files with 195 additions and 77 deletions

View File

@@ -72,6 +72,10 @@ dependencies {
modCompileOnly("maven.modrinth:chunky:1.3.138") modCompileOnly("maven.modrinth:chunky:1.3.138")
modRuntimeOnly("maven.modrinth:chunky:1.3.138") modRuntimeOnly("maven.modrinth:chunky:1.3.138")
modRuntimeOnly("maven.modrinth:spark:1.10.73-fabric")
modRuntimeOnly("maven.modrinth:fabric-permissions-api:0.3.1")
modRuntimeOnly("maven.modrinth:nsight-loader:1.2.0")
modImplementation('io.github.douira:glsl-transformer:2.0.1') modImplementation('io.github.douira:glsl-transformer:2.0.1')
} }

View File

@@ -44,6 +44,13 @@ import static org.lwjgl.opengl.GL30C.GL_DRAW_FRAMEBUFFER_BINDING;
//There is strict forward only dataflow //There is strict forward only dataflow
//Ingest -> world engine -> raw render data -> render data //Ingest -> world engine -> raw render data -> render data
//REDESIGN THIS PIECE OF SHIT SPAGETTY SHIT FUCK
// like Get rid of interactor and renderer being seperate just fucking put them together
// fix the callback bullshit spagetti
//REMOVE setRenderGen like holy hell
public class VoxelCore { public class VoxelCore {
private final WorldEngine world; private final WorldEngine world;
private final RenderGenerationService renderGen; private final RenderGenerationService renderGen;
@@ -67,9 +74,16 @@ public class VoxelCore {
Capabilities.init();//Ensure clinit is called Capabilities.init();//Ensure clinit is called
this.modelManager = new ModelManager(16); this.modelManager = new ModelManager(16);
this.renderer = this.createRenderBackend(); this.renderer = this.createRenderBackend();
System.out.println("Using " + this.renderer.getClass().getSimpleName());
this.viewportSelector = new ViewportSelector<>(this.renderer::createViewport); this.viewportSelector = new ViewportSelector<>(this.renderer::createViewport);
System.out.println("Renderer initialized");
//Ungodly hacky code
if (this.renderer instanceof AbstractRenderWorldInteractor) {
this.interactor = (AbstractRenderWorldInteractor) this.renderer;
} else {
this.interactor = new DefaultRenderWorldInteractor(cfg, this.world, this.renderer); this.interactor = new DefaultRenderWorldInteractor(cfg, this.world, this.renderer);
}
System.out.println("Renderer initialized");
this.renderGen = new RenderGenerationService(this.world, this.modelManager, VoxyConfig.CONFIG.renderThreads, this.interactor::processBuildResult, this.renderer.generateMeshlets()); this.renderGen = new RenderGenerationService(this.world, this.modelManager, VoxyConfig.CONFIG.renderThreads, this.interactor::processBuildResult, this.renderer.generateMeshlets());
this.world.setDirtyCallback(this.interactor::sectionUpdated); this.world.setDirtyCallback(this.interactor::sectionUpdated);
@@ -101,16 +115,15 @@ public class VoxelCore {
System.out.println("Voxy core initialized"); System.out.println("Voxy core initialized");
} }
private AbstractFarWorldRenderer<?,?> createRenderBackend() { private IRenderInterface<?> createRenderBackend() {
if (false) { if (false) {
System.out.println("Using Gl46MeshletFarWorldRendering"); return new Gl46HierarchicalRenderer(this.modelManager);
} else if (true) {
return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
} else { } else {
if (VoxyConfig.CONFIG.useMeshShaders()) { if (VoxyConfig.CONFIG.useMeshShaders()) {
System.out.println("Using NvMeshFarWorldRenderer");
return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
} else { } else {
System.out.println("Using Gl46FarWorldRenderer");
return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections); return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
} }
} }
@@ -124,6 +137,7 @@ public class VoxelCore {
boolean firstTime = true; boolean firstTime = true;
public void renderSetup(Frustum frustum, Camera camera) { public void renderSetup(Frustum frustum, Camera camera) {
if (this.firstTime) { if (this.firstTime) {
//TODO: remove initPosition
this.interactor.initPosition(camera.getBlockPos().getX(), camera.getBlockPos().getZ()); this.interactor.initPosition(camera.getBlockPos().getX(), camera.getBlockPos().getZ());
this.firstTime = false; this.firstTime = false;
//this.renderTracker.addLvl0(0,6,0); //this.renderTracker.addLvl0(0,6,0);

View File

@@ -1,11 +1,20 @@
package me.cortex.voxy.client.core.rendering; package me.cortex.voxy.client.core.rendering;
import me.cortex.voxy.client.core.AbstractRenderWorldInteractor;
import me.cortex.voxy.client.core.gl.GlBuffer; import me.cortex.voxy.client.core.gl.GlBuffer;
import me.cortex.voxy.client.core.gl.shader.PrintfInjector;
import me.cortex.voxy.client.core.gl.shader.Shader; 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.model.ModelManager;
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
import me.cortex.voxy.client.core.rendering.building.RenderDataFactory; import me.cortex.voxy.client.core.rendering.building.RenderDataFactory;
import me.cortex.voxy.client.core.rendering.building.RenderGenerationService;
import me.cortex.voxy.client.core.rendering.hierarchical.HierarchicalOcclusionRenderer;
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.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 me.cortex.voxy.common.world.WorldSection;
import me.cortex.voxy.common.world.other.Mapper; import me.cortex.voxy.common.world.other.Mapper;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera; import net.minecraft.client.render.Camera;
@@ -16,6 +25,7 @@ import org.joml.Vector3f;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
@@ -35,10 +45,41 @@ import static org.lwjgl.opengl.GL43.*;
import static org.lwjgl.opengl.GL45.glBindTextureUnit; import static org.lwjgl.opengl.GL45.glBindTextureUnit;
import static org.lwjgl.opengl.GL45.nglClearNamedBufferSubData; import static org.lwjgl.opengl.GL45.nglClearNamedBufferSubData;
public class Gl46HierarchicalRenderer implements IRenderInterface { public class Gl46HierarchicalRenderer implements IRenderInterface<Gl46HierarchicalViewport>, AbstractRenderWorldInteractor {
private final HierarchicalOcclusionRenderer sectionSelector;
private final MeshManager meshManager = new MeshManager();
private final PrintfInjector printf = new PrintfInjector(100000, 10, System.out::println);
private final GlBuffer renderSections = new GlBuffer(100_000 * 4 + 4).zero();
private final ModelManager modelManager;
private RenderGenerationService sectionGenerationService;
private Consumer<BuiltSection> resultConsumer;
public Gl46HierarchicalRenderer(ModelManager model) {
this.modelManager = model;
this.sectionSelector = new HierarchicalOcclusionRenderer(new INodeInteractor() {
@Override @Override
public Viewport createViewport() { public void watchUpdates(long pos) {
return null;
}
@Override
public void unwatchUpdates(long pos) {
}
@Override
public void requestMesh(long pos) {
}
@Override
public void setMeshUpdateCallback(Consumer<BuiltSection> mesh) {
Gl46HierarchicalRenderer.this.resultConsumer = mesh;
}
}, this.meshManager, this.printf);
} }
@Override @Override
@@ -47,19 +88,36 @@ public class Gl46HierarchicalRenderer implements IRenderInterface {
} }
@Override @Override
public void renderFarAwayOpaque(Viewport viewport) { public void renderFarAwayOpaque(Gl46HierarchicalViewport viewport) {
//Render terrain from previous frame (renderSections)
{//Run the hierarchical selector over the buffer to generate the set of render sections
var i = new int[1];
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, i);
this.sectionSelector.doHierarchicalTraversalSelection(viewport, i[0], this.renderSections);
}
this.printf.download();
}
@Override
public void renderFarAwayTranslucent(Gl46HierarchicalViewport viewport) {
} }
@Override @Override
public void renderFarAwayTranslucent(Viewport viewport) { public void addDebugData(List<String> debug) {
} }
@Override
public void shutdown() {
}
@Override @Override
public void addBlockState(Mapper.StateEntry stateEntry) { public void addBlockState(Mapper.StateEntry stateEntry) {
@@ -71,13 +129,60 @@ public class Gl46HierarchicalRenderer implements IRenderInterface {
} }
@Override
public void processBuildResult(BuiltSection section) {
}
@Override
public void sectionUpdated(WorldSection worldSection) {
}
@Override
public void initPosition(int x, int z) {
}
@Override
public void setCenter(int x, int y, int z) {
}
@Override @Override
public boolean generateMeshlets() { public boolean generateMeshlets() {
return false; return false;
} }
@Override @Override
public void addDebugData(List debug) { public void setRenderGen(RenderGenerationService renderService) {
this.sectionGenerationService = renderService;
}
@Override
public Gl46HierarchicalViewport createViewport() {
return new Gl46HierarchicalViewport(this);
}
@Override
public void shutdown() {
this.meshManager.free();
this.sectionSelector.free();
this.printf.free();
} }
} }

View File

@@ -85,6 +85,7 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
glTextureParameteri(this.hizSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTextureParameteri(this.hizSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTextureParameteri(this.hizSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTextureParameteri(this.hizSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTextureParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/* /*
nglClearNamedBufferData(this.meshletBuffer.id, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); nglClearNamedBufferData(this.meshletBuffer.id, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
@@ -166,6 +167,7 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
this.lodShader.bind(); this.lodShader.bind();
this.bindResources(viewport, true, false, false); this.bindResources(viewport, true, false, false);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 4*4); glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 4*4);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);

View File

@@ -3,8 +3,8 @@ package me.cortex.voxy.client.core.rendering;
import org.joml.Matrix4f; import org.joml.Matrix4f;
public abstract class Viewport <A extends Viewport<A>> { public abstract class Viewport <A extends Viewport<A>> {
int width; public int width;
int height; public int height;
int frameId; int frameId;
Matrix4f projection; Matrix4f projection;
Matrix4f modelView; Matrix4f modelView;

View File

@@ -55,7 +55,7 @@ public class RenderDataFactory {
// can do funny stuff like double rendering // can do funny stuff like double rendering
private static final boolean USE_UINT64 = Capabilities.INSTANCE.INT64_t; private static final boolean USE_UINT64 = Capabilities.INSTANCE.INT64_t;
public static final int QUADS_PER_MESHLET = 62; public static final int QUADS_PER_MESHLET = 14;
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);

View File

@@ -4,6 +4,7 @@ import me.cortex.voxy.client.core.gl.GlBuffer;
import me.cortex.voxy.client.core.gl.shader.PrintfInjector; import me.cortex.voxy.client.core.gl.shader.PrintfInjector;
import me.cortex.voxy.client.core.gl.shader.Shader; 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.Gl46HierarchicalViewport;
import me.cortex.voxy.client.core.rendering.HiZBuffer; import me.cortex.voxy.client.core.rendering.HiZBuffer;
import me.cortex.voxy.client.core.rendering.building.BuiltSection; 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.INodeInteractor;
@@ -22,47 +23,25 @@ import static org.lwjgl.opengl.GL43.glDispatchCompute;
import static org.lwjgl.opengl.GL45.glBindTextureUnit; import static org.lwjgl.opengl.GL45.glBindTextureUnit;
public class HierarchicalOcclusionRenderer { public class HierarchicalOcclusionRenderer {
private PrintfInjector printf = new PrintfInjector(100000, 10, System.out::println);
private final MeshManager meshManager = new MeshManager();
private final NodeManager nodeManager = new NodeManager(new INodeInteractor() {
@Override
public void watchUpdates(long pos) {
}
@Override
public void unwatchUpdates(long pos) {
}
@Override
public void requestMesh(long pos) {
}
@Override
public void setMeshUpdateCallback(Consumer<BuiltSection> mesh) {
}
}, this.meshManager);
private final HiZBuffer hiz = new HiZBuffer(); private final HiZBuffer hiz = new HiZBuffer();
private final int hizSampler = glGenSamplers(); private final int hizSampler = glGenSamplers();
private final Shader hierarchicalTraversal = Shader.make(this.printf) private final NodeManager nodeManager;
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/traversal.comp") private final Shader hierarchicalTraversal;
.compile(); private final PrintfInjector printf;
private final GlBuffer nodeQueue; private final GlBuffer nodeQueue;
private final GlBuffer renderQueue;
private final GlBuffer uniformBuffer; private final GlBuffer uniformBuffer;
public HierarchicalOcclusionRenderer() { public HierarchicalOcclusionRenderer(INodeInteractor interactor, MeshManager mesh, PrintfInjector printf) {
this.nodeManager = new NodeManager(interactor, mesh);
this.nodeQueue = new GlBuffer(1000000*4+4).zero(); this.nodeQueue = new GlBuffer(1000000*4+4).zero();
this.renderQueue = new GlBuffer(1000000*4+4).zero();
this.uniformBuffer = new GlBuffer(1024).zero(); this.uniformBuffer = new GlBuffer(1024).zero();
this.printf = printf;
this.hierarchicalTraversal = Shader.make(printf)
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/traversal.comp")
.compile();
} }
private void uploadUniform() { private void uploadUniform() {
@@ -70,11 +49,12 @@ public class HierarchicalOcclusionRenderer {
} }
private void doHierarchicalTraversal(int depthBuffer, int width, int height) { public void doHierarchicalTraversalSelection(Gl46HierarchicalViewport viewport, int depthBuffer, GlBuffer renderSelectionResult) {
this.uploadUniform(); this.uploadUniform();
this.nodeManager.upload(); this.nodeManager.upload();
//Make hiz //Make hiz
this.hiz.buildMipChain(depthBuffer, width, height); this.hiz.buildMipChain(depthBuffer, viewport.width, viewport.height);
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
this.hierarchicalTraversal.bind(); this.hierarchicalTraversal.bind();
@@ -83,7 +63,7 @@ public class HierarchicalOcclusionRenderer {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this.nodeManager.nodeBuffer.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this.nodeManager.nodeBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, this.nodeQueue.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, this.nodeQueue.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.nodeManager.requestQueue.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.nodeManager.requestQueue.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.renderQueue.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, renderSelectionResult.id);
//Bind the hiz buffer //Bind the hiz buffer
glBindSampler(0, this.hizSampler); glBindSampler(0, this.hizSampler);
@@ -98,20 +78,10 @@ public class HierarchicalOcclusionRenderer {
this.nodeManager.download(); this.nodeManager.download();
} }
public void render(int depthBuffer, int width, int height) {
this.doHierarchicalTraversal(depthBuffer, width, height);
this.printf.download();
}
public void free() { public void free() {
this.nodeQueue.free(); this.nodeQueue.free();
this.renderQueue.free();
this.printf.free();
this.hiz.free(); this.hiz.free();
this.nodeManager.free(); this.nodeManager.free();
this.meshManager.free();
glDeleteSamplers(this.hizSampler); glDeleteSamplers(this.hizSampler);
} }
} }

View File

@@ -11,9 +11,9 @@ public class IndexUtil {
MemoryBuffer buffer = new MemoryBuffer(quadCount * 6L); MemoryBuffer buffer = new MemoryBuffer(quadCount * 6L);
long ptr = buffer.address; long ptr = buffer.address;
for(int i = 0; i < quadCount*4; i += 4) { for(int i = 0; i < quadCount*4; i += 4) {
MemoryUtil.memPutByte(ptr + (0), (byte) i); MemoryUtil.memPutByte(ptr + (0), (byte) (i + 1));
MemoryUtil.memPutByte(ptr + (1), (byte) (i + 1)); MemoryUtil.memPutByte(ptr + (1), (byte) (i + 2));
MemoryUtil.memPutByte(ptr + (2), (byte) (i + 2)); MemoryUtil.memPutByte(ptr + (2), (byte) (i + 0));
MemoryUtil.memPutByte(ptr + (3), (byte) (i + 1)); MemoryUtil.memPutByte(ptr + (3), (byte) (i + 1));
MemoryUtil.memPutByte(ptr + (4), (byte) (i + 3)); MemoryUtil.memPutByte(ptr + (4), (byte) (i + 3));
MemoryUtil.memPutByte(ptr + (5), (byte) (i + 2)); MemoryUtil.memPutByte(ptr + (5), (byte) (i + 2));
@@ -30,9 +30,9 @@ public class IndexUtil {
MemoryBuffer buffer = new MemoryBuffer(quadCount * 6L * 2); MemoryBuffer buffer = new MemoryBuffer(quadCount * 6L * 2);
long ptr = buffer.address; long ptr = buffer.address;
for(int i = 0; i < quadCount*4; i += 4) { for(int i = 0; i < quadCount*4; i += 4) {
MemoryUtil.memPutShort(ptr + (0*2), (short) i); MemoryUtil.memPutShort(ptr + (0*2), (short) (i + 1));
MemoryUtil.memPutShort(ptr + (1*2), (short) (i + 1)); MemoryUtil.memPutShort(ptr + (1*2), (short) (i + 2));
MemoryUtil.memPutShort(ptr + (2*2), (short) (i + 2)); MemoryUtil.memPutShort(ptr + (2*2), (short) (i + 0));
MemoryUtil.memPutShort(ptr + (3*2), (short) (i + 1)); MemoryUtil.memPutShort(ptr + (3*2), (short) (i + 1));
MemoryUtil.memPutShort(ptr + (4*2), (short) (i + 3)); MemoryUtil.memPutShort(ptr + (4*2), (short) (i + 3));
MemoryUtil.memPutShort(ptr + (5*2), (short) (i + 2)); MemoryUtil.memPutShort(ptr + (5*2), (short) (i + 2));

View File

@@ -4,17 +4,22 @@ layout(binding = 0) uniform sampler2D blockModelAtlas;
//TODO: need to fix when merged quads have discardAlpha set to false but they span multiple tiles //TODO: need to fix when merged quads have discardAlpha set to false but they span multiple tiles
// however they are not a full block // however they are not a full block
//#define DEBUG_MESHLETS_ONLY
#ifndef DEBUG_MESHLETS_ONLY
layout(location = 0) in vec2 uv; layout(location = 0) in vec2 uv;
layout(location = 1) in flat vec2 baseUV; layout(location = 1) in flat vec2 baseUV;
layout(location = 2) in flat vec4 tinting; 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;
#else
layout(location = 6) in flat uint meshlet; layout(location = 6) in flat uint meshlet;
//layout(location = 6) in flat vec4 solidColour; #endif
layout(location = 0) out vec4 outColour; layout(location = 0) out vec4 outColour;
void main() { void main() {
#ifndef DEBUG_MESHLETS_ONLY
vec2 uv = mod(uv, vec2(1.0))*(1.0/(vec2(3.0,2.0)*256.0)); vec2 uv = mod(uv, vec2(1.0))*(1.0/(vec2(3.0,2.0)*256.0));
//vec4 colour = solidColour; //vec4 colour = solidColour;
vec4 colour = texture(blockModelAtlas, uv + baseUV, ((flags>>1)&1u)*-4.0); vec4 colour = texture(blockModelAtlas, uv + baseUV, ((flags>>1)&1u)*-4.0);
@@ -30,12 +35,12 @@ void main() {
outColour = (colour * tinting) + addin; outColour = (colour * tinting) + addin;
//outColour = vec4(uv + baseUV, 0, 1); //outColour = vec4(uv + baseUV, 0, 1);
#else
uint hash = meshlet*1231421+123141; uint hash = meshlet*1231421+123141;
hash ^= hash>>16; hash ^= hash>>16;
hash = hash*1231421+123141; hash = hash*1231421+123141;
hash ^= hash>>16; hash ^= hash>>16;
hash = hash * 1827364925 + 123325621; hash = hash * 1827364925 + 123325621;
//outColour = vec4(float(hash&15u)/15, float((hash>>4)&15u)/15, float((hash>>8)&15u)/15, 1); outColour = vec4(float(hash&15u)/15, float((hash>>4)&15u)/15, float((hash>>8)&15u)/15, 1);
#endif
} }

View File

@@ -2,12 +2,17 @@
#extension GL_ARB_gpu_shader_int64 : enable #extension GL_ARB_gpu_shader_int64 : enable
#extension GL_ARB_shader_draw_parameters : require #extension GL_ARB_shader_draw_parameters : require
//#define DEBUG_MESHLETS_ONLY
#import <voxy:lod/quad_format.glsl> #import <voxy:lod/quad_format.glsl>
#import <voxy:lod/gl46mesh/bindings.glsl> #import <voxy:lod/gl46mesh/bindings.glsl>
#import <voxy:lod/block_model.glsl> #import <voxy:lod/block_model.glsl>
#import <voxy:lod/gl46mesh/meshlet.glsl> #import <voxy:lod/gl46mesh/meshlet.glsl>
#ifdef DEBUG_MESHLETS_ONLY
layout(location = 6) out flat uint meshlet; layout(location = 6) out flat uint meshlet;
#endif
PosHeader meshletPosition; PosHeader meshletPosition;
Quad quad; Quad quad;
bool setupMeshlet() { bool setupMeshlet() {
@@ -21,7 +26,11 @@ bool setupMeshlet() {
return true; return true;
} }
#ifdef DEBUG_MESHLETS_ONLY
meshlet = data; meshlet = data;
#endif
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];
@@ -35,13 +44,14 @@ bool setupMeshlet() {
#ifndef DEBUG_MESHLETS_ONLY
layout(location = 0) out vec2 uv; layout(location = 0) out vec2 uv;
layout(location = 1) out flat vec2 baseUV; layout(location = 1) out flat vec2 baseUV;
layout(location = 2) out flat vec4 tinting; layout(location = 2) out flat vec4 tinting;
layout(location = 3) out flat vec4 addin; layout(location = 3) out flat vec4 addin;
layout(location = 4) out flat uint flags; layout(location = 4) out flat uint flags;
layout(location = 5) out flat vec4 conditionalTinting; layout(location = 5) out flat vec4 conditionalTinting;
#endif
vec4 uint2vec4RGBA(uint colour) { vec4 uint2vec4RGBA(uint colour) {
return vec4((uvec4(colour)>>uvec4(24,16,8,0))&uvec4(0xFF))/255.0; return vec4((uvec4(colour)>>uvec4(24,16,8,0))&uvec4(0xFF))/255.0;
@@ -100,12 +110,18 @@ void main() {
bool isShaded = hasAO;//TODO: make this a per face flag bool isShaded = hasAO;//TODO: make this a per face flag
vec2 modelUV = vec2(modelId&0xFFu, (modelId>>8)&0xFFu)*(1.0/(256.0));
baseUV = modelUV + (vec2(face>>1, face&1u) * (1.0/(vec2(3.0, 2.0)*256.0)));
ivec2 quadSize = extractSize(quad); ivec2 quadSize = extractSize(quad);
{ //Generate tinting and flag data #ifndef DEBUG_MESHLETS_ONLY
//Exploit provoking vertex to do less work
//if (cornerIdx==1)
{
vec2 modelUV = vec2(modelId&0xFFu, (modelId>>8)&0xFFu)*(1.0/(256.0));
baseUV = modelUV + (vec2(face>>1, face&1u) * (1.0/(vec2(3.0, 2.0)*256.0)));
//Generate tinting and flag data
flags = faceHasAlphaCuttout(faceData); flags = faceHasAlphaCuttout(faceData);
//We need to have a conditional override based on if the model size is < a full face + quadSize > 1 //We need to have a conditional override based on if the model size is < a full face + quadSize > 1
@@ -152,6 +168,7 @@ void main() {
} }
} }
} }
#endif
@@ -160,7 +177,8 @@ void main() {
vec4 faceSize = getFaceSize(faceData); vec4 faceSize = getFaceSize(faceData);
vec2 cQuadSize = (faceSize.yw + quadSize - 1) * vec2((cornerIdx>>1)&1, cornerIdx&1); vec2 cQuadSize = (faceSize.yw + quadSize - 1) * vec2((cornerIdx>>1)&1, cornerIdx&1);
uv = faceSize.xz + cQuadSize;
//uv = faceSize.xz + cQuadSize;
vec3 cornerPos = extractPos(quad); vec3 cornerPos = extractPos(quad);
float depthOffset = extractFaceIndentation(faceData); float depthOffset = extractFaceIndentation(faceData);