Skip to content

Commit

Permalink
Improve zoom culling, and make it toggleable
Browse files Browse the repository at this point in the history
Yeah! My laptop didn't handle it well! but lowering the rendered chunks did help make the culling instantaneous once more;
Really, you can overwhelm Minecraft with too much terrain at once, and only Sodium can fix this (heck, throw shaders on top of it, you can get 50 FPS but Sodium will still fix the pipeline)
  • Loading branch information
EnnuiL committed Nov 29, 2024
1 parent 2a276c8 commit abfe1d8
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ public static class TweaksConfig extends Section {
@Comment("Allows for resetting the zoom with the middle mouse button.")
public final TrackedValue<Boolean> resetZoomWithMouse = this.value(true);

@WidgetSize(Size.HALF)
@Comment("Improves performance by having the game render less of the world when not necessary while zoomed in. Disable this feature if you notice glitches on zooming out and if the game cannot be optimized any further.")
public final TrackedValue<Boolean> zoomAwareOcclusion = this.value(true);

@WidgetSize(Size.HALF)
@Comment("If enabled, the current zoom divisor is forgotten once zooming is finished.")
public final TrackedValue<Boolean> forgetZoomDivisor = this.value(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ public static void startClientTick(Minecraft minecraft) {
minecraft.player.playSound(soundDirection ? SoundEvents.SPYGLASS_USE : SoundEvents.SPYGLASS_STOP_USING, 1.0F, 1.0F);
}

ZoomUtils.validateZoomCulling(minecraft);

// Set the previous zoom signal for the next tick
lastZooming = zooming;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private void tickInstances(CallbackInfo info) {
)
)
private int modifyCulling(int original) {
if (!Zoom.isZooming()) {
if (!Zoom.isZooming() || !OkZoomerConfigManager.CONFIG.tweaks.zoomAwareOcclusion.value()) {
return original;
} else {
return Mth.positiveCeilDiv(original, Mth.floor(Zoom.getZoomDivisor()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.github.ennuil.ok_zoomer.mixin.common;

import io.github.ennuil.ok_zoomer.config.OkZoomerConfigManager;
import io.github.ennuil.ok_zoomer.zoom.Zoom;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.SectionOcclusionGraph;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.util.Mth;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(LevelRenderer.class)
public abstract class LevelRendererMixin {
@Shadow
@Final
private SectionOcclusionGraph sectionOcclusionGraph;

@Unique
private int prevZoomDivisor = 1;

@Inject(
method = "setupRender",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/renderer/LevelRenderer;prevCamX:D",
ordinal = 1
)
)
private void accountForZooming(Camera camera, Frustum frustum, boolean hasCapturedFrustum, boolean isSpectator, CallbackInfo ci) {
if (OkZoomerConfigManager.CONFIG.tweaks.zoomAwareOcclusion.value()) {
int divisor = Zoom.isZooming() ? Mth.floor(Zoom.getZoomDivisor()) : 1;

if (divisor != this.prevZoomDivisor) {
this.sectionOcclusionGraph.invalidate();
}

this.prevZoomDivisor = divisor;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,6 @@ public class ZoomUtils {

private static Predicate<LocalPlayer> hasSpyglass = player -> player.isCreative();

public static void validateZoomCulling() {
var minecraft = Minecraft.getInstance();
validateZoomCulling(minecraft);
}

public static void validateZoomCulling(Minecraft minecraft) {
int fov = minecraft.options.fov().get();
int divisor = Zoom.isZooming() ? Mth.floor(Zoom.getZoomDivisor()) : 1;
int zoomCullingFov = Math.ceilDiv(fov, divisor);

if (zoomCullingFov != lastZoomCullingFov) {
minecraft.levelRenderer.getSectionOcclusionGraph().invalidate();
}

lastZoomCullingFov = zoomCullingFov;
}

// The method used for changing the zoom divisor, used by zoom scrolling and the key binds
public static void changeZoomDivisor(Minecraft minecraft, boolean increase) {
double zoomDivisor = OkZoomerConfigManager.CONFIG.zoomValues.zoomDivisor.value();
Expand All @@ -61,8 +44,6 @@ public static void changeZoomDivisor(Minecraft minecraft, boolean increase) {

zoomStep = increase ? Math.min(zoomStep + 1, upperScrollStep) : Math.max(zoomStep - 1, -lowerScrollStep);

validateZoomCulling(minecraft);

if (zoomStep > 0) {
Zoom.setZoomDivisor(zoomDivisor + ((maximumZoomDivisor - zoomDivisor) / upperScrollStep * zoomStep));
} else if (zoomStep == 0) {
Expand All @@ -78,9 +59,6 @@ public static void resetZoomDivisor(boolean userPrompted) {

Zoom.resetZoomDivisor();
zoomStep = 0;
if (userPrompted) {
validateZoomCulling();
}
}

public static void keepZoomStepsWithinBounds() {
Expand Down
2 changes: 2 additions & 0 deletions common/src/main/resources/assets/ok_zoomer/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
"config.ok_zoomer.tweaks.hide_crosshair.tooltip": "Hides the crosshair while zooming.",
"config.ok_zoomer.tweaks.reset_zoom_with_mouse": "Reset Zoom with Mouse",
"config.ok_zoomer.tweaks.reset_zoom_with_mouse.tooltip": "Allows for resetting the zoom with the middle mouse button.",
"config.ok_zoomer.tweaks.zoom_aware_occlusion": "Zoom-Aware Occlusion",
"config.ok_zoomer.tweaks.zoom_aware_occlusion.tooltip": "Improves performance by having the game render less of the world when not necessary while zoomed in. Disable this feature if you notice glitches on zooming out and if the game cannot be optimized any further.",
"config.ok_zoomer.tweaks.forget_zoom_divisor": "Forget Zoom Divisor",
"config.ok_zoomer.tweaks.forget_zoom_divisor.tooltip": "If enabled, the current zoom divisor is forgotten once zooming is finished.",
"config.ok_zoomer.tweaks.use_spyglass_sounds": "Use Spyglass Sounds",
Expand Down
31 changes: 16 additions & 15 deletions common/src/main/resources/ok_zoomer.mixins.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
{
"required": true,
"minVersion": "0.8",
"package": "io.github.ennuil.ok_zoomer.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"common.AbstractClientPlayerMixin",
"common.EditBoxAccessor",
"common.EditBoxMixin",
"common.GameRendererMixin",
"common.GuiMixin",
"common.MouseHandlerMixin",
"common.RenderStateShardMixin"
],
"injectors": {
"defaultRequire": 1
"required": true,
"minVersion": "0.8",
"package": "io.github.ennuil.ok_zoomer.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"common.AbstractClientPlayerMixin",
"common.EditBoxAccessor",
"common.EditBoxMixin",
"common.GameRendererMixin",
"common.GuiMixin",
"common.LevelRendererMixin",
"common.MouseHandlerMixin",
"common.RenderStateShardMixin"
],
"injectors": {
"defaultRequire": 1
}
}

0 comments on commit abfe1d8

Please sign in to comment.