Added corruption visual effect

This commit is contained in:
Sollace 2022-12-12 01:05:10 +00:00
parent b1aef9160d
commit 1b091fc5fd
3 changed files with 158 additions and 0 deletions

View file

@ -12,17 +12,20 @@ import com.minelittlepony.unicopia.client.gui.LanSettingsScreen;
import com.minelittlepony.unicopia.client.gui.UHud; import com.minelittlepony.unicopia.client.gui.UHud;
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen; import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate; import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
import com.minelittlepony.unicopia.client.render.shader.ViewportShader;
import com.minelittlepony.unicopia.container.*; import com.minelittlepony.unicopia.container.*;
import com.minelittlepony.unicopia.entity.player.PlayerCamera; import com.minelittlepony.unicopia.entity.player.PlayerCamera;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.OpenToLanScreen; import net.minecraft.client.gui.screen.OpenToLanScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreens; import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.resource.ResourceType;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class UnicopiaClient implements ClientModInitializer { public class UnicopiaClient implements ClientModInitializer {
@ -67,6 +70,8 @@ public class UnicopiaClient implements ClientModInitializer {
ScreenInitCallback.EVENT.register(this::onScreenInit); ScreenInitCallback.EVENT.register(this::onScreenInit);
ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer()); ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer());
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(ViewportShader.INSTANCE);
Unicopia.SIDE = () -> Optional.ofNullable(MinecraftClient.getInstance().player).map(Pony::of); Unicopia.SIDE = () -> Optional.ofNullable(MinecraftClient.getInstance().player).map(Pony::of);
} }

View file

@ -0,0 +1,136 @@
package com.minelittlepony.unicopia.client.render.shader;
import java.io.IOException;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import com.google.common.collect.*;
import com.google.gson.JsonSyntaxException;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.*;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SynchronousResourceReloader;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
public class ViewportShader implements SynchronousResourceReloader, IdentifiableResourceReloadListener {
private static final Logger LOGGER = LogUtils.getLogger();
private static final Identifier ID = Unicopia.id("viewport_shader");
public static final ViewportShader INSTANCE = new ViewportShader();
public static final Identifier CREEPER_SHADER = new Identifier("shaders/post/invert.json");
public static final Identifier DESATURATION_SHADER = new Identifier("shaders/post/desaturate.json");
private final MinecraftClient client = MinecraftClient.getInstance();
@Nullable
private LoadedShader shader;
@Override
public Identifier getFabricId() {
return ID;
}
public void loadShader(@Nullable Identifier shaderId) {
if (shader != null) {
shader.close();
}
if (shaderId == null) {
return;
}
try {
shader = new LoadedShader(client, shaderId);
} catch (IOException e) {
LOGGER.warn("Failed to load shader: {}", shaderId, e);
} catch (JsonSyntaxException e) {
LOGGER.warn("Failed to parse shader: {}", shaderId, e);
}
}
public void onResized(int width, int height) {
if (shader != null) {
shader.setupDimensions(width, height);
}
}
public void render(float tickDelta) {
if (shader != null && client.player != null) {
RenderSystem.disableBlend();
RenderSystem.disableDepthTest();
RenderSystem.enableTexture();
RenderSystem.resetTextureMatrix();
Pony pony = Pony.of(client.player);
float corruption = pony.getCorruption().getScaled(0.9F);
corruption = pony.getInterpolator().interpolate("corruption", corruption, 10);
corruption = 1 - corruption + 0.05F;
shader.setUniformValue("color_convolve", "Saturation", corruption);
shader.render(tickDelta);
}
}
@Override
public void reload(ResourceManager var1) {
if (shader != null) {
loadShader(shader.id);
} else {
loadShader(DESATURATION_SHADER);
}
}
static class LoadedShader extends ShaderEffect {
private final Object2FloatMap<String> uniformValues = new Object2FloatOpenHashMap<>();
private Multimap<String, JsonEffectGlShader> programs;
private final Identifier id;
public LoadedShader(MinecraftClient client, Identifier id) throws IOException, JsonSyntaxException {
super(client.getTextureManager(), client.getResourceManager(), client.getFramebuffer(), id);
this.id = id;
setupDimensions(
client.getWindow().getFramebufferWidth(),
client.getWindow().getFramebufferHeight()
);
}
@Override
public PostProcessShader addPass(String programName, Framebuffer source, Framebuffer dest) throws IOException {
PostProcessShader pass = super.addPass(programName, source, dest);
if (programs == null) {
programs = LinkedListMultimap.create();
}
programs.put(pass.getProgram().getName(), pass.getProgram());
return pass;
}
public void setUniformValue(String programName, String uniformName, float value) {
float currentValue = uniformValues.containsKey(uniformName) ? 0F : uniformValues.getFloat(uniformName);
if (!MathHelper.approximatelyEquals(value, currentValue)) {
uniformValues.put(uniformName, value);
programs.get(programName).forEach(program -> {
GlUniform uniform = program.getUniformByName(uniformName);
if (uniform != null) {
uniform.set(value);
}
});
}
}
}
}

View file

@ -2,12 +2,14 @@ package com.minelittlepony.unicopia.mixin.client;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.client.BatEyesApplicator; import com.minelittlepony.unicopia.client.BatEyesApplicator;
import com.minelittlepony.unicopia.client.UnicopiaClient; import com.minelittlepony.unicopia.client.UnicopiaClient;
import com.minelittlepony.unicopia.client.render.shader.ViewportShader;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera; import net.minecraft.client.render.Camera;
@ -60,4 +62,19 @@ abstract class MixinGameRenderer implements AutoCloseable, SynchronousResourceRe
info.setReturnValue(UnicopiaClient.getWorldBrightness(info.getReturnValueF())); info.setReturnValue(UnicopiaClient.getWorldBrightness(info.getReturnValueF()));
} }
} }
@Inject(method = "render",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/gl/Framebuffer.beginWrite(Z)V",
shift = Shift.BEFORE)
)
private void onBeforeFrameEnd(float tickDelta, long startTime, boolean tick, CallbackInfo info) {
ViewportShader.INSTANCE.render(tickDelta);
}
@Inject(method = "onResized", at = @At("HEAD"))
private void onResized(int width, int height, CallbackInfo info) {
ViewportShader.INSTANCE.onResized(width, height);
}
} }