3535import net .minecraft .client .renderer .texture .DynamicTexture ;
3636import net .minecraft .core .BlockPos ;
3737import net .minecraft .core .Direction ;
38+ import net .minecraft .world .entity .Entity ;
3839import net .minecraft .world .entity .player .Player ;
3940import net .minecraft .world .level .Level ;
4041import net .minecraft .world .phys .HitResult ;
4142import net .minecraft .world .phys .Vec3 ;
4243import net .minecraftforge .client .event .EntityViewRenderEvent ;
43- import net .minecraftforge .client .event .RenderLevelLastEvent ;
44+ import net .minecraftforge .client .event .RenderLevelStageEvent ;
4445import net .minecraftforge .client .event .RenderNameplateEvent ;
4546import net .minecraftforge .event .TickEvent ;
4647import net .minecraftforge .eventbus .api .Event ;
@@ -66,7 +67,7 @@ public final class ProjectorDepthRenderer {
6667 private static final DynamicTexture [] PROJECTOR_COLOR_TARGETS = new DynamicTexture [ModShaders .MAX_PROJECTORS ];
6768 private static final Matrix4f [] PROJECTOR_CAMERA_MATRICES = new Matrix4f [ModShaders .MAX_PROJECTORS ];
6869 private static final Camera PROJECTOR_DEPTH_CAMERA = new Camera ();
69- private static final DepthOnlyRenderTarget MAIN_CAMERA_DEPTH = new DepthOnlyRenderTarget (MainTarget .DEFAULT_WIDTH , MainTarget .DEFAULT_HEIGHT );
70+ private static DepthOnlyRenderTarget MAIN_CAMERA_DEPTH = new DepthOnlyRenderTarget (MainTarget .DEFAULT_WIDTH , MainTarget .DEFAULT_HEIGHT );
7071 private static final float PROJECTOR_FORWARD_SHIFT = 7 / 16f ; // From center of projector block.
7172 private static final float PROJECTOR_NEAR = 0.5f - PROJECTOR_FORWARD_SHIFT ;
7273 private static final float PROJECTOR_FAR = ProjectorBlockEntity .MAX_RENDER_DISTANCE ;
@@ -86,6 +87,8 @@ public final class ProjectorDepthRenderer {
8687 private static boolean isRenderingProjectorDepth ;
8788 private static HitResult hitResultBak ;
8889 private static boolean entityShadowsBak ;
90+ private static Entity minecraftCameraEntityBak ;
91+ private static Camera gameRendererMainCameraBak ;
8992
9093 private static void handleProjectorNoLongerRendering (final RemovalNotification <ProjectorBlockEntity , RenderInfo > notification ) {
9194 final ProjectorBlockEntity projector = notification .getKey ();
@@ -140,7 +143,7 @@ public static boolean isIsRenderingProjectorDepth() {
140143 * method to grab the current depth buffer. This is necessary, because the depth buffer may be messed up by other
141144 * render passes when using the "Fabulous!" graphics mode.
142145 * <p>
143- * Called before {@link #handleRenderLevelLast(RenderLevelLastEvent )} every frame.
146+ * Called before {@link #renderProjectors(RenderLevelStageEvent )} every frame.
144147 */
145148 public static void captureMainCameraDepth () {
146149 final RenderTarget mainRenderTarget = Minecraft .getInstance ().getMainRenderTarget ();
@@ -149,6 +152,9 @@ public static void captureMainCameraDepth() {
149152 }
150153 if (mainRenderTarget .isStencilEnabled ()) {
151154 MAIN_CAMERA_DEPTH .enableStencil ();
155+ } else if (MAIN_CAMERA_DEPTH .isStencilEnabled ()) {
156+ MAIN_CAMERA_DEPTH .destroyBuffers ();
157+ MAIN_CAMERA_DEPTH = new DepthOnlyRenderTarget (mainRenderTarget .width , mainRenderTarget .height );
152158 }
153159 MAIN_CAMERA_DEPTH .copyDepthFrom (mainRenderTarget );
154160 mainRenderTarget .bindWrite (false );
@@ -159,7 +165,14 @@ public static void captureMainCameraDepth() {
159165 * {@link #addProjector(ProjectorBlockEntity)} this frame.
160166 */
161167 @ SubscribeEvent
162- public static void handleRenderLevelLast (final RenderLevelLastEvent event ) {
168+ public static void renderProjectors (final RenderLevelStageEvent event ) {
169+ if (event .getStage () != RenderLevelStageEvent .Stage .AFTER_PARTICLES ) {
170+ return ;
171+ }
172+ if (isIsRenderingProjectorDepth ()) {
173+ return ;
174+ }
175+
163176 if (VISIBLE_PROJECTORS .isEmpty ()) {
164177 return ;
165178 }
@@ -178,7 +191,7 @@ public static void handleRenderLevelLast(final RenderLevelLastEvent event) {
178191 });
179192
180193 final int projectorCount = Math .min (VISIBLE_PROJECTORS .size (), ModShaders .MAX_PROJECTORS );
181- renderProjectorDepths (minecraft , level , player , event .getPartialTick (), event . getStartNanos (), projectorCount );
194+ renderProjectorDepths (minecraft , level , event .getPartialTick (), projectorCount );
182195 renderProjectorColors (minecraft , event .getPoseStack ().last ().pose (), event .getProjectionMatrix (), projectorCount );
183196 } finally {
184197 VISIBLE_PROJECTORS .clear ();
@@ -221,10 +234,10 @@ public static void handleClientTick(final TickEvent.ClientTickEvent event) {
221234 * bre rendered. The output is the list of depth buffers, MVP matrices that were used to render them, and the
222235 * associated color texture for the projector.
223236 */
224- private static void renderProjectorDepths (final Minecraft minecraft , final ClientLevel level , final Player player ,
225- final float partialTicks , final long startNanos ,
226- final int projectorCount ) {
227- prepareDepthBufferRendering (minecraft , level );
237+ private static void renderProjectorDepths (final Minecraft minecraft , final ClientLevel level ,
238+ final float partialTicks , final int projectorCount ) {
239+ final Vec3 mainCameraPosition = minecraft . gameRenderer . getMainCamera (). getPosition ();
240+ prepareDepthBufferRendering (minecraft , level , partialTicks );
228241 try {
229242 final PoseStack viewModelStack = new PoseStack ();
230243 for (int projectorIndex = 0 ; projectorIndex < projectorCount ; projectorIndex ++) {
@@ -239,22 +252,22 @@ private static void renderProjectorDepths(final Minecraft minecraft, final Clien
239252 RenderSystem .setProjectionMatrix (DEPTH_CAMERA_PROJECTION_MATRIX );
240253 setupViewModelMatrix (viewModelStack );
241254
242- storeProjectorMatrix (projectorIndex , minecraft , projectorPos , viewModelStack );
255+ storeProjectorMatrix (projectorIndex , projectorPos , mainCameraPosition , viewModelStack );
243256
244257 bindProjectorDepthRenderTarget (projectorIndex , minecraft );
245258
246- renderProjectorDepthBuffer (minecraft , partialTicks , startNanos , viewModelStack );
259+ renderProjectorDepthBuffer (minecraft , partialTicks , viewModelStack );
247260
248261 storeProjectorColorBuffer (projectorIndex , projector );
249262
250263 projector .onRendering ();
251264 }
252265 } finally {
253- finishDepthBufferRendering (minecraft , player );
266+ finishDepthBufferRendering (minecraft );
254267 }
255268 }
256269
257- private static void prepareDepthBufferRendering (final Minecraft minecraft , final ClientLevel level ) {
270+ private static void prepareDepthBufferRendering (final Minecraft minecraft , final ClientLevel level , final float partialTicks ) {
258271 isRenderingProjectorDepth = true ;
259272
260273 // Suppresses hit outlines being rendered.
@@ -265,12 +278,15 @@ private static void prepareDepthBufferRendering(final Minecraft minecraft, final
265278 entityShadowsBak = minecraft .options .entityShadows ;
266279 minecraft .options .entityShadows = false ;
267280
268- minecraft .setCameraEntity (ProjectorCameraEntity .get (level , Vec3 .ZERO , 0 ));
281+ minecraftCameraEntityBak = minecraft .getCameraEntity ();
282+ minecraft .setCameraEntity (ProjectorCameraEntity .get (level , Vec3 .ZERO , partialTicks ));
283+ gameRendererMainCameraBak = minecraft .gameRenderer .mainCamera ;
284+ minecraft .gameRenderer .mainCamera = PROJECTOR_DEPTH_CAMERA ;
269285
270286 RenderSystem .backupProjectionMatrix ();
271287 }
272288
273- private static void finishDepthBufferRendering (final Minecraft minecraft , final Player player ) {
289+ private static void finishDepthBufferRendering (final Minecraft minecraft ) {
274290 minecraft .hitResult = hitResultBak ;
275291 minecraft .options .entityShadows = entityShadowsBak ;
276292
@@ -279,7 +295,8 @@ private static void finishDepthBufferRendering(final Minecraft minecraft, final
279295 ((MinecraftExt ) minecraft ).setMainRenderTargetOverride (null );
280296 minecraft .getMainRenderTarget ().bindWrite (true );
281297
282- minecraft .setCameraEntity (player );
298+ minecraft .setCameraEntity (minecraftCameraEntityBak );
299+ minecraft .gameRenderer .mainCamera = gameRendererMainCameraBak ;
283300
284301 isRenderingProjectorDepth = false ;
285302 }
@@ -298,10 +315,7 @@ private static void setupViewModelMatrix(final PoseStack viewModelStack) {
298315 }
299316 }
300317
301- private static void storeProjectorMatrix (final int projectorIndex , final Minecraft minecraft , final Vec3 projectorPos , final PoseStack viewModelStack ) {
302- final Camera mainCamera = minecraft .gameRenderer .getMainCamera ();
303- final Vec3 mainCameraPosition = mainCamera .getPosition ();
304-
318+ private static void storeProjectorMatrix (final int projectorIndex , final Vec3 projectorPos , final Vec3 mainCameraPosition , final PoseStack viewModelStack ) {
305319 // Save model-view-projection matrix for mapping in compositing shader. We use the position relative to the
306320 // main camera here, so that the main camera can sit at the origin. This avoids loss of precision.
307321 PROJECTOR_CAMERA_MATRICES [projectorIndex ].load (DEPTH_CAMERA_PROJECTION_MATRIX );
@@ -321,7 +335,7 @@ private static void bindProjectorDepthRenderTarget(final int projectorIndex, fin
321335 ((MinecraftExt ) minecraft ).setMainRenderTargetOverride (projectorDepthTarget );
322336 }
323337
324- private static void renderProjectorDepthBuffer (final Minecraft minecraft , final float partialTicks , final long startNanos , final PoseStack viewModelStack ) {
338+ private static void renderProjectorDepthBuffer (final Minecraft minecraft , final float partialTicks , final PoseStack viewModelStack ) {
325339 final LevelRenderer levelRenderer = minecraft .levelRenderer ;
326340 levelRenderer .prepareCullFrustum (
327341 viewModelStack ,
@@ -331,7 +345,7 @@ private static void renderProjectorDepthBuffer(final Minecraft minecraft, final
331345 levelRenderer .renderLevel (
332346 viewModelStack ,
333347 partialTicks ,
334- startNanos ,
348+ /* startNanos */ 0 ,
335349 /* shouldRenderBlockOutline: */ false ,
336350 PROJECTOR_DEPTH_CAMERA ,
337351 minecraft .gameRenderer ,
@@ -341,7 +355,7 @@ private static void renderProjectorDepthBuffer(final Minecraft minecraft, final
341355 }
342356
343357 private static void storeProjectorColorBuffer (final int projectorIndex , final ProjectorBlockEntity projector ) {
344- PROJECTOR_COLOR_TARGETS [projectorIndex ] = getRenderInfo (projector ). texture ( );
358+ PROJECTOR_COLOR_TARGETS [projectorIndex ] = getColorBuffer (projector );
345359 }
346360
347361 /**
@@ -352,7 +366,6 @@ private static void storeProjectorColorBuffer(final int projectorIndex, final Pr
352366 */
353367 private static void renderProjectorColors (final Minecraft minecraft , final Matrix4f modelViewMatrix , final Matrix4f projectionMatrix , final int projectorCount ) {
354368 prepareColorBufferRendering ();
355-
356369 try {
357370 prepareOrthographicRendering (minecraft );
358371
@@ -439,15 +452,15 @@ private static Matrix4f getFrustumMatrix(final float near, final float far, fina
439452 });
440453 }
441454
442- private static RenderInfo getRenderInfo (final ProjectorBlockEntity projector ) {
455+ private static DynamicTexture getColorBuffer (final ProjectorBlockEntity projector ) {
443456 try {
444457 return RENDER_INFO .get (projector , () -> {
445458 final DynamicTexture texture = new DynamicTexture (ProjectorDevice .WIDTH , ProjectorDevice .HEIGHT , false );
446459 texture .upload ();
447460 final RenderInfo renderInfo = new RenderInfo (texture );
448461 projector .setFrameConsumer (renderInfo );
449462 return renderInfo ;
450- });
463+ }). texture () ;
451464 } catch (final ExecutionException e ) {
452465 throw new RuntimeException (e );
453466 }
0 commit comments