mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-25 20:22:22 +00:00
Fix texture filtering sampling regression (#2115)
This commit is contained in:
1 parent
b6a4497fb3
commit
ef68af5850
8 files changed
+67
-9
No files matched your search
@@ -0,0 +1,12 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import org.lwjgl.opengl.OpenGLException;
|
||||
|
||||
final class GLErrorReporter {
|
||||
|
||||
private GLErrorReporter() {}
|
||||
|
||||
static void reportError(int error) {
|
||||
throw new OpenGLException(error);
|
||||
}
|
||||
}
|
||||
@@ -5400,7 +5400,7 @@ public class GLStateManager {
|
||||
|
||||
public static void checkGLError() {
|
||||
final int error = glGetError();
|
||||
if (error != GL11.GL_NO_ERROR) throw new org.lwjgl.opengl.OpenGLException(error);
|
||||
if (error != GL11.GL_NO_ERROR) GLErrorReporter.reportError(error);
|
||||
}
|
||||
|
||||
public static String glGetString(int pname) {
|
||||
|
||||
+4
@@ -202,6 +202,10 @@ class AngelicaChunkRenderer extends DefaultChunkRenderer {
|
||||
}
|
||||
|
||||
private void bindTerrainSampler() {
|
||||
if (!SodiumGameOptions.usesTerrainTexelSnap()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int anisotropy = SodiumGameOptions.resolvedAnisotropicFiltering();
|
||||
final boolean nearest = ClientProxy.options().quality.texelSampling.isNearest();
|
||||
|
||||
|
||||
+9
-2
@@ -30,13 +30,20 @@ public class AngelicaRenderPassConfiguration {
|
||||
.vertexType(vertexType)
|
||||
.primitiveType(QuadPrimitiveType.TRIANGULATED);
|
||||
|
||||
final int mipmapLevels = SodiumGameOptions.terrainMipmapLevels();
|
||||
|
||||
if (rgssEnabled) {
|
||||
builder.extraDefine("USE_RGSS", "");
|
||||
}
|
||||
if (SodiumGameOptions.usesTerrainTexelSnap()) {
|
||||
builder.extraDefine("USE_TEXEL_SNAP", "");
|
||||
}
|
||||
if (SodiumGameOptions.effectiveTextureFilterMode().usesAnisotropy()) {
|
||||
builder.extraDefine("USE_ANISOTROPIC", "");
|
||||
builder.extraDefine("TERRAIN_GUTTER",
|
||||
SpritePadding.gutterFor(SodiumGameOptions.terrainMipmapLevels(), true) + ".0");
|
||||
builder.extraDefine("TERRAIN_GUTTER", SpritePadding.gutterFor(mipmapLevels, true) + ".0");
|
||||
}
|
||||
if (mipmapLevels <= 0) {
|
||||
builder.extraDefine("TERRAIN_NO_MIPS", "");
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -2,6 +2,7 @@ package me.jellysquid.mods.sodium.client.gui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
@@ -202,6 +203,10 @@ public class SodiumGameOptionPages {
|
||||
.setBinding((opts, value) -> opts.quality.texelSampling = value,
|
||||
opts -> opts.quality.texelSampling)
|
||||
.setImpact(OptionImpact.LOW)
|
||||
// Only this mode needs a rerender
|
||||
.setFlags(() -> textureFilterMode.getValue() == TextureFilterMode.NONE
|
||||
? EnumSet.of(OptionFlag.REQUIRES_RENDERER_RELOAD)
|
||||
: EnumSet.noneOf(OptionFlag.class))
|
||||
.build();
|
||||
|
||||
groups.add(OptionGroup.createBuilder()
|
||||
|
||||
@@ -80,6 +80,11 @@ public class SodiumGameOptions {
|
||||
return resolveFilterMode(ClientProxy.options().quality.textureFilterMode);
|
||||
}
|
||||
|
||||
public static boolean usesTerrainTexelSnap() {
|
||||
return effectiveTextureFilterMode() != TextureFilterMode.NONE
|
||||
|| !ClientProxy.options().quality.texelSampling.isNearest();
|
||||
}
|
||||
|
||||
public static TextureFilterMode resolveFilterMode(TextureFilterMode mode) {
|
||||
if (mode == null) {
|
||||
mode = TextureFilterMode.RGSS_ANISOTROPIC;
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.EnumSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
private final OptionStorage<S> storage;
|
||||
@@ -23,7 +24,7 @@ public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
private final OptionBinding<S, T> binding;
|
||||
private final Control<T> control;
|
||||
|
||||
private final EnumSet<OptionFlag> flags;
|
||||
private final Supplier<EnumSet<OptionFlag>> flags;
|
||||
|
||||
private final String name;
|
||||
private final String tooltip;
|
||||
@@ -41,7 +42,7 @@ public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
String tooltip,
|
||||
OptionBinding<S, T> binding,
|
||||
Function<OptionImpl<S, T>, Control<T>> control,
|
||||
EnumSet<OptionFlag> flags,
|
||||
Supplier<EnumSet<OptionFlag>> flags,
|
||||
OptionImpact impact,
|
||||
boolean enabled) {
|
||||
this.storage = storage;
|
||||
@@ -121,7 +122,7 @@ public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
|
||||
@Override
|
||||
public Collection<OptionFlag> getFlags() {
|
||||
return this.flags;
|
||||
return this.flags.get();
|
||||
}
|
||||
|
||||
public static <S, T> OptionImpl.Builder<S, T> createBuilder(Class<T> type, OptionStorage<S> storage) {
|
||||
@@ -136,6 +137,7 @@ public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
private Function<OptionImpl<S, T>, Control<T>> control;
|
||||
private OptionImpact impact;
|
||||
private final EnumSet<OptionFlag> flags = EnumSet.noneOf(OptionFlag.class);
|
||||
private Supplier<EnumSet<OptionFlag>> flagsSupplier = () -> this.flags;
|
||||
private boolean enabled = true;
|
||||
|
||||
private Builder(OptionStorage<S> storage) {
|
||||
@@ -202,13 +204,21 @@ public class OptionImpl<S, T> implements OptionExtended<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<S, T> setFlags(Supplier<EnumSet<OptionFlag>> flags) {
|
||||
Validate.notNull(flags, "Flags supplier must not be null");
|
||||
|
||||
this.flagsSupplier = flags;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionImpl<S, T> build() {
|
||||
Validate.notNull(this.name, "Name must be specified");
|
||||
Validate.notNull(this.tooltip, "Tooltip must be specified");
|
||||
Validate.notNull(this.binding, "Option binding must be specified");
|
||||
Validate.notNull(this.control, "Control must be specified");
|
||||
|
||||
return new OptionImpl<>(this.storage, this.name, this.tooltip, this.binding, this.control, this.flags, this.impact, this.enabled);
|
||||
return new OptionImpl<>(this.storage, this.name, this.tooltip, this.binding, this.control, this.flagsSupplier, this.impact, this.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,13 +68,18 @@ float footprintScale(vec2 du, vec2 dv, vec2 texelSize, float limitTexels) {
|
||||
#endif
|
||||
|
||||
vec4 sampleTexelSnapped(sampler2D tex, vec2 uv, vec2 texelSize, vec2 du, vec2 dv, vec2 texelsPerPixel) {
|
||||
vec2 snapped = snapToTexelCentre(uv, texelSize, texelsPerPixel);
|
||||
|
||||
#if defined(TERRAIN_NO_MIPS) && !defined(USE_ANISOTROPIC)
|
||||
return textureLod(tex, snapped, 0.0);
|
||||
#else
|
||||
float gradientScale = exp2(v_MaterialMipBias);
|
||||
#ifdef USE_ANISOTROPIC
|
||||
gradientScale *= footprintScale(du * gradientScale, dv * gradientScale, texelSize, TERRAIN_GUTTER);
|
||||
#endif
|
||||
|
||||
return textureGrad(tex, snapToTexelCentre(uv, texelSize, texelsPerPixel),
|
||||
du * gradientScale, dv * gradientScale);
|
||||
return textureGrad(tex, snapped, du * gradientScale, dv * gradientScale);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 sampleTexelSnapped(sampler2D tex, vec2 uv, vec2 texelSize) {
|
||||
@@ -132,6 +137,12 @@ vec4 sampleRGSS(sampler2D tex, vec2 uv, vec2 texelSize) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rgss += textureGrad(tex, uv + RGSS_OFFSETS[i].x * spreadU + RGSS_OFFSETS[i].y * spreadV, gradU, gradV);
|
||||
}
|
||||
#elif defined(TERRAIN_NO_MIPS)
|
||||
const float lod = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rgss += textureLod(tex, uv + RGSS_OFFSETS[i] * texelSize, lod);
|
||||
}
|
||||
#else
|
||||
float duLength = length(du / texelSize);
|
||||
float dvLength = length(dv / texelSize);
|
||||
@@ -152,12 +163,16 @@ vec4 sampleRGSS(sampler2D tex, vec2 uv, vec2 texelSize) {
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#ifdef USE_TEXEL_SNAP
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(u_BlockTex, 0));
|
||||
#ifdef USE_RGSS
|
||||
vec4 diffuseColor = sampleRGSS(u_BlockTex, v_TexCoord, texelSize);
|
||||
#else
|
||||
vec4 diffuseColor = sampleTexelSnapped(u_BlockTex, v_TexCoord, texelSize);
|
||||
#endif
|
||||
#else
|
||||
vec4 diffuseColor = texture(u_BlockTex, v_TexCoord, v_MaterialMipBias);
|
||||
#endif
|
||||
|
||||
#ifdef USE_FRAGMENT_DISCARD
|
||||
if (diffuseColor.a < v_MaterialAlphaCutoff) {
|
||||
|
||||
Reference in new issue
Block a user