Skip to content
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class ChunkRenderManager<T extends ChunkGraphicsState> 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
Expand Down Expand Up @@ -97,6 +97,10 @@ public class ChunkRenderManager<T extends ChunkGraphicsState> 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<T> backend, BlockRenderPassManager renderPassManager, ClientWorld world, int renderDistance) {
this.backend = backend;
this.renderer = renderer;
Expand Down Expand Up @@ -160,9 +164,12 @@ private void iterateChunks(Camera camera, FrustumExtended frustum, int frame, bo
}

private void addChunk(ChunkRenderContainer<T> 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);
}
Expand All @@ -178,7 +185,7 @@ private void addChunk(ChunkRenderContainer<T> render) {
}
}

if (!render.isEmpty()) {
if (!render.isEmpty() && !enqueued) {
this.addChunkToRenderLists(render);
this.addEntitiesToRenderLists(render);
}
Expand Down Expand Up @@ -399,7 +406,7 @@ private ChunkRenderContainer<T> createChunkRender(ChunkRenderColumn<T> 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));
Expand Down Expand Up @@ -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<T> 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<CompletableFuture<ChunkBuildResult<T>>> futures = new ArrayDeque<>();
Deque<ChunkRenderContainer<T>> containers = new ArrayDeque<>();

int budget = this.builder.getSchedulingBudget();
int submitted = 0;

while (!this.importantRebuildQueue.isEmpty()) {
Expand All @@ -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<T> 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
Expand All @@ -467,7 +487,13 @@ public void updateChunks() {
this.backend.upload(RenderDevice.INSTANCE.createCommandList(), new FutureDequeDrain<>(futures));
}

this.builder.createMoreThreads();
while (!containers.isEmpty()) {
ChunkRenderContainer<T> render = containers.poll();
if (!render.isEmpty()) {
this.addChunkToRenderLists(render);
this.addEntitiesToRenderLists(render);
}
}
}

public void markDirty() {
Expand All @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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.
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -31,13 +33,15 @@ private void preGetLight(T entity, float tickDelta, CallbackInfoReturnable<Integ
}
}

@Inject(method = "shouldRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Frustum;isVisible(Lnet/minecraft/util/math/Box;)Z", shift = At.Shift.AFTER), cancellable = true)
private void preShouldRender(T entity, Frustum frustum, double x, double y, double z, CallbackInfoReturnable<Boolean> 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 1 addition & 1 deletion src/main/resources/assets/sodium/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/sodium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading