diff --git a/gradle.properties b/gradle.properties index d396830a1..c28ab23d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx2G org.gradle.parallel = true org.gradle.caching = true -mod_version = 2.5.1 +mod_version = 2.5.2 minecraft_version = 1.16.1 # https://github.com/tildejustin/yarn/tags diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java index c0b49b193..2f4413953 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java @@ -46,8 +46,8 @@ public static class QualitySettings implements SpeedrunConfigStorage { public static class SpeedrunSettings implements SpeedrunConfigStorage { public boolean usePlanarFog = true; - public boolean showEntityCulling = true; - public boolean showFogOcclusion = true; + public boolean showEntityCulling = false; + public boolean showFogOcclusion = false; } { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/SodiumWorldRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/SodiumWorldRenderer.java index caffb805e..2d5e1e79d 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/SodiumWorldRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/SodiumWorldRenderer.java @@ -193,6 +193,10 @@ public void updateChunks(Camera camera, Frustum frustum, boolean hasForcedFrustu this.chunkRenderManager.update(camera, (FrustumExtended) frustum, frame, spectator); } + profiler.swap("chunk_update"); + + this.chunkRenderManager.updateImportantChunks(); + profiler.swap("visible_chunk_tick"); this.chunkRenderManager.tickVisibleRenders(); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java index 9dfd330d9..15cc4dfbe 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java @@ -49,7 +49,7 @@ public class ChunkRenderManager implements ChunkSt /** * The maximum distance a chunk can be from the player's camera in order to be eligible for blocking updates. */ - private static final double NEARBY_CHUNK_DISTANCE = Math.pow(48, 2.0); + private static final double NEARBY_CHUNK_DISTANCE; /** * The minimum distance the culling plane can be from the player's camera. This helps to prevent mathematical @@ -97,6 +97,10 @@ public class ChunkRenderManager implements ChunkSt private boolean usePlanarFog; private double fogRenderCutoff; + static { + NEARBY_CHUNK_DISTANCE = 768; // must not inline because of mixin in seedqueue + } + public ChunkRenderManager(SodiumWorldRenderer renderer, ChunkRenderBackend backend, BlockRenderPassManager renderPassManager, ClientWorld world, int renderDistance) { this.backend = backend; this.renderer = renderer; @@ -160,9 +164,12 @@ private void iterateChunks(Camera camera, FrustumExtended frustum, int frame, bo } private void addChunk(ChunkRenderContainer render) { + boolean enqueued = false; if (render.needsRebuild() && render.canRebuild()) { if (render.needsImportantRebuild()) { this.importantRebuildQueue.enqueue(render); + // important rebuilds are uploaded shortly after in updateChunks, uploading them now leads to blinking + enqueued = true; } else { this.rebuildQueue.enqueue(render); } @@ -178,7 +185,7 @@ private void addChunk(ChunkRenderContainer render) { } } - if (!render.isEmpty()) { + if (!render.isEmpty() && !enqueued) { this.addChunkToRenderLists(render); this.addEntitiesToRenderLists(render); } @@ -399,7 +406,7 @@ private ChunkRenderContainer createChunkRender(ChunkRenderColumn column, i if (ChunkSection.isEmpty(this.world.getChunk(x, z).getSectionArray()[y])) { render.setData(ChunkRenderData.EMPTY); } else { - render.scheduleRebuild(false); + render.scheduleRebuild(this.isChunkPrioritized(render)); } render.setId(this.renders.add(render)); @@ -432,9 +439,28 @@ public boolean isChunkVisible(int x, int y, int z) { } public void updateChunks() { + int budget = this.builder.getSchedulingBudget(); + int submitted = 0; + + while (submitted < budget && !this.rebuildQueue.isEmpty()) { + ChunkRenderContainer render = this.rebuildQueue.dequeue(); + + this.builder.deferRebuild(render); + submitted++; + } + + this.dirty |= submitted > 0; + + // have to do some uploads here to stop flashing issues? + this.dirty |= this.builder.performPendingUploads(); + + this.builder.createMoreThreads(); + } + + public void updateImportantChunks() { Deque>> futures = new ArrayDeque<>(); + Deque> containers = new ArrayDeque<>(); - int budget = this.builder.getSchedulingBudget(); int submitted = 0; while (!this.importantRebuildQueue.isEmpty()) { @@ -445,19 +471,13 @@ public void updateChunks() { this.builder.deferRebuild(render); } else { futures.add(this.builder.scheduleRebuildTaskAsync(render)); + containers.add(render); } this.dirty = true; submitted++; } - while (submitted < budget && !this.rebuildQueue.isEmpty()) { - ChunkRenderContainer render = this.rebuildQueue.dequeue(); - - this.builder.deferRebuild(render); - submitted++; - } - this.dirty |= submitted > 0; // Try to complete some other work on the main thread while we wait for rebuilds to complete @@ -467,7 +487,13 @@ public void updateChunks() { this.backend.upload(RenderDevice.INSTANCE.createCommandList(), new FutureDequeDrain<>(futures)); } - this.builder.createMoreThreads(); + while (!containers.isEmpty()) { + ChunkRenderContainer render = containers.poll(); + if (!render.isEmpty()) { + this.addChunkToRenderLists(render); + this.addEntitiesToRenderLists(render); + } + } } public void markDirty() { @@ -479,6 +505,9 @@ public boolean isDirty() { } public void restoreChunks(LongCollection chunks) { + // set cameraXYZ so chunks can be properly prioritized in rebuild scheduling + this.setup(MinecraftClient.getInstance().gameRenderer.getCamera()); + LongIterator it = chunks.iterator(); while (it.hasNext()) { diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/block/MixinWorldRenderer.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/block/MixinWorldRenderer.java index f2af6efdf..3709ab2af 100644 --- a/src/main/java/me/jellysquid/mods/sodium/mixin/features/block/MixinWorldRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/block/MixinWorldRenderer.java @@ -1,6 +1,5 @@ package me.jellysquid.mods.sodium.mixin.features.block; -import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; import me.jellysquid.mods.sodium.client.render.pipeline.context.ChunkRenderCacheShared; import net.minecraft.client.render.Camera; import net.minecraft.client.render.GameRenderer; @@ -9,17 +8,12 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.Matrix4f; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(WorldRenderer.class) public class MixinWorldRenderer { - @Shadow - private int regularEntityCount; - /** * Reset any global cached state before rendering a frame. This will hopefully ensure that any world state that has * changed is reflected in vanilla-style rendering. @@ -30,12 +24,4 @@ private void reset(MatrixStack matrices, float tickDelta, long limitTime, boolea CallbackInfo ci) { ChunkRenderCacheShared.resetCaches(); } - - @Redirect(method = "getEntitiesDebugString", at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/WorldRenderer;regularEntityCount:I")) - private int hidEntityCount(WorldRenderer instance) { - if(SodiumWorldRenderer.getInstance().getUseEntityCulling()){ - return -1; - } - return this.regularEntityCount; - } } diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinEntityRenderer.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinEntityRenderer.java index 9637fc71e..08f8185ef 100644 --- a/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinEntityRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinEntityRenderer.java @@ -1,8 +1,10 @@ package me.jellysquid.mods.sodium.mixin.features.entity.smooth_lighting; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import me.jellysquid.mods.sodium.client.model.light.EntityLighter; import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; import me.jellysquid.mods.sodium.client.render.entity.EntityLightSampler; +import me.jellysquid.mods.sodium.mixin.features.entity.smooth_lighting.accessor.WorldRendererAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.options.AoOption; import net.minecraft.client.render.Frustum; @@ -31,13 +33,15 @@ private void preGetLight(T entity, float tickDelta, CallbackInfoReturnable cir) { + @ModifyExpressionValue(method = "shouldRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Frustum;isVisible(Lnet/minecraft/util/math/Box;)Z")) + private boolean preShouldRender(boolean original, T entity, Frustum frustum, double x, double y, double z) { // If the entity isn't culled already by other means, try to perform a second pass - if (cir.getReturnValue() && !SodiumWorldRenderer.getInstance().isEntityVisible(entity)) { -// MinecraftClient.getInstance().worldRenderer.regularEntityCount++; - cir.setReturnValue(false); + if (original && !SodiumWorldRenderer.getInstance().isEntityVisible(entity)) { + WorldRendererAccessor wra = ((WorldRendererAccessor) MinecraftClient.getInstance().worldRenderer); + wra.setRegularEntityCount(wra.getRegularEntityCount() + 1); + return false; } + return original; } @Override diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinWorldRenderer.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinWorldRenderer.java index 7a2a77054..4c121bae5 100644 --- a/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinWorldRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/MixinWorldRenderer.java @@ -1,21 +1,30 @@ package me.jellysquid.mods.sodium.mixin.features.entity.smooth_lighting; -import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import me.jellysquid.mods.sodium.client.world.WorldRendererExtended; import net.minecraft.client.render.WorldRenderer; import net.minecraft.util.profiler.Profiler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Objects; @Mixin(WorldRenderer.class) public class MixinWorldRenderer { - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V")) - void doNothing(Profiler profiler, String location) { - if (!Objects.equals(location, "blockentities") || !SodiumWorldRenderer.getInstance().getUseEntityCulling()) { - profiler.swap(location); + @WrapWithCondition(method = "render", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", args = "ldc=blockentities")) + private boolean doNothing(Profiler profiler, String location) { + if (!((WorldRendererExtended) this).getSodiumWorldRenderer().getUseEntityCulling()) { + return true; } + profiler.swap("turn off entity culling for blockentities"); + profiler.pop(); + return false; } -} + @WrapWithCondition(method = "render", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", args = "ldc=destroyProgress")) + private boolean doNothing2(Profiler profiler, String location) { + if (!((WorldRendererExtended) this).getSodiumWorldRenderer().getUseEntityCulling()) { + return true; + } + profiler.push(location); + return false; + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/accessor/WorldRendererAccessor.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/accessor/WorldRendererAccessor.java new file mode 100644 index 000000000..be7fb2208 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/entity/smooth_lighting/accessor/WorldRendererAccessor.java @@ -0,0 +1,14 @@ +package me.jellysquid.mods.sodium.mixin.features.entity.smooth_lighting.accessor; + +import net.minecraft.client.render.WorldRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(WorldRenderer.class) +public interface WorldRendererAccessor { + @Accessor + int getRegularEntityCount(); + + @Accessor + void setRegularEntityCount(int regularEntityCount); +} diff --git a/src/main/resources/assets/sodium/lang/en_us.json b/src/main/resources/assets/sodium/lang/en_us.json index a6b497efd..9df85be7b 100644 --- a/src/main/resources/assets/sodium/lang/en_us.json +++ b/src/main/resources/assets/sodium/lang/en_us.json @@ -3,7 +3,7 @@ "speedrunapi.config.sodium.category.advanced": "Advanced", "speedrunapi.config.sodium.category.speedrun": "Speedrun", "speedrunapi.config.sodium.option.quality:enableVignette": "Vignette", - "speedrunapi.config.sodium.option.quality:enableVignette.description": "If enabled, a vignette effect will be rendered on the player's view. This is very unlikely to make a difference to frame rates unless you are fill-rate limited.", + "speedrunapi.config.sodium.option.quality:enableVignette.description": "If disabled, the vignette effect will not be rendered on Fancy graphics. This is very unlikely to make a difference to frame rates unless you are fill-rate limited.", "speedrunapi.config.sodium.option.advanced:initialChunkThreads": "Initial Chunk Threads", "speedrunapi.config.sodium.option.advanced:initialChunkThreads.description": "How many chunk building threads to create instantly when reloading (lower = less F3 + F lag). Cannot be more than Target Chunk Threads.", "speedrunapi.config.sodium.option.advanced:initialChunkThreads.value.0": "Auto", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index eb9a51b8a..f96b98efa 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "sodium", "version": "${version}", "name": "Sodium", - "description": "Sodium is a free and open-source optimization mod for Minecraft which improves frame rates and reduces lag spikes. \nThis is an unofficial backport of JellySquid's original mod.", + "description": "Sodium is a free and open-source optimization mod for Minecraft which improves frame rates and reduces lag spikes. This is an unofficial backport of JellySquid's original mod.", "authors": [ { "name": "jellysquid3", diff --git a/src/main/resources/sodium.mixins.json b/src/main/resources/sodium.mixins.json index 39ffb146c..e56081021 100644 --- a/src/main/resources/sodium.mixins.json +++ b/src/main/resources/sodium.mixins.json @@ -42,6 +42,7 @@ "features.entity.smooth_lighting.MixinEntityRenderer", "features.entity.smooth_lighting.MixinPaintingEntityRenderer", "features.entity.smooth_lighting.MixinWorldRenderer", + "features.entity.smooth_lighting.accessor.WorldRendererAccessor", "features.gui.MixinDebugHud", "features.gui.fast_loading_screen.MixinLevelLoadingScreen", "features.gui.font.MixinGlyphRenderer",