From c7cf4a74d588569fdeffea9fa592e3d4fb47c3f0 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sun, 14 Dec 2025 23:44:46 +1000 Subject: [PATCH] mipping --- .../me/cortex/voxy/client/VoxyClient.java | 2 +- .../voxy/client/core/VoxyRenderSystem.java | 2 +- .../cortex/voxy/client/core/model/MipGen.java | 128 +++++++++++++++++ .../voxy/client/core/model/ModelFactory.java | 84 ++++------- .../voxy/client/core/model/TextureUtils.java | 134 +++++++----------- .../core/model/bakery/ModelTextureBakery.java | 7 +- .../model/bakery/ReuseVertexConsumer.java | 4 + .../assets/voxy/shaders/lod/gl46/quads.frag | 1 + src/main/resources/voxy.accesswidener | 2 + 9 files changed, 221 insertions(+), 143 deletions(-) create mode 100644 src/main/java/me/cortex/voxy/client/core/model/MipGen.java diff --git a/src/main/java/me/cortex/voxy/client/VoxyClient.java b/src/main/java/me/cortex/voxy/client/VoxyClient.java index 4ea6e8d7..e91934fb 100644 --- a/src/main/java/me/cortex/voxy/client/VoxyClient.java +++ b/src/main/java/me/cortex/voxy/client/VoxyClient.java @@ -64,6 +64,6 @@ public class VoxyClient implements ClientModInitializer { } public static boolean disableSodiumChunkRender() { - return getOcclusionDebugState() != 0; + return false;// getOcclusionDebugState() != 0; } } \ No newline at end of file diff --git a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java index c1a8b16e..970c47e2 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java @@ -376,7 +376,7 @@ public class VoxyRenderSystem { return base.mulLocal( makeProjectionMatrix(0.05f, Minecraft.getInstance().gameRenderer.getDepthFar()).invert(), new Matrix4f() - ).mulLocal(makeProjectionMatrix(VoxyClient.getOcclusionDebugState()<=1?16f:0.1f, 16*3000)); + ).mulLocal(makeProjectionMatrix(VoxyClient.disableSodiumChunkRender()?0.1f:16f, 16*3000)); } private boolean frexStillHasWork() { diff --git a/src/main/java/me/cortex/voxy/client/core/model/MipGen.java b/src/main/java/me/cortex/voxy/client/core/model/MipGen.java new file mode 100644 index 00000000..3439c06d --- /dev/null +++ b/src/main/java/me/cortex/voxy/client/core/model/MipGen.java @@ -0,0 +1,128 @@ +package me.cortex.voxy.client.core.model; + +import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue; +import me.cortex.voxy.common.util.MemoryBuffer; +import net.caffeinemc.mods.sodium.client.util.color.ColorSRGB; +import org.lwjgl.system.MemoryUtil; + +import java.util.Arrays; + +import static me.cortex.voxy.client.core.model.ModelFactory.LAYERS; +import static me.cortex.voxy.client.core.model.ModelFactory.MODEL_TEXTURE_SIZE; + +public class MipGen { + static { + if (MODEL_TEXTURE_SIZE>16) throw new IllegalStateException("TODO: THIS MUST BE UPDATED, IT CURRENTLY ASSUMES 16 OR SMALLER SIZE"); + } + private static final short[] SCRATCH = new short[MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE]; + private static final ByteArrayFIFOQueue QUEUE = new ByteArrayFIFOQueue(MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE); + + private static long getOffset(int bx, int by, int i) { + bx += i&(MODEL_TEXTURE_SIZE-1); + by += i/MODEL_TEXTURE_SIZE; + return bx+by*MODEL_TEXTURE_SIZE*3; + } + + private static void solidify(long baseAddr, byte msk) { + for (int idx = 0; idx < 6; idx++) { + if (((msk>>idx)&1)==0) continue; + int bx = (idx>>1)*MODEL_TEXTURE_SIZE; + int by = (idx&1)*MODEL_TEXTURE_SIZE; + long cAddr = baseAddr + (long)(bx+by*MODEL_TEXTURE_SIZE*3)*4; + Arrays.fill(SCRATCH, (short) -1); + for (int y = 0; y=MODEL_TEXTURE_SIZE||y2<0||y2>=MODEL_TEXTURE_SIZE) continue; + int pos2 = x2+y2*MODEL_TEXTURE_SIZE; + if ((newVal&0xFF00)<(SCRATCH[pos2]&0xFF00)) { + SCRATCH[pos2] = newVal; + QUEUE.enqueue((byte) pos2); + } + } + } + + for (int i = 0; i < MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE; i++) { + int d = Short.toUnsignedInt(SCRATCH[i]); + if ((d&0xFF00)!=0) { + int c = MemoryUtil.memGetInt(baseAddr+getOffset(bx, by, d&0xFF)*4)&0x00FFFFFF; + MemoryUtil.memPutInt(baseAddr+getOffset(bx, by, i)*4, c); + } + } + } + } + + public static void putTextures(boolean darkened, ColourDepthTextureData[] textures, MemoryBuffer into) { + //if (MODEL_TEXTURE_SIZE != 16) {throw new IllegalStateException("THIS METHOD MUST BE REDONE IF THIS CONST CHANGES");} + + //TODO: need to use a write mask to see what pixels must be used to contribute to mipping + // as in, using the depth/stencil info, check if pixel was written to, if so, use that pixel when blending, else dont + + final long addr = into.address; + final int LENGTH_B = MODEL_TEXTURE_SIZE*3; + byte solidMsk = 0; + for (int i = 0; i < 6; i++) { + int x = (i>>1)*MODEL_TEXTURE_SIZE; + int y = (i&1)*MODEL_TEXTURE_SIZE; + int j = 0; + boolean anyTransparent = false; + for (int t : textures[i].colour()) { + int o = ((y+(j>>LAYERS))*LENGTH_B + ((j&(MODEL_TEXTURE_SIZE-1))+x))*4; j++;//LAYERS here is just cause faster + //t = ((t&0xFF000000)==0)?0x00_FF_00_FF:t;//great for testing + MemoryUtil.memPutInt(addr+o, t); + anyTransparent |= ((t&0xFF000000)==0); + } + solidMsk |= (anyTransparent?1:0)<>(i<<1);//is.. i*2 because shrink both MODEL_TEXTURE_SIZE by >>i so is 2*i total shift + int width = (MODEL_TEXTURE_SIZE*3)>>(i+1); + int sWidth = (MODEL_TEXTURE_SIZE*3)>>i; + int height = (MODEL_TEXTURE_SIZE*2)>>(i+1); + //TODO: OPTIMZIE THIS + for (int px = 0; px < width; px++) { + for (int py = 0; py < height; py++) { + long bp = sAddr + (px*2 + py*2*sWidth)*4; + int C00 = MemoryUtil.memGetInt(bp); + int C01 = MemoryUtil.memGetInt(bp+sWidth*4); + int C10 = MemoryUtil.memGetInt(bp+4); + int C11 = MemoryUtil.memGetInt(bp+sWidth*4+4); + MemoryUtil.memPutInt(dAddr + (px+py*width) * 4L, TextureUtils.mipColours(darkened, C00, C01, C10, C11)); + } + } + } + + /* + */ + } + + public static void generateMipmaps(long[] textures, int size) { + + } +} diff --git a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java index 162348b0..5004b4b9 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java +++ b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java @@ -63,6 +63,7 @@ import static org.lwjgl.opengl.GL11.*; // this _quarters_ the memory requirements for the texture atlas!!! WHICH IS HUGE saving public class ModelFactory { public static final int MODEL_TEXTURE_SIZE = 16; + public static final int LAYERS = Integer.numberOfTrailingZeros(MODEL_TEXTURE_SIZE); //TODO: replace the fluid BlockState with a client model id integer of the fluidState, requires looking up // the fluid state in the mipper @@ -158,6 +159,7 @@ public class ModelFactory { private final MemoryBuffer rawData; public boolean isShaded; + public boolean hasDarkenedTextures; public RawBakeResult(int blockId, BlockState blockState, MemoryBuffer rawData) { this.blockId = blockId; @@ -219,7 +221,9 @@ public class ModelFactory { RawBakeResult result = new RawBakeResult(blockId, blockState); int allocation = this.downstream.download(MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE*2*4*6, ptr -> this.rawBakeResults.add(result.cpyBuf(ptr))); - result.isShaded = this.bakery.renderToStream(blockState, this.downstream.getBufferId(), allocation); + int flags = this.bakery.renderToStream(blockState, this.downstream.getBufferId(), allocation); + result.hasDarkenedTextures = (flags&2)!=0; + result.isShaded = (flags&1)!=0; return true; } @@ -245,7 +249,7 @@ public class ModelFactory { } } result.rawData.free(); - var bakeResult = this.processTextureBakeResult(result.blockId, result.blockState, textureData, result.isShaded); + var bakeResult = this.processTextureBakeResult(result.blockId, result.blockState, textureData, result.isShaded, result.hasDarkenedTextures); if (bakeResult!=null) { this.uploadResults.add(bakeResult); } @@ -337,7 +341,7 @@ public class ModelFactory { } } - private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState blockState, ColourDepthTextureData[] textureData, boolean isShaded) { + private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState blockState, ColourDepthTextureData[] textureData, boolean isShaded, boolean darkenedTinting) { if (this.idMappings[blockId] != -1) { //This should be impossible to reach as it means that multiple bakes for the same blockId happened and where inflight at the same time! throw new IllegalStateException("Block id already added: " + blockId + " for state: " + blockState); @@ -636,7 +640,7 @@ public class ModelFactory { //TODO callback to inject extra data into the model data - this.putTextures(textureData, uploadResult.texture); + MipGen.putTextures(darkenedTinting, textureData, uploadResult.texture); //glGenerateTextureMipmap(this.textures.id); @@ -734,7 +738,7 @@ public class ModelFactory { // if it is, need to add it to a list and mark it as biome colour dependent or something then the shader // will either use the uint as an index or a direct colour multiplier private static int captureColourConstant(BlockColor colorProvider, BlockState state, Biome biome) { - return colorProvider.getColor(state, new BlockAndTintGetter() { + var getter = new BlockAndTintGetter() { @Override public float getShade(Direction direction, boolean shaded) { return 0; @@ -780,12 +784,16 @@ public class ModelFactory { public int getMinY() { return 0; } - }, BlockPos.ZERO, 0); + }; + //Multiple layer bs to do with flower beds + int c = colorProvider.getColor(state, getter, BlockPos.ZERO, 0); + if (c!=-1) return c; + return colorProvider.getColor(state, getter, BlockPos.ZERO, 1); } private static boolean isBiomeDependentColour(BlockColor colorProvider, BlockState state) { boolean[] biomeDependent = new boolean[1]; - colorProvider.getColor(state, new BlockAndTintGetter() { + var getter = new BlockAndTintGetter() { @Override public float getShade(Direction direction, boolean shaded) { return 0; @@ -832,7 +840,9 @@ public class ModelFactory { public int getMinY() { return 0; } - }, BlockPos.ZERO, 0); + }; + colorProvider.getColor(state, getter, BlockPos.ZERO, 0); + colorProvider.getColor(state, getter, BlockPos.ZERO, 1); return biomeDependent[0]; } @@ -881,57 +891,6 @@ public class ModelFactory { } - private static int computeSizeWithMips(int size) { - int total = 0; - for (;size!=0;size>>=1) total += size*size; - return total; - } - private static final MemoryBuffer SCRATCH_TEX = new MemoryBuffer((2L*3*computeSizeWithMips(MODEL_TEXTURE_SIZE))*4); - private static final int LAYERS = Integer.numberOfTrailingZeros(MODEL_TEXTURE_SIZE); - //TODO: redo to batch blit, instead of 6 seperate blits, and also fix mipping - private void putTextures(ColourDepthTextureData[] textures, MemoryBuffer into) { - //if (MODEL_TEXTURE_SIZE != 16) {throw new IllegalStateException("THIS METHOD MUST BE REDONE IF THIS CONST CHANGES");} - - //TODO: need to use a write mask to see what pixels must be used to contribute to mipping - // as in, using the depth/stencil info, check if pixel was written to, if so, use that pixel when blending, else dont - - final long addr = into.address; - final int LENGTH_B = MODEL_TEXTURE_SIZE*3; - for (int i = 0; i < 6; i++) { - int x = (i>>1)*MODEL_TEXTURE_SIZE; - int y = (i&1)*MODEL_TEXTURE_SIZE; - int j = 0; - for (int t : textures[i].colour()) { - int o = ((y+(j>>LAYERS))*LENGTH_B + ((j&(MODEL_TEXTURE_SIZE-1))+x))*4; j++;//LAYERS here is just cause faster - MemoryUtil.memPutInt(addr+o, t); - } - } - - //Mip the scratch - long dAddr = addr; - for (int i = 0; i < LAYERS-1; i++) { - long sAddr = dAddr; - dAddr += (MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE*3*2*4)>>(i<<1);//is.. i*2 because shrink both MODEL_TEXTURE_SIZE by >>i so is 2*i total shift - int width = (MODEL_TEXTURE_SIZE*3)>>(i+1); - int sWidth = (MODEL_TEXTURE_SIZE*3)>>i; - int height = (MODEL_TEXTURE_SIZE*2)>>(i+1); - //TODO: OPTIMZIE THIS - for (int px = 0; px < width; px++) { - for (int py = 0; py < height; py++) { - long bp = sAddr + (px*2 + py*2*sWidth)*4; - int C00 = MemoryUtil.memGetInt(bp); - int C01 = MemoryUtil.memGetInt(bp+sWidth*4); - int C10 = MemoryUtil.memGetInt(bp+4); - int C11 = MemoryUtil.memGetInt(bp+sWidth*4+4); - MemoryUtil.memPutInt(dAddr + (px+py*width) * 4L, TextureUtils.mipColours(C00, C01, C10, C11)); - } - } - } - - /* - */ - } - public void free() { this.bakery.free(); this.downstream.free(); @@ -954,4 +913,11 @@ public class ModelFactory { size += this.biomeQueue.size(); return size; } + + + private static int computeSizeWithMips(int size) { + int total = 0; + for (;size!=0;size>>=1) total += size*size; + return total; + } } diff --git a/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java b/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java index af56bca4..ae11aad0 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java +++ b/src/main/java/me/cortex/voxy/client/core/model/TextureUtils.java @@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.model; import net.caffeinemc.mods.sodium.client.util.color.ColorSRGB; import net.minecraft.client.renderer.texture.MipmapGenerator; +import net.minecraft.util.ARGB; //Texturing utils to manipulate data from the model bakery public class TextureUtils { @@ -9,14 +10,14 @@ public class TextureUtils { public static int getWrittenPixelCount(ColourDepthTextureData texture, int checkMode) { int count = 0; for (int i = 0; i < texture.colour().length; i++) { - count += wasPixelWritten(texture, checkMode, i)?1:0; + count += wasPixelWritten(texture, checkMode, i) ? 1 : 0; } return count; } public static boolean isSolid(ColourDepthTextureData texture) { for (int pixel : texture.colour()) { - if (((pixel>>24)&0xFF) != 255) { + if (((pixel >> 24) & 0xFF) != 255) { return false; } } @@ -26,14 +27,15 @@ public class TextureUtils { public static final int WRITE_CHECK_STENCIL = 1; public static final int WRITE_CHECK_DEPTH = 2; public static final int WRITE_CHECK_ALPHA = 3; + private static boolean wasPixelWritten(ColourDepthTextureData data, int mode, int index) { if (mode == WRITE_CHECK_STENCIL) { - return (data.depth()[index]&0xFF)!=0; + return (data.depth()[index] & 0xFF) != 0; } else if (mode == WRITE_CHECK_DEPTH) { - return (data.depth()[index]>>>8)!=((1<<24)-1); + return (data.depth()[index] >>> 8) != ((1 << 24) - 1); } else if (mode == WRITE_CHECK_ALPHA) { //TODO:FIXME: for some reason it has an alpha of 1 even if its ment to be 0 - return ((data.colour()[index]>>>24)&0xff)>1; + return ((data.colour()[index] >>> 24) & 0xff) > 1; } throw new IllegalArgumentException(); } @@ -54,10 +56,10 @@ public class TextureUtils { if (!wasPixelWritten(texture, checkMode, i)) { continue; } - if ((colourData[i]&0xFFFFFF) == 0 || (colourData[i]>>>24)==0) {//If the pixel is fully black (or translucent) + 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; + boolean pixelTinited = (depthData[i] & (1 << 7)) != 0; wasWriten |= true; allTinted &= pixelTinited; someTinted |= pixelTinited; @@ -66,7 +68,7 @@ public class TextureUtils { if (!wasWriten) { return 0; } - return someTinted?(allTinted?3:2):1; + return someTinted ? (allTinted ? 3 : 2) : 1; } public static final int DEPTH_MODE_AVG = 1; @@ -90,7 +92,7 @@ public class TextureUtils { if (!wasPixelWritten(texture, checkMode, i)) { continue; } - int depth = depthData[i]>>>8; + int depth = depthData[i] >>> 8; if (mode == DEPTH_MODE_AVG) { a++; b += depth; @@ -105,7 +107,7 @@ public class TextureUtils { if (a == 0) { return -1; } - return u2fdepth((int) (b/a)); + return u2fdepth((int) (b / a)); } else if (mode == DEPTH_MODE_MAX) { if (a == Long.MIN_VALUE) { return -1; @@ -121,7 +123,7 @@ public class TextureUtils { } private static float u2fdepth(int depth) { - float depthF = (float) ((double)depth/((1<<24)-1)); + float depthF = (float) ((double) depth / ((1 << 24) - 1)); //https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml // due to this and the unsigned bullshit, believe the depth value needs to get multiplied by 2 @@ -150,10 +152,10 @@ public class TextureUtils { minX++; } while (minX != data.width()); - int maxX = data.width()-1; + int maxX = data.width() - 1; maxXCheck: do { - for (int y = data.height()-1; y!=-1; y--) { + for (int y = data.height() - 1; y != -1; y--) { int idx = maxX + (y * data.width()); if (wasPixelWritten(data, checkMode, idx)) { break maxXCheck;//pixel was written too so break from loop @@ -178,10 +180,10 @@ public class TextureUtils { } while (minY != data.height()); - int maxY = data.height()-1; + int maxY = data.height() - 1; maxYCheck: do { - for (int x = data.width()-1; x!=-1; x--) { + for (int x = data.width() - 1; x != -1; x--) { int idx = (maxY * data.height()) + x; if (wasPixelWritten(data, checkMode, idx)) { break maxYCheck;//pixel was written too so break from loop @@ -195,70 +197,42 @@ public class TextureUtils { } - - - - - - - - - - - - - public static int mipColours(int one, int two, int three, int four) { - if (false) { - return 0; - //return MipmapGenerator.alphaBlend(one, two, three, four, false); - } else { - return weightedAverageColor(weightedAverageColor(one, two), weightedAverageColor(three, four)); + public static int mipColours(boolean darkend, int C00, int C01, int C10, int C11) { + darkend = !darkend;//Invert to make it easier + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; + float a = 0.0f; + if (darkend || (C00 >>> 24) != 0) { + r += ColorSRGB.srgbToLinear((C00 >> 0) & 0xFF); + g += ColorSRGB.srgbToLinear((C00 >> 8) & 0xFF); + b += ColorSRGB.srgbToLinear((C00 >> 16) & 0xFF); + a += darkend ? (C00 >>> 24) : ColorSRGB.srgbToLinear(C00 >>> 24); } + if (darkend || (C01 >>> 24) != 0) { + r += ColorSRGB.srgbToLinear((C01 >> 0) & 0xFF); + g += ColorSRGB.srgbToLinear((C01 >> 8) & 0xFF); + b += ColorSRGB.srgbToLinear((C01 >> 16) & 0xFF); + a += darkend ? (C01 >>> 24) : ColorSRGB.srgbToLinear(C01 >>> 24); + } + if (darkend || (C10 >>> 24) != 0) { + r += ColorSRGB.srgbToLinear((C10 >> 0) & 0xFF); + g += ColorSRGB.srgbToLinear((C10 >> 8) & 0xFF); + b += ColorSRGB.srgbToLinear((C10 >> 16) & 0xFF); + a += darkend ? (C10 >>> 24) : ColorSRGB.srgbToLinear(C10 >>> 24); + } + if (darkend || (C11 >>> 24) != 0) { + r += ColorSRGB.srgbToLinear((C11 >> 0) & 0xFF); + g += ColorSRGB.srgbToLinear((C11 >> 8) & 0xFF); + b += ColorSRGB.srgbToLinear((C11 >> 16) & 0xFF); + a += darkend ? (C11 >>> 24) : ColorSRGB.srgbToLinear(C11 >>> 24); + } + + return ColorSRGB.linearToSrgb( + r / 4, + g / 4, + b / 4, + darkend ? ((int) a) / 4 : ARGB.linearToSrgbChannel(a / 4) + ); } - - //TODO: FIXME!!! ITS READING IT AS ABGR??? isnt the format RGBA?? - private static int weightedAverageColor(int a, int b) { - //We specifically want the entire other component if the alpha is zero - // this prevents black mips from generating due to A) non filled colours, and B) when the sampler samples everything it doesnt detonate - if ((a&0xFF000000) == 0) { - //return (b&0x00FFFFFF)|((b>>>2)&0x3FC00000); - return b; - } - if ((b&0xFF000000) == 0) { - //return (a&0x00FFFFFF)|((a>>>2)&0x3FC00000); - return a; - } - - if (((a^b)&0xFF000000)==0) { - return ColorSRGB.linearToSrgb( - addHalfLinear(0, a,b), - addHalfLinear(8, a,b), - addHalfLinear(16, a,b), - a>>>24); - } - - - - - - { - int A = (a>>>24); - int B = (a>>>24); - float mul = 1.0F / (float)(A+B); - float wA = A * mul; - float wB = B * mul; - return ColorSRGB.linearToSrgb( - addMulLinear(0, a,b,wA,wB), - addMulLinear(8, a,b,wA,wB), - addMulLinear(16, a,b,wA,wB) - , (A + B)/2); - } - } - - private static float addHalfLinear(int shift, int a, int b) { - return addMulLinear(shift, a, b, 0.5f, 0.5f); - } - private static float addMulLinear(int shift, int a, int b, float mulA, float mulB) { - return Math.fma(ColorSRGB.srgbToLinear((a>>shift)&0xFF),mulA, ColorSRGB.srgbToLinear((b>>shift)&0xFF)*mulB); - } -} +} \ No newline at end of file diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java index 74df9b9a..627e32cc 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java @@ -170,7 +170,7 @@ public class ModelTextureBakery { } - public boolean renderToStream(BlockState state, int streamBuffer, int streamOffset) { + public int renderToStream(BlockState state, int streamBuffer, int streamOffset) { this.capture.clear(); boolean isBlock = true; ChunkSectionLayer layer; @@ -221,10 +221,12 @@ public class ModelTextureBakery { } boolean isAnyShaded = false; + boolean isAnyDarkend = false; if (isBlock) { this.vc.reset(); this.bakeBlockModel(state, layer); isAnyShaded |= this.vc.anyShaded; + isAnyDarkend |= this.vc.anyDarkendTex; if (!this.vc.isEmpty()) {//only render if there... is shit to render //Setup for continual emission @@ -267,6 +269,7 @@ public class ModelTextureBakery { this.bakeFluidState(state, layer, i); if (this.vc.isEmpty()) continue; isAnyShaded |= this.vc.anyShaded; + isAnyDarkend |= this.vc.anyDarkendTex; BudgetBufferRenderer.setup(this.vc.getAddress(), this.vc.quadCount(), blockTextureId); glViewport((i % 3) * this.width, (i / 3) * this.height, this.width, this.height); @@ -331,7 +334,7 @@ public class ModelTextureBakery { GL14.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } - return isAnyShaded; + return (isAnyShaded?1:0)|(isAnyDarkend?2:0); } diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/ReuseVertexConsumer.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/ReuseVertexConsumer.java index c0a18e72..487de35b 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/bakery/ReuseVertexConsumer.java +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/ReuseVertexConsumer.java @@ -4,6 +4,7 @@ package me.cortex.voxy.client.core.model.bakery; import me.cortex.voxy.common.util.MemoryBuffer; import net.minecraft.client.model.geom.builders.UVPair; import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.MipmapStrategy; import org.lwjgl.system.MemoryUtil; import static me.cortex.voxy.client.core.model.bakery.BudgetBufferRenderer.VERTEX_FORMAT_SIZE; @@ -17,6 +18,7 @@ public final class ReuseVertexConsumer implements VertexConsumer { private int defaultMeta; public boolean anyShaded; + public boolean anyDarkendTex; public ReuseVertexConsumer() { this.reset(); @@ -82,6 +84,7 @@ public final class ReuseVertexConsumer implements VertexConsumer { public ReuseVertexConsumer quad(BakedQuad quad, int metadata) { this.anyShaded |= quad.shade(); + this.anyDarkendTex |= quad.sprite().contents().mipmapStrategy == MipmapStrategy.DARK_CUTOUT; this.ensureCanPut(); for (int i = 0; i < 4; i++) { var pos = quad.position(i); @@ -109,6 +112,7 @@ public final class ReuseVertexConsumer implements VertexConsumer { public ReuseVertexConsumer reset() { this.anyShaded = false; + this.anyDarkendTex = false; this.defaultMeta = 0;//RESET THE DEFAULT META this.count = 0; this.ptr = this.buffer.address - VERTEX_FORMAT_SIZE;//the thing is first time this gets incremented by FORMAT_STRIDE diff --git a/src/main/resources/assets/voxy/shaders/lod/gl46/quads.frag b/src/main/resources/assets/voxy/shaders/lod/gl46/quads.frag index b075fc26..a8c62427 100644 --- a/src/main/resources/assets/voxy/shaders/lod/gl46/quads.frag +++ b/src/main/resources/assets/voxy/shaders/lod/gl46/quads.frag @@ -166,6 +166,7 @@ void main() { //Also, small quad is really fking over the mipping level somehow #ifndef TRANSLUCENT if (useDiscard() && (textureLod(blockModelAtlas, texPos, 0).a <= 0.1f)) { + //if (useDiscard() && (colour.a <= 0.1f)) { #else if (textureLod(blockModelAtlas, texPos, 0).a == 0.0f) { #endif diff --git a/src/main/resources/voxy.accesswidener b/src/main/resources/voxy.accesswidener index 225da5f8..2ed07919 100644 --- a/src/main/resources/voxy.accesswidener +++ b/src/main/resources/voxy.accesswidener @@ -14,6 +14,8 @@ accessible field net/minecraft/world/level/chunk/PalettedContainer data Lnet/min accessible field net/minecraft/world/level/chunk/PalettedContainer$Data palette Lnet/minecraft/world/level/chunk/Palette; accessible field net/minecraft/world/level/chunk/PalettedContainer$Data storage Lnet/minecraft/util/BitStorage; +accessible field net/minecraft/client/renderer/texture/SpriteContents mipmapStrategy Lnet/minecraft/client/renderer/texture/MipmapStrategy; + accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F accessible method net/minecraft/client/multiplayer/ClientChunkCache$Storage getChunk (I)Lnet/minecraft/world/level/chunk/LevelChunk;