model metadata

This commit is contained in:
mcrcortex
2025-09-24 22:32:27 +10:00
parent ae7004f5d8
commit 474a8a7e3c
8 changed files with 73 additions and 13 deletions

View File

@@ -3,6 +3,7 @@ package me.cortex.voxy.client.core.gl;
import me.cortex.voxy.common.util.TrackedObject; import me.cortex.voxy.common.util.TrackedObject;
import static org.lwjgl.opengl.GL45C.*; import static org.lwjgl.opengl.GL45C.*;
import static org.lwjgl.opengl.GL45C.glNamedFramebufferDrawBuffers;
public class GlFramebuffer extends TrackedObject { public class GlFramebuffer extends TrackedObject {
public final int id; public final int id;
@@ -24,6 +25,11 @@ public class GlFramebuffer extends TrackedObject {
return this; return this;
} }
public GlFramebuffer setDrawBuffers(int... buffers) {
glNamedFramebufferDrawBuffers(this.id, buffers);
return this;
}
@Override @Override
public void free() { public void free() {
super.free0(); super.free0();

View File

@@ -99,7 +99,7 @@ public class GlTexture extends TrackedObject {
private long getEstimatedSize() { private long getEstimatedSize() {
this.assertAllocated(); this.assertAllocated();
long elemSize = switch (this.format) { long elemSize = switch (this.format) {
case GL_RGBA8, GL_DEPTH24_STENCIL8, GL_R32F -> 4; case GL_R32UI, GL_RGBA8, GL_DEPTH24_STENCIL8, GL_R32F -> 4;
case GL_DEPTH_COMPONENT24 -> 4;//TODO: check this is right???? case GL_DEPTH_COMPONENT24 -> 4;//TODO: check this is right????
case GL_DEPTH_COMPONENT32F -> 4; case GL_DEPTH_COMPONENT32F -> 4;
case GL_DEPTH_COMPONENT32 -> 4; case GL_DEPTH_COMPONENT32 -> 4;

View File

@@ -414,7 +414,15 @@ public class ModelFactory {
faceModelData |= ((!faceCoversFullBlock)&&blockRenderLayer != BlockRenderLayer.TRANSLUCENT)?1<<23:0;//Alpha discard override, translucency doesnt have alpha discard faceModelData |= ((!faceCoversFullBlock)&&blockRenderLayer != BlockRenderLayer.TRANSLUCENT)?1<<23:0;//Alpha discard override, translucency doesnt have alpha discard
//Bits 24,25 are tint metadata
if (colourProvider!=null) {//We have a tint
int tintState = TextureUtils.computeFaceTint(textureData[face], checkMode);
if (tintState == 2) {//Partial tint
faceModelData |= 1<<24;
} else if (tintState == 3) {//Full tint
faceModelData |= 2<<24;
}
}
MemoryUtil.memPutInt(faceUploadPtr, faceModelData); MemoryUtil.memPutInt(faceUploadPtr, faceModelData);
} }

View File

@@ -38,6 +38,37 @@ public class TextureUtils {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
//0: nothing written
//1: none tinted
//2: some tinted
//3: all tinted
public static int computeFaceTint(ColourDepthTextureData texture, int checkMode) {
boolean allTinted = true;
boolean someTinted = false;
boolean wasWriten = false;
final var colourData = texture.colour();
final var depthData = texture.depth();
for (int i = 0; i < colourData.length; i++) {
if (!wasPixelWritten(texture, checkMode, i)) {
continue;
}
if ((colourData[i]&0xFFFFFF) == 0 || (colourData[i]>>>24)==0) {//If the pixel is fully black (or translucent)
continue;
}
boolean pixelTinited = (depthData[i]&(1<<7))!=0;
wasWriten |= true;
allTinted &= pixelTinited;
someTinted |= pixelTinited;
}
if (!wasWriten) {
return 0;
}
return someTinted?(allTinted?3:2):1;
}
public static final int DEPTH_MODE_AVG = 1; public static final int DEPTH_MODE_AVG = 1;
public static final int DEPTH_MODE_MAX = 2; public static final int DEPTH_MODE_MAX = 2;
public static final int DEPTH_MODE_MIN = 3; public static final int DEPTH_MODE_MIN = 3;

View File

@@ -7,8 +7,7 @@ import me.cortex.voxy.client.core.gl.shader.ShaderType;
import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; import static org.lwjgl.opengl.ARBDirectStateAccess.*;
import static org.lwjgl.opengl.ARBDirectStateAccess.nglClearNamedFramebufferfv;
import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_FRAMEBUFFER_BARRIER_BIT; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_FRAMEBUFFER_BARRIER_BIT;
import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_PIXEL_BUFFER_BARRIER_BIT; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_PIXEL_BUFFER_BARRIER_BIT;
import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
@@ -25,12 +24,14 @@ public class GlViewCapture {
private final GlTexture colourTex; private final GlTexture colourTex;
private final GlTexture depthTex; private final GlTexture depthTex;
private final GlTexture stencilTex; private final GlTexture stencilTex;
private final GlTexture metaTex;
final GlFramebuffer framebuffer; final GlFramebuffer framebuffer;
private final Shader copyOutShader; private final Shader copyOutShader;
public GlViewCapture(int width, int height) { public GlViewCapture(int width, int height) {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.metaTex = new GlTexture().store(GL_R32UI, 1, width*3, height*2).name("ModelBakeryMetadata");
this.colourTex = new GlTexture().store(GL_RGBA8, 1, width*3, height*2).name("ModelBakeryColour"); this.colourTex = new GlTexture().store(GL_RGBA8, 1, width*3, height*2).name("ModelBakeryColour");
this.depthTex = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width*3, height*2).name("ModelBakeryDepth"); this.depthTex = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width*3, height*2).name("ModelBakeryDepth");
//TODO: FIXME: Mesa is broken when trying to read from a sampler of GL_STENCIL_INDEX //TODO: FIXME: Mesa is broken when trying to read from a sampler of GL_STENCIL_INDEX
@@ -39,22 +40,27 @@ public class GlViewCapture {
this.stencilTex = this.depthTex.createView(); this.stencilTex = this.depthTex.createView();
glTextureParameteri(this.depthTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); glTextureParameteri(this.depthTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
this.framebuffer = new GlFramebuffer().bind(GL_COLOR_ATTACHMENT0, this.colourTex).bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthTex).verify().name("ModelFramebuffer"); this.framebuffer = new GlFramebuffer().bind(GL_COLOR_ATTACHMENT0, this.colourTex).bind(GL_COLOR_ATTACHMENT1, this.metaTex).setDrawBuffers(GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1).bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthTex).verify().name("ModelFramebuffer");
glTextureParameteri(this.stencilTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); glTextureParameteri(this.stencilTex.id, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(this.stencilTex.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameteri(this.metaTex.id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(this.metaTex.id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
this.copyOutShader = Shader.makeAuto() this.copyOutShader = Shader.makeAuto()
.define("WIDTH", width) .define("WIDTH", width)
.define("HEIGHT", height) .define("HEIGHT", height)
.define("COLOUR_IN_BINDING", 0) .define("COLOUR_IN_BINDING", 0)
.define("DEPTH_IN_BINDING", 1) .define("DEPTH_IN_BINDING", 1)
.define("STENCIL_IN_BINDING", 2) .define("STENCIL_IN_BINDING", 2)
.define("BUFFER_OUT_BINDING", 3) .define("META_IN_BINDING", 3)
.define("BUFFER_OUT_BINDING", 4)
.add(ShaderType.COMPUTE, "voxy:bakery/bufferreorder.comp") .add(ShaderType.COMPUTE, "voxy:bakery/bufferreorder.comp")
.compile() .compile()
.name("ModelBakeryOut") .name("ModelBakeryOut")
.texture("META_IN_BINDING", 0, this.metaTex)
.texture("COLOUR_IN_BINDING", 0, this.colourTex) .texture("COLOUR_IN_BINDING", 0, this.colourTex)
.texture("DEPTH_IN_BINDING", 0, this.depthTex) .texture("DEPTH_IN_BINDING", 0, this.depthTex)
.texture("STENCIL_IN_BINDING", 0, this.stencilTex); .texture("STENCIL_IN_BINDING", 0, this.stencilTex);
@@ -62,10 +68,10 @@ public class GlViewCapture {
public void emitToStream(int buffer, int offset) { public void emitToStream(int buffer, int offset) {
this.copyOutShader.bind(); this.copyOutShader.bind();
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, buffer, offset, (this.width*3L)*(this.height*2L)*4L*2);//its 2*4 because colour + depth stencil glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 4, buffer, offset, (this.width*3L)*(this.height*2L)*4L*2);//its 2*4 because colour + depth stencil
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_UPDATE_BARRIER_BIT|GL_PIXEL_BUFFER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);//Am not sure if barriers are right glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_UPDATE_BARRIER_BIT|GL_PIXEL_BUFFER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);//Am not sure if barriers are right
glDispatchCompute(3, 2, 1); glDispatchCompute(3, 2, 1);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, 0, 0, 4);//WHY DOES THIS FIX FUCKING BINDING ISSUES HERE WHEN DOING THIS IN THE RENDER SYSTEM DOESNT glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 4, 0, 0, 4);//WHY DOES THIS FIX FUCKING BINDING ISSUES HERE WHEN DOING THIS IN THE RENDER SYSTEM DOESNT
} }
public void clear() { public void clear() {
@@ -74,6 +80,9 @@ public class GlViewCapture {
MemoryUtil.memPutLong(ptr, 0); MemoryUtil.memPutLong(ptr, 0);
MemoryUtil.memPutLong(ptr+8, 0); MemoryUtil.memPutLong(ptr+8, 0);
nglClearNamedFramebufferfv(this.framebuffer.id, GL_COLOR, 0, ptr); nglClearNamedFramebufferfv(this.framebuffer.id, GL_COLOR, 0, ptr);
nglClearNamedFramebufferuiv(this.framebuffer.id, GL_COLOR, 1, ptr);
//TODO: fix the draw buffer thing maybe? it might need todo multiple clears
//nglClearNamedFramebufferfv(this.framebuffer.id, GL_COLOR, 0, ptr);
} }
glClearNamedFramebufferfi(this.framebuffer.id, GL_DEPTH_STENCIL, 0, 1.0f, 0); glClearNamedFramebufferfi(this.framebuffer.id, GL_DEPTH_STENCIL, 0, 1.0f, 0);
} }
@@ -83,6 +92,7 @@ public class GlViewCapture {
this.colourTex.free(); this.colourTex.free();
this.stencilTex.free(); this.stencilTex.free();
this.depthTex.free(); this.depthTex.free();
this.metaTex.free();
this.copyOutShader.free(); this.copyOutShader.free();
} }
} }

View File

@@ -71,9 +71,7 @@ public class ModelTextureBakery {
for (var part : model.getParts(new LocalRandom(42L))) { for (var part : model.getParts(new LocalRandom(42L))) {
var quads = part.getQuads(direction); var quads = part.getQuads(direction);
for (var quad : quads) { for (var quad : quads) {
//TODO: add meta specifiying quad has a tint this.vc.quad(quad, meta|(quad.hasTint()?4:0));
//quad.hasTint()
this.vc.quad(quad, meta);
} }
} }
} }
@@ -81,6 +79,7 @@ public class ModelTextureBakery {
private void bakeFluidState(BlockState state, BlockRenderLayer layer, int face) { private void bakeFluidState(BlockState state, BlockRenderLayer layer, int face) {
//TODO: somehow set the tint flag aswell
this.vc.setDefaultMeta(getMetaFromLayer(layer));//Set the meta while baking this.vc.setDefaultMeta(getMetaFromLayer(layer));//Set the meta while baking
MinecraftClient.getInstance().getBlockRenderManager().renderFluid(BlockPos.ORIGIN, new BlockRenderView() { MinecraftClient.getInstance().getBlockRenderManager().renderFluid(BlockPos.ORIGIN, new BlockRenderView() {
@Override @Override

View File

@@ -2,6 +2,7 @@
layout(local_size_x = WIDTH, local_size_y = HEIGHT) in; layout(local_size_x = WIDTH, local_size_y = HEIGHT) in;
layout(binding = META_IN_BINDING) uniform usampler2D metaTexIn;
layout(binding = COLOUR_IN_BINDING) uniform sampler2D colourTexIn; layout(binding = COLOUR_IN_BINDING) uniform sampler2D colourTexIn;
layout(binding = DEPTH_IN_BINDING) uniform sampler2D depthTexIn; layout(binding = DEPTH_IN_BINDING) uniform sampler2D depthTexIn;
layout(binding = STENCIL_IN_BINDING) uniform usampler2D stencilTexIn; layout(binding = STENCIL_IN_BINDING) uniform usampler2D stencilTexIn;
@@ -24,8 +25,11 @@ void main() {
float depth = clamp(texelFetch(depthTexIn, samplePoint, 0).r, 0, 1);//Opengl grumble grumble float depth = clamp(texelFetch(depthTexIn, samplePoint, 0).r, 0, 1);//Opengl grumble grumble
uint stencil = texelFetch(stencilTexIn, samplePoint, 0).r; uint stencil = texelFetch(stencilTexIn, samplePoint, 0).r;
uint metadata = texelFetch(metaTexIn, samplePoint, 0).r;
uint value = uint(depth*((1<<24)-1))<<8; uint value = uint(depth*((1<<24)-1))<<8;
value |= stencil; value |= stencil&0xFFu;
//Use the very top bit of the stencil to mask if its tinted
value |= (metadata&1u)<<7;
outPoint.y = value; outPoint.y = value;
outBuffer[globalOutIndex] = outPoint; outBuffer[globalOutIndex] = outPoint;

View File

@@ -3,11 +3,13 @@
layout(location=0) uniform sampler2D tex; layout(location=0) uniform sampler2D tex;
in vec2 texCoord; in vec2 texCoord;
in flat uint metadata; in flat uint metadata;
out vec4 colour; layout(location=0) out vec4 colour;
layout(location=1) out uvec4 metaOut;
void main() { void main() {
colour = texture(tex, texCoord, ((~metadata>>1)&1u)*-16.0f); colour = texture(tex, texCoord, ((~metadata>>1)&1u)*-16.0f);
if (colour.a < 0.001f && ((metadata&1u)!=0)) { if (colour.a < 0.001f && ((metadata&1u)!=0)) {
discard; discard;
} }
metaOut = uvec4((metadata>>2)&1u);//Write if it is or isnt tinted
} }