Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

I'm trying to conditionally hide specific chunks by disabling their rendering logic. I've found that LevelRenderer does this using renderChunksInFrustum but I don't think this is the only place they are rendered.

I've got this mixin that (for testing purposes) just hides every 2nd chunk on the X axis:

@Mixin(LevelRenderer.class)
public abstract class LevelRendererMixin {

    @Final
    @Shadow
    private ObjectArrayList<LevelRenderer.RenderChunkInfo> renderChunksInFrustum;

    @Inject(
        method = "renderLevel(Lcom/mojang/blaze3d/vertex/PoseStack;FJZLnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/GameRenderer;Lnet/minecraft/client/renderer/LightTexture;Lcom/mojang/math/Matrix4f;)V",
        at = @At("HEAD")
    )
    private void renderlevel(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
        if (OrthoviewClientEvents.isEnabled())
            renderChunksInFrustum.removeIf(chunkInfo -> chunkInfo.chunk.bb.minX % 32 == 0)
    }
}

While this does hide the chunks I expected (see below), it seems it only works while the camera is stationary. While the camera is moving, all chunks will still show, causing a flickering effect as you move around.

n1NCxKT.png

Note that the Orthoview flag in my mod is just the isometric camera being enabled, but this problem happens in the regular camera too so that isn't an issue.

Where is the logic to render chunks while the camera is moving and how can I apply the same conditions I want to it from my mixin?

57 minutes ago, SoLegendary said:

I've found that LevelRenderer does this using renderChunksInFrustum but I don't think this is the only place they are rendered.

That's an incorrect assumption. What you should look for is where the chunks are added which happens within `renderLevel`, so every time the game loads a new area because of the camera moving, the chunks that were removed will flicker as they are added in and compiled in the next frame of execution. If you want to properly handle things, you should look into LevelRenderer#applyFrustum where the chunks are added to the field.

  • Author

Ok so i've got it mostly reliable now, and managed to force a frustum update every tick so it doesn't rely on the camera to move to update.

    @Final @Shadow private ObjectArrayList<LevelRenderer.RenderChunkInfo> renderChunksInFrustum;
    @Final @Shadow private AtomicReference<LevelRenderer.RenderChunkStorage> renderChunkStorage = new AtomicReference<>();
    @Final @Shadow private Minecraft minecraft;

    @Inject(
        method = "applyFrustum(Lnet/minecraft/client/renderer/culling/Frustum;)V",
        at = @At("HEAD"),
        cancellable = true
    )
    private void applyFrustum(Frustum pFrustum, CallbackInfo ci) {
        ci.cancel();

        if (!Minecraft.getInstance().isSameThread()) {
            throw new IllegalStateException("applyFrustum called from wrong thread: " + Thread.currentThread().getName());
        } else {
            this.minecraft.getProfiler().push("apply_frustum");
            this.renderChunksInFrustum.clear();

            LinkedHashSet<LevelRenderer.RenderChunkInfo> renderChunkInfos = (this.renderChunkStorage.get()).renderChunks;

            for(LevelRenderer.RenderChunkInfo chunkInfo : renderChunkInfos) {
                if (pFrustum.isVisible(chunkInfo.chunk.getBoundingBox())) {

                    for (LivingEntity entity : UnitClientEvents.getAllUnits()) {

                        Vec3 centre = chunkInfo.chunk.bb.getCenter();
                        Vec2 centre2d = new Vec2((float) centre.x(), (float) centre.z());
                        Vec2 entity2d = new Vec2((float) entity.getX(), (float) entity.getZ());

                        if (entity2d.distanceToSqr(centre2d) < 900) {
                            this.renderChunksInFrustum.add(chunkInfo);
                            break;
                        }
                    }
                }
            }
            this.minecraft.getProfiler().pop();
        }
    }

 

However, i'm testing out only rendering chunks close to specific entities (for testing, centre of the chunk must be within 30 blocks of the entity), which kind of works but only when the viewing player is at specific positions:
L79lz78.png

However, if I move the player too far away from the entity, all of these chunks disappear, and renderChunkInfos contains only 7 items, instead of the usual 1000+, so it's not even an issue of my filtering logic. It's not the case that the entity i'm using to test distance with no longer exists as it is still loaded clientside (the leftmost mob in the below image). It also doesn't seem to be a frustum issue as it still happens even as I move the camera around. What is causing this and why is it tied to the player position?

EDIT: by "too far away" I mean only a few blocks away, basically just 1 chunk further than away than in the top image, not out of normal render distance of course

2jm4vRX.png

Edited by SoLegendary
more details

  • Author

I think I found the issue: when the player is in an unloaded chunk (ie. has never been loaded before in the world) renderChunkInfos is reduced to only your current chunk and adjacent chunks, but since my code only allowed rendering of the chunks near the mob I specified, it never gets a chance to load anything else. The solution may be to allow the player's immediate chunk to be loaded to avoid this issue, though I hope I can still not actually render it somehow.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.