Another big step towards Blur+

- Added rainbow mode!
- Allow gradients to be rotated
- Add many new animation curves
- Update to 1.20.5
This commit is contained in:
Martin Prokoph
2024-04-29 15:10:43 +02:00
parent 22037bd37d
commit 853f137d0c
10 changed files with 124 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version '1.5-SNAPSHOT'
id 'fabric-loom' version '1.6-SNAPSHOT'
id 'maven-publish'
}
@@ -56,8 +56,8 @@ processResources {
}
tasks.withType(JavaCompile).configureEach {
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
it.options.release = 17
// Minecraft 1.20.5 upwards uses Java 21.
it.options.release = 21
}
java {

View File

@@ -4,9 +4,9 @@ org.gradle.parallel=true
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=24w11a
yarn_mappings=24w11a+build.5
loader_version=0.15.7
minecraft_version=1.20.5
yarn_mappings=1.20.5+build.1
loader_version=0.15.10
# Mod Properties
mod_version=4.0.0
@@ -15,5 +15,5 @@ org.gradle.parallel=true
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.96.11+1.20.5
midnightlib_version=fabric-1.5.3-24w09a
fabric_version=0.97.7+1.20.5
midnightlib_version=1.5.4-fabric

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -1,8 +1,18 @@
package eu.midnightdust.blur;
import eu.midnightdust.blur.config.BlurConfig;
import eu.midnightdust.blur.util.RainbowColor;
import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.gui.DrawContext;
import org.joml.Math;
import java.awt.*;
import java.lang.Double;
import static eu.midnightdust.blur.util.RainbowColor.hue;
import static eu.midnightdust.blur.util.RainbowColor.hue2;
public class Blur implements ClientModInitializer {
@@ -22,6 +32,7 @@ public class Blur implements ClientModInitializer {
@Override
public void onInitializeClient() {
BlurConfig.init("blur", BlurConfig.class);
ClientTickEvents.END_CLIENT_TICK.register(RainbowColor::tick);
}
public static boolean doFade = false;
@@ -42,25 +53,26 @@ public class Blur implements ClientModInitializer {
}
public static void updateProgress(boolean fadeIn) {
float x;
double x;
if (fadeIn) {
x = Math.min((System.currentTimeMillis() - start) / (float) BlurConfig.fadeTimeMillis, 1);
if (BlurConfig.animationCurve.equals(BlurConfig.AnimationCurve.EASE)) x *= (2 - x); // easeInCubic
x = Math.min((System.currentTimeMillis() - start) / (double) BlurConfig.fadeTimeMillis, 1);
}
else {
x = Math.max(1 + (start - System.currentTimeMillis()) / (float) BlurConfig.fadeOutTimeMillis, 0);
if (BlurConfig.animationCurve.equals(BlurConfig.AnimationCurve.EASE)) x *= (2 - x); // easeOutCubic
x = Math.max(1 + (start - System.currentTimeMillis()) / (double) BlurConfig.fadeOutTimeMillis, 0);
if (x <= 0) {
start = -1;
x = 0;
}
}
Blur.progress = x;
x = BlurConfig.animationCurve.apply(x, fadeIn);
x = Math.clamp(0, 1, x);
Blur.progress = Double.valueOf(x).floatValue();
}
public static int getBackgroundColor(boolean second) {
int a = second ? BlurConfig.gradientEndAlpha : BlurConfig.gradientStartAlpha;
var col = MidnightColorUtil.hex2Rgb(second ? BlurConfig.gradientEnd : BlurConfig.gradientStart);
if (BlurConfig.rainbowMode) col = second ? Color.getHSBColor(hue, 1, 1) : Color.getHSBColor(hue2, 1, 1);
int r = (col.getRGB() >> 16) & 0xFF;
int b = (col.getRGB() >> 8) & 0xFF;
int g = col.getRGB() & 0xFF;
@@ -71,4 +83,18 @@ public class Blur implements ClientModInitializer {
b *= prog;
return a << 24 | r << 16 | b << 8 | g;
}
public static int getRotation() {
if (BlurConfig.rainbowMode) return RainbowColor.rotation;
return BlurConfig.gradientRotation;
}
public static boolean renderRotatedGradient(DrawContext context, int width, int height) {
if (getRotation() > 0) {
context.getMatrices().peek().getPositionMatrix().rotationZ(Math.toRadians(getRotation()));
context.getMatrices().peek().getPositionMatrix().setTranslation(width / 2f, height / 2f, 0); // Make the gradient's center the pivot point
context.getMatrices().peek().getPositionMatrix().scale(Math.sqrt((float) width*width + height*height) / height); // Scales the gradient to the maximum diagonal value needed
context.fillGradient(-width / 2, -height / 2, width / 2, height / 2, Blur.getBackgroundColor(false), Blur.getBackgroundColor(true)); // Actually draw the gradient
context.getMatrices().peek().getPositionMatrix().rotationZ(0);
return true;
} return false;
}
}

View File

@@ -1,6 +1,9 @@
package eu.midnightdust.blur.config;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.function.Function;
import static java.lang.Math.*;
public class BlurConfig extends MidnightConfig {
public static final String ANIMATIONS = "animations";
@@ -10,11 +13,11 @@ public class BlurConfig extends MidnightConfig {
@Entry(category = STYLE)
public static boolean blurContainers = true;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
public static int fadeTimeMillis = 200;
public static int fadeTimeMillis = 300;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
public static int fadeOutTimeMillis = 200;
public static int fadeOutTimeMillis = 300;
@Entry(category = ANIMATIONS)
public static AnimationCurve animationCurve = AnimationCurve.EASE;
public static BlurConfig.Easing animationCurve = Easing.FLAT;
@Entry(category = STYLE)
public static boolean useGradient = true;
@Entry(category = STYLE, isColor = true, width = 7, min = 7)
@@ -25,8 +28,36 @@ public class BlurConfig extends MidnightConfig {
public static String gradientEnd = "#000000";
@Entry(category = STYLE, isSlider = true, min = 0, max = 255)
public static int gradientEndAlpha = 75;
@Entry(category = STYLE, isSlider = true, min = 0, max = 360)
public static int gradientRotation = 0;
@Entry(category = STYLE)
public static boolean rainbowMode = false;
public enum AnimationCurve {
EASE, FLAT;
public enum Easing {
// Based on https://gist.github.com/dev-hydrogen/21a66f83f0386123e0c0acf107254843
// Thanks you very much!
FLAT(x -> x, x -> x),
SINE(x -> 1 - cos(x * PI) / 2, x -> sin(x * PI) / 2),
QUAD(x -> x * x, x -> 1 - (1 - x) * (1 - x)),
CUBIC(x -> x * x * x, x -> 1 - pow(1 - x, 3)),
QUART(x -> x * x * x * x, x -> 1 - pow(1 - x, 4)),
QUINT(x -> x * x * x * x * x, x -> 1 - pow(1 - x, 5)),
EXPO(x -> x == 0 ? 0 : pow(2, 10 * x - 10), x -> x == 1 ? 1 : 1 - pow(2, -10 * x)),
CIRC(x -> 1 - sqrt(1 - pow(x, 2)), x -> sqrt(1 - pow(x - 1, 2))),
BACK(x -> 2.70158 * x * x * x - 1.70158 * x * x,x -> 1 + 2.70158 * pow(x - 1, 3) + 1.70158 * pow(x - 1, 2)),
ELASTIC(x -> x == 0 ? 0 : x == 1 ? 1 : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * ((2 * PI) / 3)), x -> x == 0 ? 0 : x == 1 ? 1 : pow(2, -10 * x) * sin((x * 10 - 0.75) * ((2 * PI) / 3)) + 1);
final Function<Double, Number> functionIn;
final Function<Double, Number> functionOut;
Easing(Function<Double, Number> functionIn, Function<Double, Number> functionOut) {
this.functionIn = functionIn;
this.functionOut = functionOut;
}
public Double apply(Double x, boolean in) {
if (in) return functionIn.apply(x).doubleValue();
return functionOut.apply(x).doubleValue();
}
}
}

View File

@@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
public class MixinGameRenderer {
@ModifyVariable(method = "renderBlur", at = @At("STORE"), ordinal = 1)
private float blur$modifyRadius(float radius) { // Modify the radius based on the animation progress
if (!Blur.screenChanged && Blur.start >= 0) // Only update the progress after all tests have been completed
Blur.updateProgress(Blur.screenHasBlur);
return radius * Blur.progress;

View File

@@ -23,7 +23,8 @@ public class MixinInGameHud {
this.client.gameRenderer.renderBlur(delta);
this.client.getFramebuffer().beginWrite(false);
if (Blur.prevScreenHasBackground) context.fillGradient(0, 0, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight(), Blur.getBackgroundColor(false), Blur.getBackgroundColor(true));
if (Blur.prevScreenHasBackground && !Blur.renderRotatedGradient(context, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()))
context.fillGradient(0, 0, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight(), Blur.getBackgroundColor(false), Blur.getBackgroundColor(true));
}
}
}

View File

@@ -26,15 +26,10 @@ public abstract class MixinScreen {
@Shadow public abstract void renderInGameBackground(DrawContext context);
// @Unique
// private final Text blurConfig = Text.translatable("blur.midnightconfig.title");
@Shadow public int width;
@Shadow public int height;
// @Inject(at = @At("HEAD"), method = "tick")
// private void blur$reloadShader(CallbackInfo ci) {
// if (this.client != null && this.title.equals(blurConfig)) {
// //Blur.onScreenChange();
// }
// }
@Inject(at = @At("HEAD"), method = "render")
public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (!Blur.doTest && Blur.screenChanged) { // After the tests for blur and background color have been completed
@@ -46,7 +41,7 @@ public abstract class MixinScreen {
this.client.gameRenderer.renderBlur(delta);
this.client.getFramebuffer().beginWrite(false);
if (Blur.prevScreenHasBackground) context.fillGradient(0, 0, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight(), Blur.getBackgroundColor(false), Blur.getBackgroundColor(true));
if (Blur.prevScreenHasBackground && !Blur.renderRotatedGradient(context, width, height)) context.fillGradient(0, 0, width, height, Blur.getBackgroundColor(false), Blur.getBackgroundColor(true));
}
Blur.doTest = false; // Set the test state to completed, as tests will happen in the same tick.
}
@@ -80,4 +75,9 @@ public abstract class MixinScreen {
private int blur$getSecondBackgroundColor(int color) {
return Blur.getBackgroundColor(true);
}
@Inject(at = @At("HEAD"), method = "renderInGameBackground", cancellable = true)
public void blur$rotatedGradient(DrawContext context, CallbackInfo ci) {
if (Blur.renderRotatedGradient(context, width, height)) ci.cancel();
}
}

View File

@@ -0,0 +1,22 @@
package eu.midnightdust.blur.util;
import eu.midnightdust.blur.config.BlurConfig;
import net.minecraft.client.MinecraftClient;
public class RainbowColor {
public static int rotation;
public static float hue;
public static float hue2 = 0.35f;
public static void tick(MinecraftClient client) {
if (BlurConfig.rainbowMode) {
if (hue >= 1) hue = 0f;
hue += 0.01f;
if (hue2 >= 1) hue2 = 0f;
hue2 += 0.01f;
if (rotation >= 360) rotation = 0;
rotation += 1;
}
}
}

View File

@@ -6,12 +6,22 @@
"blur.midnightconfig.fadeTimeMillis": "Fade Time (in milliseconds)",
"blur.midnightconfig.fadeOutTimeMillis": "Fade Out Time (in milliseconds)",
"blur.midnightconfig.animationCurve": "Animation Curve",
"blur.midnightconfig.enum.AnimationCurve.EASE": "Ease",
"blur.midnightconfig.enum.AnimationCurve.FLAT": "Flat",
"blur.midnightconfig.enum.Easing.FLAT": "Flat",
"blur.midnightconfig.enum.Easing.SINE": "Sine",
"blur.midnightconfig.enum.Easing.QUAD": "Quad",
"blur.midnightconfig.enum.Easing.CUBIC": "Cubic",
"blur.midnightconfig.enum.Easing.QUART": "Quart",
"blur.midnightconfig.enum.Easing.QUINT": "Quint",
"blur.midnightconfig.enum.Easing.EXPO": "Expo",
"blur.midnightconfig.enum.Easing.CIRC": "Circ",
"blur.midnightconfig.enum.Easing.BACK": "Back",
"blur.midnightconfig.enum.Easing.ELASTIC": "Elastic",
"blur.midnightconfig.radius": "Radius",
"blur.midnightconfig.rainbowMode": "Rainbow Mode \uD83C\uDF08",
"blur.midnightconfig.useGradient": "Gradient as Background",
"blur.midnightconfig.gradientStart": "Gradient Start Color",
"blur.midnightconfig.gradientEnd": "Gradient End Color",
"blur.midnightconfig.gradientStartAlpha": "Gradient Start Alpha",
"blur.midnightconfig.gradientEndAlpha": "Gradient End Alpha"
"blur.midnightconfig.gradientEndAlpha": "Gradient End Alpha",
"blur.midnightconfig.gradientRotation": "Gradient Rotation"
}