From 6cf119dfee1a2e6cc869a1f138513d659793d542 Mon Sep 17 00:00:00 2001 From: Alexdoru <57050655+Alexdoru@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:55:03 +0200 Subject: [PATCH] Dynamically modify the render distance for dropped items entities to preserve performance (#653) * change sodium EntityMixin to use modify arg instead of @inject that cancels all the time * restore the 16 block render distance for dropped items * set EntityItem render distance to 32 blocks * dynamically reduce the render distance for dropped Item entities when there is too many * Add dropped item limit setting to video settings Add some missing notfine tooltip entries while I was in there * set maximum of dropped items to 2048 --------- Co-authored-by: Jason Mitchell --- .../angelica/config/AngelicaConfig.java | 11 ++++ .../gtnewhorizons/angelica/mixins/Mixins.java | 8 ++- .../client/gui/SodiumGameOptionPages.java | 13 ++++- .../control/ControlValueFormatter.java | 3 ++ .../storage/AngelicaOptionsStorage.java | 23 ++++++++ .../options/storage/SodiumOptionsStorage.java | 2 +- .../resources/assets/angelica/lang/en_US.lang | 5 ++ .../resources/assets/notfine/lang/en_US.lang | 19 +++++++ .../MixinRenderGlobal_ItemRenderDist.java | 53 +++++++++++++++++++ .../mixins/early/sodium/MixinEntity.java | 24 --------- .../sodium/MixinEntityItem_RenderDist.java | 25 +++++++++ .../early/sodium/MixinEntity_RenderDist.java | 17 ++++++ 12 files changed, 176 insertions(+), 27 deletions(-) create mode 100644 src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/AngelicaOptionsStorage.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/optimizations/MixinRenderGlobal_ItemRenderDist.java delete mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntityItem_RenderDist.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity_RenderDist.java diff --git a/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java b/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java index 6cb79ea15..47a7bb213 100644 --- a/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java +++ b/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java @@ -127,6 +127,17 @@ public class AngelicaConfig { @Config.RequiresMcRestart public static boolean fixFluidRendererCheckingBlockAgain; + @Config.Comment("Dynamically modifies the render distance of dropped items entities to preserve performance." + + " It starts reducing the render distance when exceeding the threshold set below.") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean dynamicItemRenderDistance; + + @Config.Comment("Max amount of dropped item rendered") + @Config.DefaultInt(256) + @Config.RangeInt(min = 32, max = 2048) + public static int droppedItemLimit; + @Config.Comment("Enable Debug Logging") @Config.DefaultBoolean(false) @Config.RequiresMcRestart diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java index cad94da11..2b8eccab8 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java @@ -70,6 +70,11 @@ public enum Mixins { .setApplyIf(() -> AngelicaConfig.fixFluidRendererCheckingBlockAgain) .addTargetedMod(TargetedMod.VANILLA)), + ANGELICA_LIMIT_DROPPED_ITEM_ENTITIES(new Builder("Dynamically modifies the render distance of dropped items entities to preserve performance") + .setPhase(Phase.EARLY).addMixinClasses("angelica.optimizations.MixinRenderGlobal_ItemRenderDist").setSide(Side.CLIENT) + .setApplyIf(() -> AngelicaConfig.dynamicItemRenderDistance) + .addTargetedMod(TargetedMod.VANILLA)), + // Not compatible with the lwjgl debug callbacks, so disable if that's enabled ARCHAIC_SPLASH(new Builder("ArchaicFix Splash").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT) .setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.showSplashMemoryBar && !AngelicaMod.lwjglDebug).addMixinClasses( @@ -108,7 +113,8 @@ public enum Mixins { ,"sodium.MixinChunk" ,"sodium.MixinChunkProviderServer" ,"sodium.MixinClientRegistry" - ,"sodium.MixinEntity" + ,"sodium.MixinEntity_RenderDist" + ,"sodium.MixinEntityItem_RenderDist" ,"sodium.MixinRenderManager" ,"sodium.MixinExtendedBlockStorage" ,"sodium.MixinEntityRenderer" diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java index 9130c87ab..c6fa1b3c8 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -19,6 +19,7 @@ import me.jellysquid.mods.sodium.client.gui.options.named.GraphicsQuality; import me.jellysquid.mods.sodium.client.gui.options.named.LightingQuality; import me.jellysquid.mods.sodium.client.gui.options.named.ParticleMode; +import me.jellysquid.mods.sodium.client.gui.options.storage.AngelicaOptionsStorage; import me.jellysquid.mods.sodium.client.gui.options.storage.MinecraftOptionsStorage; import me.jellysquid.mods.sodium.client.gui.options.storage.SodiumOptionsStorage; import me.jellysquid.mods.sodium.client.render.chunk.backends.multidraw.MultidrawChunkRenderBackend; @@ -36,6 +37,7 @@ public class SodiumGameOptionPages { private static final SodiumOptionsStorage sodiumOpts = new SodiumOptionsStorage(); private static final MinecraftOptionsStorage vanillaOpts = new MinecraftOptionsStorage(); + private static final AngelicaOptionsStorage angelicaOpts = new AngelicaOptionsStorage(); public static OptionPage general() { final List groups = new ArrayList<>(); @@ -153,6 +155,15 @@ else if(Minecraft.getMinecraft().currentScreen instanceof SodiumOptionsGUI oldGu .add(Settings.DYNAMIC_FOV.option) .add(Settings.MODE_WATER.option) .add(Settings.MODE_DROPPED_ITEMS.option) + .add( + OptionImpl.createBuilder(int.class, angelicaOpts) + .setName(I18n.format("options.angelica.droppedItemLimit")) + .setTooltip(I18n.format("options.angelica.droppedItemLimit.tooltip")) + .setControl(option -> new SliderControl(option, 32, 2048, 32, ControlValueFormatter.droppedItemLimitLimit())) + .setBinding((options, value) -> AngelicaConfig.droppedItemLimit = value, options -> AngelicaConfig.droppedItemLimit) + .setImpact(OptionImpact.MEDIUM) + .build() + ) .build()); return new OptionPage(I18n.format("stat.generalButton"), ImmutableList.copyOf(groups)); @@ -246,7 +257,7 @@ public static OptionPage quality() { .build()) .build()); groups.add(OptionGroup.createBuilder() - .add(Settings.MODE_GLINT_INV.option) + .add(Settings.MODE_GLINT_INV.option) .add(Settings.MODE_GLINT_WORLD.option) .build()); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java index 69c454848..ec211998a 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java @@ -10,6 +10,9 @@ static ControlValueFormatter guiScale() { static ControlValueFormatter fpsLimit() { return (v) -> (v == 260) ? I18n.format("options.framerateLimit.max") : I18n.format("options.framerate", v); } + static ControlValueFormatter droppedItemLimitLimit() { + return (v) -> (v == 2048) ? I18n.format("options.droppedItems.max") : I18n.format("options.droppedItems", v); + } static ControlValueFormatter brightness() { return (v) -> { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/AngelicaOptionsStorage.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/AngelicaOptionsStorage.java new file mode 100644 index 000000000..baf8e8f01 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/AngelicaOptionsStorage.java @@ -0,0 +1,23 @@ +package me.jellysquid.mods.sodium.client.gui.options.storage; + +import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; +import com.gtnewhorizons.angelica.config.AngelicaConfig; +import me.jellysquid.mods.sodium.client.SodiumClientMod; + +public class AngelicaOptionsStorage implements OptionStorage { + + public AngelicaOptionsStorage() { + + } + + @Override + public AngelicaConfig getData() { + return null; + } + + @Override + public void save() { + ConfigurationManager.save(AngelicaConfig.class); + SodiumClientMod.logger().info("Flushed changes to Angelica configuration"); + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/SodiumOptionsStorage.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/SodiumOptionsStorage.java index c8b3372b5..1e636ad26 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/SodiumOptionsStorage.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/storage/SodiumOptionsStorage.java @@ -25,6 +25,6 @@ public void save() { throw new RuntimeException("Couldn't save configuration changes", e); } - SodiumClientMod.logger().info("Flushed changes to Rubidium configuration"); + SodiumClientMod.logger().info("Flushed changes to Angelica configuration"); } } diff --git a/src/main/resources/assets/angelica/lang/en_US.lang b/src/main/resources/assets/angelica/lang/en_US.lang index eeac035dc..e7a1b6e73 100644 --- a/src/main/resources/assets/angelica/lang/en_US.lang +++ b/src/main/resources/assets/angelica/lang/en_US.lang @@ -2,6 +2,8 @@ options.button.shader=Shaders... options.chunks=%s chunks options.entityShadows=Entity Shadows +options.droppedItems=%s items +options.droppedItems.max=Unlimited sodium.option_impact.low=Low sodium.option_impact.medium=Medium sodium.option_impact.high=High @@ -124,12 +126,15 @@ options.iris.setToDefault=Set option to default value? options.iris.profile=Profile options.iris.profile.custom=Custom options.iris.shadowDistance=Max Shadow Distance +options.iris.shadowDistance.sodium_tooltip=Max Shadow Distance options.iris.shadowDistance.enabled=Allows you to change the maximum distance for shadows. Terrain and entities beyond this distance will not cast shadows. Lowering the shadow distance can significantly increase performance. options.iris.shadowDistance.disabled=Your current shader pack has already set a render distance for shadows; you cannot change it. options.iris.gui.hide=Hide GUI options.iris.gui.show=Show GUI options.dynamic_lights=Dynamic Lights options.dynamic_lights.tooltip=Enables dynamic lights. Modes: OFF - off, FASTEST - 500ms delay, FAST - 250ms delay, FANCY - no delay. Disabled if shaders are in use. +options.angelica.droppedItemLimit=Dropped Item Render Limit +options.angelica.droppedItemLimit.tooltip=The maximum number of dropped items that will be rendered. Lower values can improve performance. pack.iris.select.title=Select pack.iris.configure.title=Configure label.iris.true=On diff --git a/src/main/resources/assets/notfine/lang/en_US.lang b/src/main/resources/assets/notfine/lang/en_US.lang index 13a3ea63e..86b3f0354 100644 --- a/src/main/resources/assets/notfine/lang/en_US.lang +++ b/src/main/resources/assets/notfine/lang/en_US.lang @@ -11,33 +11,52 @@ options.graphics.ultra=Ultra options.off=Off options.on=On options.cloud_height=Cloud Elevation +options.cloud_height.tooltip=Cloud Elevation options.cloud_scale=Cloud Scale +options.cloud_scale.tooltip=Cloud Scale options.gui_background=Background options.downfall_distance=Weather Effects options.dynamic_fov=Dynamic FOV options.dynamic_fov.tooltip=If enabled, the game's field of view will change based on the player's speed. options.fog_near_distance=Near Fog Distance +options.fog_near_distance.tooltip=Near Fog Distance options.mode_cloud_translucency=Cloud Translucency +options.mode_cloud_translucency.tooltip=Cloud Translucency options.mode_clouds=Clouds +options.mode_clouds.tooltip=Clouds options.mode_dropped_items=Dropped Items +options.mode_dropped_items.tooltip=Dropped Items Rendering Quality options.mode_glint_inv=GUI Enchant VFX +options.mode_glint_inv.tooltip=GUI Enchant VFX options.mode_glint_world=World Enchant VFX +options.mode_glint_world.tooltip=World Enchant VFX options.mode_gui_background=Menu Backgrounds options.mode_leaves=Foliage options.mode_light_flicker=Light Flicker +options.mode_light_flicker.tooltip=Light Flicker options.mode_shadows=Entity Shadows options.mode_sky=Sky +options.mode_sky.tooltip=Render the Sky options.mode_sun_moon=Sun & Moon +options.mode_sun_moon.tooltip=Render Sun & Moon options.mode_stars=Stars +options.mode_stars.tooltip=Render Stars options.mode_water=Water +options.mode_water.tooltip=Water options.mode_vignette=Vignette +options.mode_vignette.tooltip=Vignette options.particles_enc_table=Enchantment Particles +options.particles_enc_table.tooltip=Enchantment Particles options.particles_void=Void Particles +options.particles_void.tooltip=Void Particles options.render_distance_clouds=Minimum Cloud Distance +options.render_distance_clouds.tooltip=Minimum Cloud Distance options.title.detail=Detail Settings options.title.other=Other Settings options.title.particle=Particle Settings options.title.sky=Atmosphere Settings options.title.video=Video Settings options.total_stars=Star Density +options.total_stars.tooltip=Star Density options.void_fog=Void Fog +options.void_fog.tooltip=Void Fog diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/optimizations/MixinRenderGlobal_ItemRenderDist.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/optimizations/MixinRenderGlobal_ItemRenderDist.java new file mode 100644 index 000000000..d014981d3 --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/optimizations/MixinRenderGlobal_ItemRenderDist.java @@ -0,0 +1,53 @@ +package com.gtnewhorizons.angelica.mixins.early.angelica.optimizations; + +import com.gtnewhorizons.angelica.config.AngelicaConfig; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import org.spongepowered.asm.mixin.Mixin; +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.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RenderGlobal.class) +public class MixinRenderGlobal_ItemRenderDist { + + @Unique private static final int[] sodium$entityItemCount = new int[256]; + @Unique private static int sodium$itemRenderDist = 255; + + @Inject(method = "renderEntities", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/RenderGlobal;countEntitiesRendered:I", ordinal = 0)) + private void sodium$resetEntitycount(CallbackInfo ci) { + int entityCount = 0; + boolean reachedLimit = false; + final int itemLimit = AngelicaConfig.droppedItemLimit == 2048 ? Integer.MAX_VALUE : AngelicaConfig.droppedItemLimit; + for (int i = 0; i < sodium$entityItemCount.length; i++) { + entityCount += sodium$entityItemCount[i]; + sodium$entityItemCount[i] = 0; + if (!reachedLimit && entityCount > itemLimit) { + reachedLimit = true; + sodium$itemRenderDist = i == 0 ? 1 : i; + } + } + if (!reachedLimit) { + sodium$itemRenderDist = 255; + } + } + + @ModifyVariable(method = "renderEntities", at = @At(value = "STORE", ordinal = 0), ordinal = 0, name = "flag") + private boolean sodium$renderEntityItems(boolean flag, + @Local(ordinal = 0, name = "entity") Entity entity, + @Local(ordinal = 0, name = "d0") double d0, + @Local(ordinal = 1, name = "d1") double d1, + @Local(ordinal = 2, name = "d2") double d2) { + if (flag && entity instanceof EntityItem) { + final int i = Math.min((int) (entity.getDistanceSq(d0, d1, d2) / 4.0D), 255); + sodium$entityItemCount[i]++; + return i <= sodium$itemRenderDist; + } + return flag; + } + +} diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity.java deleted file mode 100644 index 4cbc969a9..000000000 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gtnewhorizons.angelica.mixins.early.sodium; - -import com.llamalad7.mixinextras.sugar.Local; -import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(Entity.class) -public abstract class MixinEntity { - - @Shadow - public abstract boolean isInRangeToRenderDist(double dist); - - @Inject(method ="isInRangeToRender3d", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isInRangeToRenderDist(D)Z"), cancellable = true) - private void sodium$afterDistCalc(CallbackInfoReturnable ci, @Local(ordinal = 6) double d6) { - ci.setReturnValue(this.isInRangeToRenderDist(d6/(SodiumGameOptions.EntityRenderDistance.entityRenderDistanceMultiplier * SodiumGameOptions.EntityRenderDistance.entityRenderDistanceMultiplier))); - } - - -} diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntityItem_RenderDist.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntityItem_RenderDist.java new file mode 100644 index 000000000..479f5fcdb --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntityItem_RenderDist.java @@ -0,0 +1,25 @@ +package com.gtnewhorizons.angelica.mixins.early.sodium; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(EntityItem.class) +public abstract class MixinEntityItem_RenderDist extends Entity { + + public MixinEntityItem_RenderDist(World worldIn) { + super(worldIn); + } + + @Override + public boolean isInRangeToRender3d(double x, double y, double z) { + double d3 = this.posX - x; + double d4 = this.posY - y; + double d5 = this.posZ - z; + double d6 = d3 * d3 + d4 * d4 + d5 * d5; + // set render distance to 32 blocks + return this.isInRangeToRenderDist(d6 / 4.0D); + } + +} diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity_RenderDist.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity_RenderDist.java new file mode 100644 index 000000000..c20171b94 --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/sodium/MixinEntity_RenderDist.java @@ -0,0 +1,17 @@ +package com.gtnewhorizons.angelica.mixins.early.sodium; + +import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(Entity.class) +public abstract class MixinEntity_RenderDist { + + @ModifyArg(method = "isInRangeToRender3d", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isInRangeToRenderDist(D)Z")) + private double sodium$afterDistCalc(double d6) { + final double mult = SodiumGameOptions.EntityRenderDistance.entityRenderDistanceMultiplier; + return d6 / (mult * mult); + } +}