diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index 3150741277..9173efdbf4 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,5 +1,15 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java +@@ -473,6 +_,9 @@ + this.targets.entityOutline = framegraphbuilder.importExternal("entity_outline", this.entityOutlineTarget); + } + ++ var setupEvent = net.neoforged.neoforge.client.ClientHooks.fireFrameGraphSetup(framegraphbuilder, this.targets, rendertargetdescriptor, frustum, p_109604_, p_254120_, p_323920_, p_348530_, profilerfiller); ++ flag2 |= setupEvent.isOutlineProcessingEnabled(); ++ + FramePass framepass = framegraphbuilder.addPass("clear"); + this.targets.main = framepass.readsAndWrites(this.targets.main); + framepass.executes(() -> { @@ -480,7 +_,7 @@ RenderSystem.clear(16640); }); diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index c0c70806c8..7e497ecaf2 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -8,8 +8,10 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableMap; +import com.mojang.blaze3d.framegraph.FrameGraphBuilder; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.resource.RenderTargetDescriptor; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -64,6 +66,7 @@ import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.LevelTargetBundle; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderDefines; @@ -105,6 +108,7 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.util.profiling.Profiler; +import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; @@ -142,6 +146,7 @@ import net.neoforged.neoforge.client.event.ComputeFovModifierEvent; import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent; import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.event.FrameGraphSetupEvent; import net.neoforged.neoforge.client.event.GatherEffectScreenTooltipsEvent; import net.neoforged.neoforge.client.event.InputEvent; import net.neoforged.neoforge.client.event.ModelEvent; @@ -1089,4 +1094,9 @@ public static Map gatherMaterialAtlases(Map< ModLoader.postEvent(new RegisterMaterialAtlasesEvent(vanillaAtlases)); return Map.copyOf(vanillaAtlases); } + + @ApiStatus.Internal + public static FrameGraphSetupEvent fireFrameGraphSetup(FrameGraphBuilder builder, LevelTargetBundle targets, RenderTargetDescriptor renderTargetDescriptor, Frustum frustum, Camera camera, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, DeltaTracker deltaTracker, ProfilerFiller profiler) { + return NeoForge.EVENT_BUS.post(new FrameGraphSetupEvent(builder, targets, renderTargetDescriptor, frustum, camera, modelViewMatrix, projectionMatrix, deltaTracker, profiler)); + } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/FrameGraphSetupEvent.java b/src/main/java/net/neoforged/neoforge/client/event/FrameGraphSetupEvent.java new file mode 100644 index 0000000000..2a410c7bd7 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/FrameGraphSetupEvent.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.blaze3d.framegraph.FrameGraphBuilder; +import com.mojang.blaze3d.resource.RenderTargetDescriptor; +import net.minecraft.client.Camera; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.renderer.LevelTargetBundle; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.util.profiling.ProfilerFiller; +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.ApiStatus; +import org.joml.Matrix4f; + +/** + * Fired when the {@linkplain FrameGraphBuilder frame graph} is set up at the start of level rendering, right before + * the vanilla frame passes are set up. + *

+ * This event is not {@linkplain ICancellableEvent cancellable}. + *

+ * This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, + * only on the {@linkplain LogicalSide#CLIENT logical client}. + */ +public final class FrameGraphSetupEvent extends Event { + private final FrameGraphBuilder builder; + private final LevelTargetBundle targets; + private final RenderTargetDescriptor renderTargetDescriptor; + private final Frustum frustum; + private final Camera camera; + private final Matrix4f modelViewMatrix; + private final Matrix4f projectionMatrix; + private final DeltaTracker deltaTracker; + private final ProfilerFiller profiler; + private boolean enableOutline; + + @ApiStatus.Internal + public FrameGraphSetupEvent( + FrameGraphBuilder builder, + LevelTargetBundle targets, + RenderTargetDescriptor renderTargetDescriptor, + Frustum frustum, + Camera camera, + Matrix4f modelViewMatrix, + Matrix4f projectionMatrix, + DeltaTracker deltaTracker, + ProfilerFiller profiler) { + this.builder = builder; + this.targets = targets; + this.renderTargetDescriptor = renderTargetDescriptor; + this.frustum = frustum; + this.camera = camera; + this.modelViewMatrix = modelViewMatrix; + this.projectionMatrix = projectionMatrix; + this.deltaTracker = deltaTracker; + this.profiler = profiler; + } + + /** + * {@return the {@link FrameGraphBuilder} used to set up the frame graph} + */ + public FrameGraphBuilder getFrameGrapBuilder() { + return builder; + } + + /** + * {@return the render targets used during level rendering} + */ + public LevelTargetBundle getTargetBundle() { + return targets; + } + + /** + * {@return the render target descriptor to use for creating full-screen render targets} + */ + public RenderTargetDescriptor getRenderTargetDescriptor() { + return renderTargetDescriptor; + } + + /** + * {@return the culling frustum} + */ + public Frustum getFrustum() { + return frustum; + } + + /** + * {@return the active {@link Camera}} + */ + public Camera getCamera() { + return camera; + } + + /** + * {@return the model view matrix} + */ + public Matrix4f getModelViewMatrix() { + return modelViewMatrix; + } + + /** + * {@return the projection matrix} + */ + public Matrix4f getProjectionMatrix() { + return projectionMatrix; + } + + /** + * {@return the {@link DeltaTracker}} + */ + public DeltaTracker getDeltaTracker() { + return deltaTracker; + } + + /** + * {@return the active {@linkplain ProfilerFiller profiler}} + */ + public ProfilerFiller getProfiler() { + return profiler; + } + + /** + * Enables the entity outline post-processing shader regardless of any entities having active outlines + */ + public void enableOutlineProcessing() { + this.enableOutline = true; + } + + /** + * {@return whether the entity outline post-processing shader will be enabled regardless of entities using it} + */ + public boolean isOutlineProcessingEnabled() { + return enableOutline; + } +}