Skip to content

Commit 2a7f2af

Browse files
committed
fix: fix nighttime floral reef fog instantly transitioning (+ cleanup fog logic)
1 parent 91d8330 commit 2a7f2af

4 files changed

Lines changed: 113 additions & 78 deletions

File tree

src/client/java/dev/spiritstudios/abysm/client/AbysmClient.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@
5050
import net.minecraft.world.World;
5151

5252
public class AbysmClient implements ClientModInitializer {
53-
public static float underwaterVisibilityMultiplier = 1.0F;
54-
public static float nextUnderwaterVisibilityMultiplier = 1.0F;
55-
5653

5754
@Override
5855
public void onInitializeClient() {
Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,23 @@
11
package dev.spiritstudios.abysm.client.mixin.render;
22

3-
import com.llamalad7.mixinextras.sugar.Local;
4-
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
5-
import dev.spiritstudios.abysm.client.AbysmClient;
6-
import net.minecraft.block.enums.CameraSubmersionType;
7-
import net.minecraft.client.render.Camera;
3+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import dev.spiritstudios.abysm.client.render.AbysmWaterFogModifier;
6+
import net.minecraft.client.network.ClientPlayerEntity;
87
import net.minecraft.client.render.fog.FogRenderer;
9-
import net.minecraft.client.world.ClientWorld;
10-
import net.minecraft.util.math.MathHelper;
11-
import org.joml.Vector4f;
128
import org.spongepowered.asm.mixin.Mixin;
139
import org.spongepowered.asm.mixin.injection.At;
14-
import org.spongepowered.asm.mixin.injection.Inject;
15-
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1610

1711
@Mixin(FogRenderer.class)
1812
public abstract class FogRendererMixin {
19-
@Inject(method = "getFogColor", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0))
20-
private static void reduceUnderwaterVisibility(
21-
Camera camera,
22-
float tickProgress,
23-
ClientWorld world,
24-
int viewDistance,
25-
float skyDarkness,
26-
boolean thick,
27-
CallbackInfoReturnable<Vector4f> cir,
28-
@Local(ordinal = 7) LocalFloatRef underwaterVisibilityRef
13+
14+
@WrapOperation(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getUnderwaterVisibility()F"))
15+
private float adjustUnderwaterVisibility(
16+
ClientPlayerEntity instance, Operation<Float> original
2917
) {
30-
if (camera.getSubmersionType() == CameraSubmersionType.WATER) {
31-
// adjust underwater visibility
32-
float visibilityMultiplier = MathHelper.lerp(tickProgress, AbysmClient.underwaterVisibilityMultiplier, AbysmClient.nextUnderwaterVisibilityMultiplier);
18+
float value = original.call(instance);
19+
float visibilityMultiplier = AbysmWaterFogModifier.lastUnderwaterVisibilityMultiplier;
3320

34-
if (visibilityMultiplier < (1.0F - MathHelper.EPSILON)) {
35-
underwaterVisibilityRef.set(underwaterVisibilityRef.get() * visibilityMultiplier);
36-
}
37-
}
21+
return value * visibilityMultiplier;
3822
}
3923
}
Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,35 @@
11
package dev.spiritstudios.abysm.client.mixin.render;
22

3-
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
43
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5-
import dev.spiritstudios.abysm.client.AbysmClient;
6-
import dev.spiritstudios.abysm.worldgen.biome.AbysmBiomes;
7-
import net.minecraft.block.enums.CameraSubmersionType;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.llamalad7.mixinextras.sugar.Local;
6+
import dev.spiritstudios.abysm.client.render.AbysmWaterFogModifier;
87
import net.minecraft.client.render.Camera;
98
import net.minecraft.client.render.fog.WaterFogModifier;
109
import net.minecraft.client.world.ClientWorld;
11-
import net.minecraft.registry.entry.RegistryEntry;
12-
import net.minecraft.util.math.BlockPos;
13-
import net.minecraft.util.math.ColorHelper;
14-
import net.minecraft.util.math.MathHelper;
1510
import net.minecraft.world.biome.Biome;
1611
import org.spongepowered.asm.mixin.Mixin;
17-
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1816

1917
@Mixin(WaterFogModifier.class)
2018
public abstract class WaterFogModifierMixin {
21-
@Shadow
22-
private static long updateTime;
2319

24-
@WrapMethod(method = "getFogColor")
25-
private int adjustWaterFogColor(ClientWorld world, Camera camera, int viewDistance, float skyDarkness, Operation<Integer> original) {
26-
int value = original.call(world, camera, viewDistance, skyDarkness);
27-
28-
CameraSubmersionType cameraSubmersionType = camera.getSubmersionType();
29-
if (cameraSubmersionType == CameraSubmersionType.WATER) {
30-
float lightness = 0.5F + 2.0F * MathHelper.clamp(MathHelper.cos(world.getSkyAngle(1.0F) * MathHelper.TAU), -0.25F, 0.25F);
31-
RegistryEntry<Biome> biome = world.getBiome(BlockPos.ofFloored(camera.getPos()));
32-
33-
// update underwater visiblity
34-
float visibilityMultiplier;
35-
if (biome.matchesKey(AbysmBiomes.FLORAL_REEF)) {
36-
visibilityMultiplier = 0.3F + 0.7F * lightness;
37-
} else if (biome.matchesKey(AbysmBiomes.DEEP_SEA_RUINS)) {
38-
visibilityMultiplier = 0.13F;
39-
} else {
40-
visibilityMultiplier = 1.0F;
41-
}
42-
43-
if (updateTime < 0L) {
44-
AbysmClient.underwaterVisibilityMultiplier = visibilityMultiplier;
45-
AbysmClient.nextUnderwaterVisibilityMultiplier = visibilityMultiplier;
46-
} else {
47-
AbysmClient.underwaterVisibilityMultiplier = AbysmClient.nextUnderwaterVisibilityMultiplier;
48-
AbysmClient.nextUnderwaterVisibilityMultiplier = MathHelper.lerp(0.007F, AbysmClient.underwaterVisibilityMultiplier, visibilityMultiplier);
49-
}
50-
51-
// adjust fog color
52-
if (lightness < 0.999F && biome.matchesKey(AbysmBiomes.FLORAL_REEF)) {
53-
int nightWaterFogColor = 0x11082F;
54-
return ColorHelper.lerp(lightness, nightWaterFogColor, value);
55-
} else {
56-
return value;
57-
}
58-
} else {
59-
return value;
60-
}
20+
@Inject(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/biome/Biome;getWaterFogColor()I"))
21+
private void updateUnderwaterVisibility(ClientWorld world, Camera camera, int viewDistance, float skyDarkness, CallbackInfoReturnable<Integer> cir, @Local(ordinal = 0) long measuringTime) {
22+
AbysmWaterFogModifier.updateUnderwaterVisibility(world, camera, measuringTime);
6123
}
6224

25+
@WrapOperation(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/biome/Biome;getWaterFogColor()I"))
26+
private int adjustFogColor(Biome instance, Operation<Integer> original, ClientWorld world, Camera camera, int viewDistance, float skyDarkness, @Local(ordinal = 0) long measuringTime) {
27+
int value = original.call(instance);
28+
return AbysmWaterFogModifier.adjustWaterFogColor(value, world, camera);
29+
}
6330

31+
@Inject(method = "onSkipped", at = @At("RETURN"))
32+
private void onSkipped(CallbackInfo ci) {
33+
AbysmWaterFogModifier.onSkipped();
34+
}
6435
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package dev.spiritstudios.abysm.client.render;
2+
3+
import dev.spiritstudios.abysm.worldgen.biome.AbysmBiomes;
4+
import net.minecraft.client.render.Camera;
5+
import net.minecraft.client.world.ClientWorld;
6+
import net.minecraft.registry.entry.RegistryEntry;
7+
import net.minecraft.util.math.ColorHelper;
8+
import net.minecraft.util.math.MathHelper;
9+
import net.minecraft.world.biome.Biome;
10+
11+
public class AbysmWaterFogModifier {
12+
private static float targetUnderwaterVisibilityMultiplier = 1.0F;
13+
private static float lerpedUnderwaterVisibilityMultiplier = 1.0F;
14+
public static float lastUnderwaterVisibilityMultiplier = 1.0F;
15+
private static long updateTime = -1L;
16+
17+
public static float getLightness(ClientWorld world) {
18+
return 0.5F + 2.0F * MathHelper.clamp(MathHelper.cos(world.getSkyAngle(1.0F) * MathHelper.TAU), -0.25F, 0.25F);
19+
}
20+
21+
public static RegistryEntry<Biome> getBiome(ClientWorld world, Camera camera) {
22+
return world.getBiome(camera.getBlockPos());
23+
}
24+
25+
public static int adjustWaterFogColor(int original, ClientWorld world, Camera camera) {
26+
float lightness = getLightness(world);
27+
RegistryEntry<Biome> biome = getBiome(world, camera);
28+
29+
return getFogColor(original, lightness, biome);
30+
}
31+
32+
public static int getFogColor(int original, float lightness, RegistryEntry<Biome> biome) {
33+
if (lightness < 0.999F && biome.matchesKey(AbysmBiomes.FLORAL_REEF)) {
34+
int nightWaterFogColor = 0x11082F;
35+
return ColorHelper.lerp(lightness, nightWaterFogColor, original);
36+
} else {
37+
return original;
38+
}
39+
}
40+
41+
public static void updateUnderwaterVisibility(ClientWorld world, Camera camera, long time) {
42+
float lightness = getLightness(world);
43+
RegistryEntry<Biome> biome = getBiome(world, camera);
44+
45+
float visibilityMultiplier = getUnderwaterVisibilityMultiplier(biome, lightness);
46+
47+
if (updateTime < 0L) {
48+
targetUnderwaterVisibilityMultiplier = visibilityMultiplier;
49+
lerpedUnderwaterVisibilityMultiplier = visibilityMultiplier;
50+
lastUnderwaterVisibilityMultiplier = visibilityMultiplier;
51+
updateTime = time;
52+
return;
53+
}
54+
55+
float lerpFactor = MathHelper.clamp((float) (time - updateTime) / 5000.0F, 0.0F, 1.0F);
56+
float currentVisibility = MathHelper.lerp(lerpFactor, lerpedUnderwaterVisibilityMultiplier, targetUnderwaterVisibilityMultiplier);
57+
58+
if (targetUnderwaterVisibilityMultiplier != visibilityMultiplier) {
59+
targetUnderwaterVisibilityMultiplier = visibilityMultiplier;
60+
lerpedUnderwaterVisibilityMultiplier = currentVisibility;
61+
updateTime = time;
62+
}
63+
64+
lastUnderwaterVisibilityMultiplier = currentVisibility;
65+
}
66+
67+
public static float getUnderwaterVisibilityMultiplier(RegistryEntry<Biome> biome, float lightness) {
68+
if (biome.matchesKey(AbysmBiomes.FLORAL_REEF)) {
69+
return 0.3F + 0.7F * lightness;
70+
} else if (biome.matchesKey(AbysmBiomes.DEEP_SEA_RUINS)) {
71+
return 0.13F;
72+
} else {
73+
return 1.0F;
74+
}
75+
}
76+
77+
public static void onSkipped() {
78+
updateTime = -1L;
79+
targetUnderwaterVisibilityMultiplier = 1.0F;
80+
lerpedUnderwaterVisibilityMultiplier = 1.0F;
81+
lastUnderwaterVisibilityMultiplier = 1.0F;
82+
}
83+
}

0 commit comments

Comments
 (0)