From ca4bbcb6b756d3781519963bb7df9e76b7b6262a Mon Sep 17 00:00:00 2001 From: JellySquid Date: Sat, 18 Jan 2025 12:45:58 -0600 Subject: [PATCH] Use 8 bits of sub-texel precision and fix off-by-one error --- .../chunk/shader/DefaultShaderInterface.java | 28 +++++++------------ .../format/impl/CompactChunkVertex.java | 4 +-- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java index 5d0bda6be3..f2cb18fcb6 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java @@ -5,6 +5,7 @@ import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat3v; import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformInt; import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformMatrix4f; +import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.impl.CompactChunkVertex; import net.caffeinemc.mods.sodium.client.util.TextureUtil; import net.caffeinemc.mods.sodium.mixin.core.render.texture.TextureAtlasAccessor; import net.minecraft.client.Minecraft; @@ -20,22 +21,9 @@ */ public class DefaultShaderInterface implements ChunkShaderInterface { // Direct3D specifies at least 8 bits of sub-texel precision for texture fetches. OpenGL specifies at least - // 4 bits of sub-texel precision. Most OpenGL-capable graphics are Direct3D-capable as well, so we could + // 4 bits of sub-texel precision. Most OpenGL-capable graphics are Direct3D-capable as well, so we can // *probably* assume 8 bits of precision. - // - // However, in practice, this seems to be a complete mess. The rounding behavior for point-filtering seems to - // be defined inconsistently and depends on the shader compiler and hardware implementation. Apple's GL-on-Metal - // implementation is the worst of all of them, with a very large epsilon (1.0 / 32.0) being needed to cure - // texture seams between blocks. - // - // Unless we implemented texture filtering in the shader ourselves (i.e. using texelFetch(..)), it is unlikely - // we could avoid these issues. And that would not help much in the case of linear interpolation across - // mip layers. - // - // So in other words, this constant is the lowest common denominator we found through evaluation on the target - // hardware. It is rather pessimistic to accommodate for Apple's implementation, but does seem to reliably fix - // texture seams. - private static final int SUB_TEXEL_PRECISION_BITS = 5; + private static final int SUB_TEXEL_PRECISION_BITS = 8; private final Map uniformTextures; @@ -71,10 +59,14 @@ public void setupState() { .getTexture(TextureAtlas.LOCATION_BLOCKS); // There is a limited amount of sub-texel precision when using hardware texture sampling. The mapped texture - // area must be "shrunk" by at least one sub-texel to avoid bleed between textures in the atlas. + // area must be "shrunk" by at least one sub-texel to avoid bleed between textures in the atlas. And since we + // offset texture coordinates in the vertex format by one texel, we also need to undo that here. + double subTexelPrecision = (1 << SUB_TEXEL_PRECISION_BITS); + double subTexelOffset = 1.0f / CompactChunkVertex.TEXTURE_MAX_VALUE; + this.uniformTexCoordShrink.set( - (1.0f / textureAtlas.getWidth()) / (1 << SUB_TEXEL_PRECISION_BITS), - (1.0f / textureAtlas.getHeight()) / (1 << SUB_TEXEL_PRECISION_BITS) + (float) (subTexelOffset + ((1.0D / textureAtlas.getWidth()) / subTexelPrecision)), + (float) (subTexelOffset + ((1.0D / textureAtlas.getHeight()) / subTexelPrecision)) ); this.fogShader.setup(); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java index 44c73a8719..410dc0a5c0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java @@ -18,8 +18,8 @@ public class CompactChunkVertex implements ChunkVertexType { .addElement(DefaultChunkMeshAttributes.LIGHT_MATERIAL_INDEX, ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX, 16) .build(); - private static final int POSITION_MAX_VALUE = 1 << 20; - private static final int TEXTURE_MAX_VALUE = 1 << 15; + public static final int POSITION_MAX_VALUE = 1 << 20; + public static final int TEXTURE_MAX_VALUE = 1 << 15; private static final float MODEL_ORIGIN = 8.0f; private static final float MODEL_RANGE = 32.0f;