Skip to content

Commit

Permalink
Adjust tex coord epsilon depending on atlas size
Browse files Browse the repository at this point in the history
This fixes some texture precision issues with very large
atlases, and with hardware that has limited sub-texel
precision.
  • Loading branch information
jellysquid3 committed Jan 18, 2025
1 parent d74e421 commit 3bc32ee
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.caffeinemc.mods.sodium.client.gl.shader.uniform;

import org.lwjgl.opengl.GL30C;

public class GlUniformFloat2v extends GlUniform<float[]> {
public GlUniformFloat2v(int index) {
super(index);
}

@Override
public void set(float[] value) {
if (value.length != 2) {
throw new IllegalArgumentException("value.length != 2");
}

GL30C.glUniform2fv(this.index, value);
}

public void set(float x, float y) {
GL30C.glUniform2f(this.index, x, y);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package net.caffeinemc.mods.sodium.client.render.chunk.shader;

import com.mojang.blaze3d.platform.GlStateManager;
import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat2v;
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.util.TextureUtil;
import net.caffeinemc.mods.sodium.mixin.core.render.texture.TextureAtlasAccessor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlas;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL32C;

Expand All @@ -20,6 +24,7 @@ public class DefaultShaderInterface implements ChunkShaderInterface {
private final GlUniformMatrix4f uniformModelViewMatrix;
private final GlUniformMatrix4f uniformProjectionMatrix;
private final GlUniformFloat3v uniformRegionOffset;
private final GlUniformFloat2v uniformTexCoordShrink;

// The fog shader component used by this program in order to setup the appropriate GL state
private final ChunkShaderFogComponent fogShader;
Expand All @@ -28,6 +33,7 @@ public DefaultShaderInterface(ShaderBindingContext context, ChunkShaderOptions o
this.uniformModelViewMatrix = context.bindUniform("u_ModelViewMatrix", GlUniformMatrix4f::new);
this.uniformProjectionMatrix = context.bindUniform("u_ProjectionMatrix", GlUniformMatrix4f::new);
this.uniformRegionOffset = context.bindUniform("u_RegionOffset", GlUniformFloat3v::new);
this.uniformTexCoordShrink = context.bindUniform("u_TexCoordShrink", GlUniformFloat2v::new);

this.uniformTextures = new EnumMap<>(ChunkShaderTextureSlot.class);
this.uniformTextures.put(ChunkShaderTextureSlot.BLOCK, context.bindUniform("u_BlockTex", GlUniformInt::new));
Expand All @@ -38,9 +44,22 @@ public DefaultShaderInterface(ShaderBindingContext context, ChunkShaderOptions o

@Override // the shader interface should not modify pipeline state
public void setupState() {
// TODO: Bind to these textures directly rather than using fragile RenderSystem state
this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId());
this.bindTexture(ChunkShaderTextureSlot.LIGHT, TextureUtil.getLightTextureId());

var textureAtlas = (TextureAtlasAccessor) Minecraft.getInstance()
.getTextureManager()
.getTexture(TextureAtlas.LOCATION_BLOCKS);

// Direct3D specifies "at least 16.8 fixed-point precision" for texture fetches. Most OpenGL-capable graphics
// cards are Direct3D-capable as well, so this would likely be a safe bet. However, mobile GPUs (and notably
// Apple's own hardware) only seems to provide 16.4 fixed-point precision.
this.uniformTexCoordShrink.set(
(1.0f / textureAtlas.getWidth()) / 32.0f,
(1.0f / textureAtlas.getHeight()) / 32.0f
);

this.fogShader.setup();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package net.caffeinemc.mods.sodium.mixin.core.render.texture;

import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

import java.util.Map;

@Mixin(TextureAtlas.class)
public interface TextureAtlasAccessor {
@Accessor
Map<ResourceLocation, TextureAtlasSprite> getTexturesByName();
int getWidth();

@Accessor
int getHeight();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ out float v_FragDistance;

uniform int u_FogShape;
uniform vec3 u_RegionOffset;
uniform vec2 u_TexCoordShrink;

uniform sampler2D u_LightTex; // The light map texture sampler

Expand Down Expand Up @@ -47,7 +48,7 @@ void main() {

// Add the light color to the vertex color, and pass the texture coordinates to the fragment shader
v_Color = _vert_color * texture(u_LightTex, _vert_tex_light_coord);
v_TexCoord = _vert_tex_diffuse_coord;
v_TexCoord = _vert_tex_diffuse_coord - (_vert_tex_diffuse_coord_bias * u_TexCoordShrink);

v_MaterialMipBias = _material_mip_bias(_material_params);
#ifdef USE_FRAGMENT_DISCARD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ vec3 _vert_position;

// The block texture coordinate of the vertex
vec2 _vert_tex_diffuse_coord;
vec2 _vert_tex_diffuse_coord_bias;

// The light texture coordinate of the vertex
vec2 _vert_tex_light_coord;
Expand All @@ -28,10 +29,6 @@ const uint TEXTURE_MAX_VALUE = TEXTURE_MAX_COORD - 1u;
const float VERTEX_SCALE = 32.0 / float(POSITION_MAX_COORD);
const float VERTEX_OFFSET = -8.0;

// The amount of inset the texture coordinates from the edges of the texture, to avoid texture bleeding
const float TEXTURE_FUZZ_AMOUNT = 1.0 / 64.0;
const float TEXTURE_GROW_FACTOR = (1.0 - TEXTURE_FUZZ_AMOUNT) / TEXTURE_MAX_COORD;

in uvec2 a_Position;
in vec4 a_Color;
in uvec2 a_TexCoord;
Expand All @@ -49,13 +46,14 @@ vec2 _get_texcoord() {
}

vec2 _get_texcoord_bias() {
return mix(vec2(-TEXTURE_GROW_FACTOR), vec2(TEXTURE_GROW_FACTOR), bvec2(a_TexCoord >> TEXTURE_BITS));
return mix(vec2(-1.0), vec2(1.0), bvec2(a_TexCoord >> TEXTURE_BITS));
}

void _vert_init() {
_vert_position = (_deinterleave_u20x3(a_Position) * VERTEX_SCALE) + VERTEX_OFFSET;
_vert_color = a_Color;
_vert_tex_diffuse_coord = _get_texcoord() + _get_texcoord_bias();
_vert_tex_diffuse_coord = _get_texcoord();
_vert_tex_diffuse_coord_bias = _get_texcoord_bias();

_vert_tex_light_coord = vec2(a_LightAndData.xy) / vec2(256.0);

Expand Down

0 comments on commit 3bc32ee

Please sign in to comment.