From e85618a27c09e74dc79b19f8df4edd89d5b6eded Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Tue, 29 Jun 2021 12:48:38 +0200 Subject: [PATCH] Change frame time (used by Iris) to be based on replay or video time Iris derives that one from the frameStartNanos argument passed to the render method and shaders usually use it to do animations. Prior to this commit we always pass 0 which effectively froze any shader animations. With this commit, we now compute the frameStartNanos based on the FPS of the video we are rendering (so animations will happen in real time when watching the video) or based on the time in the replay (so animations will be influenced by playback speed / be frozen if the replay is frozen). We default to the video time based approach because the replay time one may produce undesirable results when it comes to things like motion blur and TAA. --- .../java/com/replaymod/render/Setting.java | 2 ++ .../render/hooks/EntityRendererHandler.java | 25 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/replaymod/render/Setting.java b/src/main/java/com/replaymod/render/Setting.java index d8426126..c8a58037 100644 --- a/src/main/java/com/replaymod/render/Setting.java +++ b/src/main/java/com/replaymod/render/Setting.java @@ -7,4 +7,6 @@ public final class Setting { new SettingsRegistry.SettingKeys<>("advanced", "renderPath", null, "./replay_videos/"); public static final SettingsRegistry.SettingKey SKIP_POST_RENDER_GUI = new SettingsRegistry.SettingKeys<>("advanced", "skipPostRenderGui", null, false); + public static final SettingsRegistry.SettingKey FRAME_TIME_FROM_WORLD_TIME = + new SettingsRegistry.SettingKeys<>("render", "frameTimeFromWorldTime", null, false); } diff --git a/src/main/java/com/replaymod/render/hooks/EntityRendererHandler.java b/src/main/java/com/replaymod/render/hooks/EntityRendererHandler.java index 20e10c07..8dbd50f7 100644 --- a/src/main/java/com/replaymod/render/hooks/EntityRendererHandler.java +++ b/src/main/java/com/replaymod/render/hooks/EntityRendererHandler.java @@ -1,22 +1,22 @@ package com.replaymod.render.hooks; +import com.replaymod.core.ReplayMod; import com.replaymod.core.events.PreRenderHandCallback; import com.replaymod.core.versions.MCVer; import com.replaymod.render.RenderSettings; +import com.replaymod.render.Setting; import com.replaymod.render.capturer.CaptureData; import com.replaymod.render.capturer.RenderInfo; import com.replaymod.render.capturer.WorldRenderer; +import com.replaymod.replay.ReplayModReplay; import de.johni0702.minecraft.gui.utils.EventRegistrations; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; -//#if MC>=11500 -import net.minecraft.client.util.math.MatrixStack; -//#endif - //#if MC>=11400 import com.replaymod.core.events.PostRenderCallback; import com.replaymod.core.events.PreRenderCallback; +import net.minecraft.util.Util; //#else //#if MC>=11400 //$$ import net.minecraftforge.fml.hooks.BasicEventHooks; @@ -38,10 +38,18 @@ public class EntityRendererHandler extends EventRegistrations implements WorldRe public boolean omnidirectional; + private final long startTime; + public EntityRendererHandler(RenderSettings settings, RenderInfo renderInfo) { this.settings = settings; this.renderInfo = renderInfo; + //#if MC>=11400 + this.startTime = Util.getMeasuringTimeNano(); + //#else + //$$ this.startTime = System.nanoTime(); + //#endif + on(PreRenderHandCallback.EVENT, () -> omnidirectional); ((IEntityRenderer) mc.gameRenderer).replayModRender_setHandler(this); @@ -51,7 +59,14 @@ public class EntityRendererHandler extends EventRegistrations implements WorldRe @Override public void renderWorld(final float partialTicks, CaptureData data) { this.data = data; - renderWorld(partialTicks, 0); + long offsetMillis; + if (ReplayMod.instance.getSettingsRegistry().get(Setting.FRAME_TIME_FROM_WORLD_TIME)) { + offsetMillis = ReplayModReplay.instance.getReplayHandler().getReplaySender().currentTimeStamp(); + } else { + offsetMillis = renderInfo.getFramesDone() * 1_000L / settings.getFramesPerSecond(); + } + long frameStartTimeNano = startTime + offsetMillis * 1_000_000L; + renderWorld(partialTicks, frameStartTimeNano); } public void renderWorld(float partialTicks, long finishTimeNano) {