diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml deleted file mode 100644 index 30577674d7..0000000000 --- a/.github/workflows/build-release.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This workflow will build a Java project with Brachyra -# For more information see: docs/development/brachyura.md - -name: Release script - -on: - release: - types: - - published - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 21 - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - with: - cache-read-only: false - - - name: Run build with Gradle Wrapper - run: ./gradlew build -Dbuild.release=true - - - name: Upload artifacts to Modrinth and GitHub - uses: Kir-Antipov/mc-publish@v3.3 - with: - modrinth-id: YL57xq9U - modrinth-token: ${{ secrets.MODRINTH_TOKEN }} - modrinth-featured: true - - curseforge-id: 455508 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - - github-token: ${{ secrets.GITHUB_TOKEN }} - - files: build/libs/!(*-@(dev|sources|all)).jar - - version-type: release - - loaders: fabric quilt - - dependencies: sodium - - version-resolver: latest # Defaults to selecting the latest compatible version of Minecraft, using the tag from the fabric.mod.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 713c9b7ec9..0000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,32 +0,0 @@ -# This workflow will build a Java project with Brachyra -# For more information see: docs/development/brachyura.md - -name: Java CI with Gradle - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 21 - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - with: - cache-read-only: false - - - name: Run build with Gradle Wrapper - run: ./gradlew build - - - name: Upload built JAR (Fabric) - uses: actions/upload-artifact@v3 - with: - name: iris-artifacts - path: build/libs diff --git a/common/build.gradle.kts b/common/build.gradle.kts index f16e9c40d0..1143b2f148 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -59,7 +59,10 @@ dependencies { modCompileOnly("net.fabricmc.fabric-api:fabric-renderer-api-v1:3.2.9+1172e897d7") - modImplementation("maven.modrinth", "sodium", "mc1.21.4-0.6.2-fabric") + // modImplementation("maven.modrinth", "sodium", "mc1.21-0.6.0-beta.2-fabric") + modImplementation("net.caffeinemc", "fabric", "0.6.6-snapshot+mc1.21.4-local") { + isChanging = true + } modCompileOnly("org.antlr:antlr4-runtime:4.13.1") modCompileOnly("io.github.douira:glsl-transformer:2.0.1") modCompileOnly("org.anarres:jcpp:1.4.14") diff --git a/common/src/main/java/net/irisshaders/iris/compat/dh/mixin/MixinAdvancedShadowCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/compat/dh/mixin/MixinAdvancedShadowCullingFrustum.java index 8d612f839b..a09df069e0 100644 --- a/common/src/main/java/net/irisshaders/iris/compat/dh/mixin/MixinAdvancedShadowCullingFrustum.java +++ b/common/src/main/java/net/irisshaders/iris/compat/dh/mixin/MixinAdvancedShadowCullingFrustum.java @@ -21,7 +21,7 @@ public MixinAdvancedShadowCullingFrustum(Matrix4f matrix4f, Matrix4f matrix4f2) } @Shadow(remap = false) - protected int isVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { + protected boolean isVisibleBool(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { throw new IllegalStateException(); } @@ -33,6 +33,6 @@ public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewP @Override public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) { - return this.isVisible(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth) != 0; + return this.isVisibleBool(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth); } } diff --git a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderRegion.java b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderRegion.java new file mode 100644 index 0000000000..2140c80b69 --- /dev/null +++ b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderRegion.java @@ -0,0 +1,47 @@ +package net.irisshaders.iris.compat.sodium.mixin; + +import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderList; +import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion; +import net.irisshaders.iris.compat.sodium.mixinterface.ShadowRenderRegion; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(RenderRegion.class) +public class MixinRenderRegion implements ShadowRenderRegion { + @Final + @Shadow + @Mutable + private ChunkRenderList renderList; + + @Unique + ChunkRenderList regularRenderList; + + @Unique + ChunkRenderList shadowRenderList; + + @Unique + @Override + public void swapToShadowRenderList() { + this.regularRenderList = this.renderList; + this.renderList = this.shadowRenderList; + this.ensureRenderList(); + } + + @Unique + @Override + public void swapToRegularRenderList() { + this.shadowRenderList = this.renderList; + this.renderList = this.regularRenderList; + this.ensureRenderList(); + } + + @Unique + private void ensureRenderList() { + if (this.renderList == null) { + this.renderList = new ChunkRenderList((RenderRegion) (Object) this); + } + } +} diff --git a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderSectionManagerShadow.java b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderSectionManagerShadow.java index 64abada476..4a45bb9f85 100644 --- a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderSectionManagerShadow.java +++ b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinRenderSectionManagerShadow.java @@ -1,16 +1,20 @@ package net.irisshaders.iris.compat.sodium.mixin; -import net.caffeinemc.mods.sodium.client.gl.device.CommandList; -import net.caffeinemc.mods.sodium.client.render.chunk.ChunkUpdateType; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.caffeinemc.mods.sodium.client.render.chunk.RenderSection; import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager; +import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionInfo; import net.caffeinemc.mods.sodium.client.render.chunk.lists.SortedRenderLists; +import net.caffeinemc.mods.sodium.client.render.chunk.lists.VisibleChunkCollectorAsync; +import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegionManager; +import net.caffeinemc.mods.sodium.client.render.chunk.tree.RemovableMultiForest; import net.caffeinemc.mods.sodium.client.render.viewport.Viewport; +import net.irisshaders.iris.compat.sodium.mixinterface.ShadowRenderRegion; import net.irisshaders.iris.shadows.ShadowRenderingState; import net.minecraft.client.Camera; -import net.minecraft.client.multiplayer.ClientLevel; import org.jetbrains.annotations.NotNull; -import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -18,88 +22,116 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.ArrayDeque; -import java.util.EnumMap; -import java.util.Map; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(RenderSectionManager.class) -public class MixinRenderSectionManagerShadow { +public abstract class MixinRenderSectionManagerShadow { @Shadow(remap = false) private @NotNull SortedRenderLists renderLists; + @Shadow(remap = false) - private @NotNull Map> taskLists; + private boolean needsRenderListUpdate; + @Shadow - private int lastUpdatedFrame; + @Final + private RenderRegionManager regions; + @Shadow + private int frame; + @Unique private @NotNull SortedRenderLists shadowRenderLists = SortedRenderLists.empty(); + + @Unique + private boolean shadowNeedsRenderListUpdate = true; + @Unique - private @NotNull Map> shadowTaskLists = new EnumMap<>(ChunkUpdateType.class); - private int lastUpdatedFrameShadow; - - @Inject(method = "", at = @At("TAIL")) - private void create(ClientLevel level, int renderDistance, CommandList commandList, CallbackInfo ci) { - for (int var6 = 0; var6 < ChunkUpdateType.values().length; ++var6) { - ChunkUpdateType type = ChunkUpdateType.values()[var6]; - shadowTaskLists.put(type, new ArrayDeque<>()); + private boolean renderListStateIsShadow = false; + + @WrapOperation(method = "notifyChangedCamera", at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;cameraChanged:Z")) + private void notifyChangedCamera(RenderSectionManager instance, boolean value, Operation original) { + if (!ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { + original.call(instance, value); + return; } + + this.shadowNeedsRenderListUpdate = true; } - @Redirect(remap = false, method = "createTerrainRenderList", at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;renderLists:Lnet/caffeinemc/mods/sodium/client/render/chunk/lists/SortedRenderLists;")) - private void useShadowRenderList(RenderSectionManager instance, SortedRenderLists value) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { - shadowRenderLists = value; - } else { - renderLists = value; - } + @Inject(method = "updateRenderLists", at = @At(target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/occlusion/AsyncCameraTimingControl;getShouldRenderSync(Lnet/minecraft/client/Camera;)Z", value = "INVOKE")) + private void updateRenderLists(Camera camera, Viewport viewport, boolean spectator, boolean updateImmediately, CallbackInfo ci) { + this.shadowNeedsRenderListUpdate |= this.needsRenderListUpdate; } - @Redirect(remap = false, method = "createTerrainRenderList", at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;taskLists:Ljava/util/Map;")) - private void useShadowTaskrList(RenderSectionManager instance, @NotNull Map> value) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { - shadowTaskLists = value; - } else { - taskLists = value; + @Shadow(remap = false) + public abstract int getVisibleChunkCount(); + + @Shadow(remap = false) + public abstract int getTotalSections(); + + @Shadow + @Final + private RemovableMultiForest renderableSectionTree; + + @Shadow + protected abstract float getSearchDistance(); + + @Inject(method = "updateRenderLists", at = @At("HEAD"), cancellable = true) + private void updateShadowRenderLists(Camera camera, Viewport viewport, boolean spectator, boolean updateImmediately, CallbackInfo ci) { + if (!ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { + if (this.renderListStateIsShadow) { + for (var region : this.regions.getLoadedRegions()) { + ((ShadowRenderRegion) region).swapToRegularRenderList(); + } + this.renderListStateIsShadow = false; + } + return; } - } - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;createTerrainRenderList(Lnet/minecraft/client/Camera;Lnet/caffeinemc/mods/sodium/client/render/viewport/Viewport;IZ)V", shift = At.Shift.AFTER), cancellable = true) - private void cancelIfShadow(Camera camera, Viewport viewport, boolean spectator, CallbackInfo ci) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) ci.cancel(); - } + if (this.shadowNeedsRenderListUpdate) { + if (!this.renderListStateIsShadow) { + for (var region : this.regions.getLoadedRegions()) { + ((ShadowRenderRegion) region).swapToShadowRenderList(); + } + this.renderListStateIsShadow = true; + } - @Redirect(method = { - "getRenderLists", - "getVisibleChunkCount", - "renderLayer" - }, at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;renderLists:Lnet/caffeinemc/mods/sodium/client/render/chunk/lists/SortedRenderLists;"), remap = false) - private SortedRenderLists useShadowRenderList2(RenderSectionManager instance) { - return ShadowRenderingState.areShadowsCurrentlyBeingRendered() ? shadowRenderLists : renderLists; - } + var visibleCollector = new VisibleChunkCollectorAsync(this.regions, -this.frame); + this.renderableSectionTree.prepareForTraversal(); + this.renderableSectionTree.traverse(visibleCollector, viewport, this.getSearchDistance()); + this.shadowRenderLists = visibleCollector.createRenderLists(viewport); + } - @Inject(method = "updateChunks", at = @At("HEAD"), cancellable = true, remap = false) - private void doNotUpdateDuringShadow(boolean updateImmediately, CallbackInfo ci) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) ci.cancel(); + this.shadowNeedsRenderListUpdate = false; + ci.cancel(); } - @Inject(method = "uploadChunks", at = @At("HEAD"), cancellable = true, remap = false) - private void doNotUploadDuringShadow(CallbackInfo ci) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) ci.cancel(); + @Inject(method = "updateSectionInfo", at = @At("HEAD")) + private void updateSectionInfo(RenderSection render, BuiltSectionInfo info, CallbackInfoReturnable cir) { + this.shadowNeedsRenderListUpdate = true; } - @Redirect(method = { - "resetRenderLists", - "submitSectionTasks(Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/executor/ChunkJobCollector;Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/executor/ChunkJobCollector;Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/executor/ChunkJobCollector;)V" - }, at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;taskLists:Ljava/util/Map;"), remap = false) - private @NotNull Map> useShadowTaskList3(RenderSectionManager instance) { - return ShadowRenderingState.areShadowsCurrentlyBeingRendered() ? shadowTaskLists : taskLists; + @Inject(method = "onSectionRemoved", at = @At("HEAD")) + private void onSectionRemoved(int x, int y, int z, CallbackInfo ci) { + this.shadowNeedsRenderListUpdate = true; } @Redirect(method = { - "resetRenderLists" + "getRenderLists", + "getVisibleChunkCount", + "renderLayer" }, at = @At(value = "FIELD", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;renderLists:Lnet/caffeinemc/mods/sodium/client/render/chunk/lists/SortedRenderLists;"), remap = false) - private void useShadowRenderList3(RenderSectionManager instance, SortedRenderLists value) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) shadowRenderLists = value; - else renderLists = value; + private SortedRenderLists useShadowRenderList(RenderSectionManager instance) { + return ShadowRenderingState.areShadowsCurrentlyBeingRendered() ? this.shadowRenderLists : this.renderLists; + } + + @Inject(method = "getChunksDebugString", at = @At("HEAD"), cancellable = true) + private void getShadowChunksDebugString(CallbackInfoReturnable cir) { + if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { + var renderLists = this.renderLists; + this.renderLists = this.shadowRenderLists; + cir.setReturnValue(String.format("C: %d/%d", this.getVisibleChunkCount(), this.getTotalSections())); + this.renderLists = renderLists; + cir.cancel(); + } } } diff --git a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinSodiumWorldRenderer.java b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinSodiumWorldRenderer.java index 6cf49595c2..24dc710116 100644 --- a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinSodiumWorldRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinSodiumWorldRenderer.java @@ -5,9 +5,11 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer; import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager; +import net.caffeinemc.mods.sodium.client.render.viewport.Viewport; import net.irisshaders.iris.mixin.LevelRendererAccessor; import net.irisshaders.iris.shadows.ShadowRenderingState; import net.irisshaders.iris.uniforms.CapturedRenderingState; +import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; @@ -16,16 +18,18 @@ import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.level.block.entity.BlockEntity; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.SortedSet; @Mixin(SodiumWorldRenderer.class) public class MixinSodiumWorldRenderer { + @Shadow + private RenderSectionManager renderSectionManager; @Unique private static boolean renderLightsOnly = false; @Unique @@ -58,32 +62,18 @@ private static void checkRenderShadow(PoseStack matrices, RenderBuffers bufferBu } } - @Redirect(method = "setupTerrain", remap = false, - at = @At(value = "INVOKE", - target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;needsUpdate()Z", ordinal = 0, - remap = false)) - private boolean iris$forceChunkGraphRebuildInShadowPass(RenderSectionManager instance) { + @Inject(method = "setupTerrain", at = @At("HEAD"), cancellable = true) + private void setupShadowTerrain(Camera camera, Viewport viewport, boolean spectator, boolean updateChunksImmediately, CallbackInfo ci) { if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { float sunAngle = Minecraft.getInstance().level.getSunAngle(CapturedRenderingState.INSTANCE.getTickDelta()); - if (lastSunAngle != sunAngle) { - lastSunAngle = sunAngle; - return true; + if (this.lastSunAngle != sunAngle) { + this.lastSunAngle = sunAngle; + this.renderSectionManager.notifyChangedCamera(); } - } - return instance.needsUpdate(); - } + this.renderSectionManager.updateRenderLists(camera, viewport, spectator, updateChunksImmediately); - @Redirect(method = "setupTerrain", remap = false, - at = @At(value = "INVOKE", - target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager;needsUpdate()Z", ordinal = 1, - remap = false)) - private boolean iris$forceEndGraphRebuild(RenderSectionManager instance) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { - // TODO: Detect when the sun/moon isn't moving - return false; - } else { - return instance.needsUpdate(); + ci.cancel(); } } } diff --git a/common/src/main/java/net/irisshaders/iris/compat/sodium/mixinterface/ShadowRenderRegion.java b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixinterface/ShadowRenderRegion.java new file mode 100644 index 0000000000..8ea0489cbd --- /dev/null +++ b/common/src/main/java/net/irisshaders/iris/compat/sodium/mixinterface/ShadowRenderRegion.java @@ -0,0 +1,7 @@ +package net.irisshaders.iris.compat.sodium.mixinterface; + +public interface ShadowRenderRegion { + void swapToShadowRenderList(); + + void swapToRegularRenderList(); +} diff --git a/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderSection.java b/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderSection.java deleted file mode 100644 index 9207fc91f1..0000000000 --- a/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderSection.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.irisshaders.iris.mixin; - -import net.caffeinemc.mods.sodium.client.render.chunk.RenderSection; -import net.irisshaders.iris.shadows.ShadowRenderingState; -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.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(remap = false, value = RenderSection.class) -public class MixinRenderSection { - @Unique - private int lastVisibleFrameShadow; - - @Inject(method = "setLastVisibleFrame", at = @At("HEAD"), cancellable = true) - private void setLastVisibleFrameShadow(int i, CallbackInfo ci) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { - ci.cancel(); - lastVisibleFrameShadow = i; - } - } - - @Inject(method = "getLastVisibleFrame", at = @At("HEAD"), cancellable = true) - private void getLastVisibleFrameShadow(CallbackInfoReturnable cir) { - if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { - cir.setReturnValue(lastVisibleFrameShadow); - } - } -} diff --git a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShaderProperties.java b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShaderProperties.java index 2efec5d5e5..b63b1de3bd 100644 --- a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShaderProperties.java +++ b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShaderProperties.java @@ -178,7 +178,7 @@ public ShaderProperties(String contents, ShaderPackOptions shaderPackOptions, It switch (value) { case "false" -> shadowCulling = ShadowCullState.DISTANCE; case "true" -> shadowCulling = ShadowCullState.ADVANCED; - case "reversed" -> shadowCulling = ShadowCullState.REVERSED; + case "reversed", "safe_zone" -> shadowCulling = ShadowCullState.ADVANCED_SAFE_ZONE; case null, default -> Iris.logger.error("Unrecognized shadow culling setting: " + value); } } diff --git a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShadowCullState.java b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShadowCullState.java index 5870ea4169..ef55bbef1f 100644 --- a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShadowCullState.java +++ b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/ShadowCullState.java @@ -3,6 +3,6 @@ public enum ShadowCullState { DEFAULT, ADVANCED, - REVERSED, + ADVANCED_SAFE_ZONE, DISTANCE } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java index de8925a999..8c9183075e 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer; import net.irisshaders.batchedentityrendering.impl.BatchingDebugMessageHelper; import net.irisshaders.batchedentityrendering.impl.DrawCallTrackingRenderBuffers; import net.irisshaders.batchedentityrendering.impl.FullyBufferedMultiBufferSource; @@ -24,7 +25,7 @@ import net.irisshaders.iris.shadows.frustum.CullEverythingFrustum; import net.irisshaders.iris.shadows.frustum.FrustumHolder; import net.irisshaders.iris.shadows.frustum.advanced.AdvancedShadowCullingFrustum; -import net.irisshaders.iris.shadows.frustum.advanced.ReversedAdvancedShadowCullingFrustum; +import net.irisshaders.iris.shadows.frustum.advanced.SafeZoneAdvancedShadowCullingFrustum; import net.irisshaders.iris.shadows.frustum.fallback.BoxCullingFrustum; import net.irisshaders.iris.shadows.frustum.fallback.NonCullingFrustum; import net.irisshaders.iris.uniforms.CameraUniforms; @@ -304,12 +305,12 @@ private FrustumHolder createShadowFrustum(float renderMultiplier, FrustumHolder } else { BoxCuller boxCuller; - boolean isReversed = packCullingState == ShadowCullState.REVERSED; + boolean hasSafeZone = packCullingState == ShadowCullState.ADVANCED_SAFE_ZONE; // Assume render multiplier is meant to be 1 if reversed culling is on - if (isReversed && renderMultiplier < 0) renderMultiplier = 1.0f; + if (hasSafeZone && renderMultiplier < 0) renderMultiplier = 1.0f; - double distance = (isReversed ? voxelDistance : halfPlaneLength) * renderMultiplier; + double distance = (hasSafeZone ? voxelDistance : halfPlaneLength) * renderMultiplier; String setter = "(set by shader pack)"; if (renderMultiplier < 0) { @@ -317,7 +318,7 @@ private FrustumHolder createShadowFrustum(float renderMultiplier, FrustumHolder setter = "(set by user)"; } - if (distance >= Minecraft.getInstance().options.getEffectiveRenderDistance() * 16 && !isReversed) { + if (distance >= Minecraft.getInstance().options.getEffectiveRenderDistance() * 16 && !hasSafeZone) { distanceInfo = "render distance = " + Minecraft.getInstance().options.getEffectiveRenderDistance() * 16 + " blocks "; distanceInfo += Minecraft.getInstance().isLocalServer() ? "(capped by normal render distance)" : "(capped by normal/server render distance)"; @@ -325,7 +326,7 @@ private FrustumHolder createShadowFrustum(float renderMultiplier, FrustumHolder } else { distanceInfo = distance + " blocks " + setter; - if (distance == 0.0 && !isReversed) { + if (distance == 0.0 && !hasSafeZone) { cullingInfo = "no shadows rendered"; holder.setInfo(new CullEverythingFrustum(), distanceInfo, cullingInfo); } @@ -333,7 +334,7 @@ private FrustumHolder createShadowFrustum(float renderMultiplier, FrustumHolder boxCuller = new BoxCuller(distance); } - cullingInfo = (isReversed ? "Reversed" : "Advanced") + " Frustum Culling enabled"; + cullingInfo = (hasSafeZone ? "Reversed" : "Advanced") + " Frustum Culling enabled"; Vector4f shadowLightPosition = new CelestialUniforms(sunPathRotation).getShadowLightPositionInWorldSpace(); @@ -345,8 +346,8 @@ private FrustumHolder createShadowFrustum(float renderMultiplier, FrustumHolder Matrix4f projView = ((shouldRenderDH && DHCompat.hasRenderingEnabled()) ? DHCompat.getProjection() : CapturedRenderingState.INSTANCE.getGbufferProjection()) .mul(CapturedRenderingState.INSTANCE.getGbufferModelView(), new Matrix4f()); - if (isReversed) { - return holder.setInfo(new ReversedAdvancedShadowCullingFrustum(projView, PROJECTION, shadowLightVectorFromOrigin, boxCuller, new BoxCuller(halfPlaneLength * renderMultiplier)), distanceInfo, cullingInfo); + if (hasSafeZone) { + return holder.setInfo(new SafeZoneAdvancedShadowCullingFrustum(projView, PROJECTION, shadowLightVectorFromOrigin, boxCuller, new BoxCuller(halfPlaneLength * renderMultiplier)), distanceInfo, cullingInfo); } else { return holder.setInfo(new AdvancedShadowCullingFrustum(projView, PROJECTION, shadowLightVectorFromOrigin, boxCuller), distanceInfo, cullingInfo); } @@ -439,22 +440,11 @@ public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCame boolean wasChunkCullingEnabled = client.smartCull; client.smartCull = false; - // Always schedule a terrain update - // TODO: Only schedule a terrain update if the sun / moon is moving, or the shadow map camera moved. - // We have to ensure that we don't regenerate clouds every frame, since that's what needsUpdate ends up doing. - // This took up to 10% of the frame time before we applied this fix! That's really bad! - - // TODO IMS 24w35a determine clouds - ((LevelRenderer) levelRenderer).needsUpdate(); + // forcing a terrain update it not necessary here, sodium figured it out on its own // Execute the vanilla terrain setup / culling routines using our shadow frustum. levelRenderer.invokeSetupRender(playerCamera, terrainFrustumHolder.getFrustum(), false, false); - // Don't forget to increment the frame counter! This variable is arbitrary and only used in terrain setup, - // and if it's not incremented, the vanilla culling code will get confused and think that it's already seen - // chunks during traversal, and break rendering in concerning ways. - //worldRenderer.setFrameId(worldRenderer.getFrameId() + 1); - client.smartCull = wasChunkCullingEnabled; profiler.popPush("terrain"); @@ -560,7 +550,7 @@ public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCame IrisRenderSystem.restorePlayerProjection(); - debugStringTerrain = ((LevelRenderer) levelRenderer).getSectionStatistics(); + debugStringTerrain = SodiumWorldRenderer.instance().getChunksDebugString(); profiler.popPush("generate mipmaps"); diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/BoxCuller.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/BoxCuller.java index ae61ef5ad2..926bf12cef 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/BoxCuller.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/BoxCuller.java @@ -1,6 +1,7 @@ package net.irisshaders.iris.shadows.frustum; import net.minecraft.world.phys.AABB; +import org.joml.FrustumIntersection; public class BoxCuller { private final double maxDistance; @@ -54,6 +55,28 @@ public boolean isCulledSodium(double minX, double minY, double minZ, double maxX return maxZ < -this.maxDistance || minZ > this.maxDistance; } + public int intersectAab(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { + if (maxX < -this.maxDistance || minX > this.maxDistance) { + return FrustumIntersection.OUTSIDE; + } + + if (maxY < -this.maxDistance || minY > this.maxDistance) { + return FrustumIntersection.OUTSIDE; + } + + if (maxZ < -this.maxDistance || minZ > this.maxDistance) { + return FrustumIntersection.OUTSIDE; + } + + if (minX >= -this.maxDistance && maxX <= this.maxDistance && + minY >= -this.maxDistance && maxY <= this.maxDistance && + minZ >= -this.maxDistance && maxZ <= this.maxDistance) { + return FrustumIntersection.INSIDE; + } + + return FrustumIntersection.INTERSECT; + } + @Override public String toString() { return "Box Culling active; max distance " + maxDistance; diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/CullEverythingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/CullEverythingFrustum.java index ea3f589941..810a76f177 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/CullEverythingFrustum.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/CullEverythingFrustum.java @@ -4,6 +4,7 @@ import net.caffeinemc.mods.sodium.client.render.viewport.ViewportProvider; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.world.phys.AABB; +import org.joml.FrustumIntersection; import org.joml.Matrix4f; import org.joml.Vector3d; @@ -38,4 +39,9 @@ public void prepare(double d, double e, double f) { public boolean testAab(float v, float v1, float v2, float v3, float v4, float v5) { return false; } + + @Override + public int intersectAab(float v, float v1, float v2, float v3, float v4, float v5) { + return FrustumIntersection.OUTSIDE; + } } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/AdvancedShadowCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/AdvancedShadowCullingFrustum.java index d810cd2919..0f2dd6e4ea 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/AdvancedShadowCullingFrustum.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/AdvancedShadowCullingFrustum.java @@ -7,6 +7,8 @@ import net.irisshaders.iris.shadows.frustum.BoxCuller; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.world.phys.AABB; +import org.jetbrains.annotations.Nullable; +import org.joml.FrustumIntersection; import org.joml.Matrix4fc; import org.joml.Vector3d; import org.joml.Vector3f; @@ -36,7 +38,7 @@ */ public class AdvancedShadowCullingFrustum extends Frustum implements net.caffeinemc.mods.sodium.client.render.viewport.frustum.Frustum, ViewportProvider { private static final int MAX_CLIPPING_PLANES = 13; - protected final BoxCuller boxCuller; + protected final @Nullable BoxCuller boxCuller; /** * We store each plane equation as a Vector4f. * @@ -75,7 +77,7 @@ public class AdvancedShadowCullingFrustum extends Frustum implements net.caffein private int planeCount = 0; public AdvancedShadowCullingFrustum(Matrix4fc modelViewProjection, Matrix4fc shadowProjection, Vector3f shadowLightVectorFromOrigin, - BoxCuller boxCuller) { + @Nullable BoxCuller boxCuller) { // We're overriding all of the methods, don't pass any matrices down. super(new org.joml.Matrix4f(), new org.joml.Matrix4f()); @@ -290,37 +292,8 @@ public void prepare(double cameraX, double cameraY, double cameraZ) { } @Override - public boolean isVisible(AABB aabb) { - if (boxCuller != null && boxCuller.isCulled(aabb)) { - return false; - } - - return this.isVisible(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ) != 0; - } - - // For Sodium - public int fastAabbTest(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - if (boxCuller != null && boxCuller.isCulled(minX, minY, minZ, maxX, maxY, maxZ)) { - return 0; - } - - return isVisible(minX, minY, minZ, maxX, maxY, maxZ); - } - - // For Immersive Portals - // TODO: Figure out if IP culling can somehow be compatible with Iris culling. - public boolean canDetermineInvisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { - return false; - } - - protected int isVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { - float f = (float) (minX - this.x); - float g = (float) (minY - this.y); - float h = (float) (minZ - this.z); - float i = (float) (maxX - this.x); - float j = (float) (maxY - this.y); - float k = (float) (maxZ - this.z); - return this.checkCornerVisibility(f, g, h, i, j, k); + public Viewport sodium$createViewport() { + return new Viewport(this, this.position.set(this.x, this.y, this.z)); } private static final boolean FMA_SUPPORT; @@ -351,12 +324,12 @@ private static float safeFMA(float a, float b, float c) { * @param maxX Maximum X value of the AABB. * @param maxY Maximum Y value of the AABB. * @param maxZ Maximum Z value of the AABB. - * @return 0 if nothing is visible, 1 if everything is visible, 2 if only some corners are visible. + * @return OUTSIDE if nothing is visible, INSIDE if everything is visible, INTERSECT if only some corners are visible. */ protected int checkCornerVisibility(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { boolean inside = true; - for (int i = 0; i < planeCount; ++i) { + for (int i = 0; i < this.planeCount; ++i) { float[] plane = this.planes[i]; // Check if plane is inside or intersecting. @@ -366,14 +339,13 @@ protected int checkCornerVisibility(float minX, float minY, float minZ, float ma float outsideBoundY = (plane[1] < 0) ? minY : maxY; float outsideBoundZ = (plane[2] < 0) ? minZ : maxZ; - // Use Math.fma for the dot product calculation to get vectorization (sorry old Intel users) if (FMA_SUPPORT) { if (Math.fma(plane[0], outsideBoundX, Math.fma(plane[1], outsideBoundY, plane[2] * outsideBoundZ)) >= -plane[3]) { inside &= Math.fma(plane[0], (plane[0] < 0 ? maxX : minX), Math.fma(plane[1], (plane[1] < 0 ? maxY : minY), Math.fma(plane[2], (plane[2] < 0 ? maxZ : minZ), plane[3]))) >= 0; } else { - return 0; + return FrustumIntersection.OUTSIDE; } } else { if (safeFMA(plane[0], outsideBoundX, safeFMA(plane[1], outsideBoundY, plane[2] * outsideBoundZ)) >= -plane[3]) { @@ -381,12 +353,12 @@ protected int checkCornerVisibility(float minX, float minY, float minZ, float ma safeFMA(plane[1], (plane[1] < 0 ? maxY : minY), safeFMA(plane[2], (plane[2] < 0 ? maxZ : minZ), plane[3]))) >= 0; } else { - return 0; + return FrustumIntersection.OUTSIDE; } } } - return inside ? 1 : 2; + return inside ? FrustumIntersection.INSIDE : FrustumIntersection.INTERSECT; } /** @@ -401,28 +373,78 @@ protected int checkCornerVisibility(float minX, float minY, float minZ, float ma * @return true if visible, false if not. */ public boolean checkCornerVisibilityBool(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - for (int i = 0; i < planeCount; ++i) { - float[] plane = planes[i]; + for (int i = 0; i < this.planeCount; ++i) { + float[] plane = this.planes[i]; float outsideBoundX = (plane[0] < 0) ? minX : maxX; float outsideBoundY = (plane[1] < 0) ? minY : maxY; float outsideBoundZ = (plane[2] < 0) ? minZ : maxZ; - if (Math.fma(plane[0], outsideBoundX, Math.fma(plane[1], outsideBoundY, plane[2] * outsideBoundZ)) < -plane[3]) { - return false; + if (FMA_SUPPORT) { + if (Math.fma(plane[0], outsideBoundX, Math.fma(plane[1], outsideBoundY, plane[2] * outsideBoundZ)) < -plane[3]) { + return false; + } + } else { + if (safeFMA(plane[0], outsideBoundX, safeFMA(plane[1], outsideBoundY, plane[2] * outsideBoundZ)) < -plane[3]) { + return false; + } } } return true; } + // For Immersive Portals + // TODO: Figure out if IP culling can somehow be compatible with Iris culling. + public boolean canDetermineInvisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { + return false; + } + + protected boolean isVisibleBool(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { + return this.checkCornerVisibilityBool( + (float) (minX - this.x), + (float) (minY - this.y), + (float) (minZ - this.z), + (float) (maxX - this.x), + (float) (maxY - this.y), + (float) (maxZ - this.z)); + } + + @Override + public boolean isVisible(AABB aabb) { + if (this.boxCuller != null && this.boxCuller.isCulled(aabb)) { + return false; + } + + return this.isVisibleBool(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ); + } + @Override public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - return (boxCuller == null || !boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) && this.checkCornerVisibility(minX, minY, minZ, maxX, maxY, maxZ) > 0; + return (this.boxCuller == null || !this.boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) && + this.checkCornerVisibilityBool(minX, minY, minZ, maxX, maxY, maxZ); } @Override - public Viewport sodium$createViewport() { - return new Viewport(this, position.set(x, y, z)); + public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { + if (this.boxCuller == null) { + return this.checkCornerVisibility(minX, minY, minZ, maxX, maxY, maxZ); + } + + var distanceResult = this.boxCuller.intersectAab(minX, minY, minZ, maxX, maxY, maxZ); + if (distanceResult == FrustumIntersection.OUTSIDE) { + return FrustumIntersection.OUTSIDE; + } + + var frustumResult = this.checkCornerVisibility(minX, minY, minZ, maxX, maxY, maxZ); + if (frustumResult == FrustumIntersection.OUTSIDE) { + return FrustumIntersection.OUTSIDE; + } + + if (frustumResult == FrustumIntersection.INSIDE && distanceResult == FrustumIntersection.INSIDE) { + return FrustumIntersection.INSIDE; + } + + return FrustumIntersection.INTERSECT; } } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/ReversedAdvancedShadowCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/ReversedAdvancedShadowCullingFrustum.java deleted file mode 100644 index 2b4907d362..0000000000 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/ReversedAdvancedShadowCullingFrustum.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.irisshaders.iris.shadows.frustum.advanced; - -import net.caffeinemc.mods.sodium.client.render.viewport.frustum.Frustum; -import net.irisshaders.iris.shadows.frustum.BoxCuller; -import net.minecraft.world.phys.AABB; -import org.joml.Matrix4fc; -import org.joml.Vector3f; - -public class ReversedAdvancedShadowCullingFrustum extends AdvancedShadowCullingFrustum implements Frustum { - private final BoxCuller distanceCuller; - - public ReversedAdvancedShadowCullingFrustum(Matrix4fc modelViewProjection, Matrix4fc shadowProjection, Vector3f shadowLightVectorFromOrigin, BoxCuller voxelCuller, BoxCuller distanceCuller) { - super(modelViewProjection, shadowProjection, shadowLightVectorFromOrigin, voxelCuller); - this.distanceCuller = distanceCuller; - } - - @Override - public void prepare(double cameraX, double cameraY, double cameraZ) { - if (this.distanceCuller != null) { - this.distanceCuller.setPosition(cameraX, cameraY, cameraZ); - } - super.prepare(cameraX, cameraY, cameraZ); - } - - @Override - public boolean isVisible(AABB aabb) { - if (distanceCuller != null && distanceCuller.isCulled(aabb)) { - return false; - } - - if (boxCuller != null && !boxCuller.isCulled(aabb)) { - return true; - } - - return this.isVisible(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ) != 0; - } - - @Override - public int fastAabbTest(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - if (distanceCuller != null && distanceCuller.isCulled(minX, minY, minZ, maxX, maxY, maxZ)) { - return 0; - } - - if (boxCuller != null && !boxCuller.isCulled(minX, minY, minZ, maxX, maxY, maxZ)) { - return 2; - } - - return isVisible(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - if (distanceCuller != null && distanceCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) { - return false; - } - - if (boxCuller != null && !boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) { - return true; - } - - return this.checkCornerVisibility(minX, minY, minZ, maxX, maxY, maxZ) > 0; - } -} diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/SafeZoneAdvancedShadowCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/SafeZoneAdvancedShadowCullingFrustum.java new file mode 100644 index 0000000000..c30248e953 --- /dev/null +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/advanced/SafeZoneAdvancedShadowCullingFrustum.java @@ -0,0 +1,82 @@ +package net.irisshaders.iris.shadows.frustum.advanced; + +import net.irisshaders.iris.shadows.frustum.BoxCuller; +import net.minecraft.world.phys.AABB; +import org.jetbrains.annotations.NotNull; +import org.joml.FrustumIntersection; +import org.joml.Matrix4fc; +import org.joml.Vector3f; + +// nothing is rendered that falls outside the distanceCuller, and everything is rendered that falls within the boxCuller (safe zone) +public class SafeZoneAdvancedShadowCullingFrustum extends AdvancedShadowCullingFrustum { + private final @NotNull BoxCuller distanceCuller; + + public SafeZoneAdvancedShadowCullingFrustum(Matrix4fc modelViewProjection, Matrix4fc shadowProjection, Vector3f shadowLightVectorFromOrigin, BoxCuller voxelCuller, @NotNull BoxCuller distanceCuller) { + super(modelViewProjection, shadowProjection, shadowLightVectorFromOrigin, voxelCuller); + this.distanceCuller = distanceCuller; + } + + @Override + public void prepare(double cameraX, double cameraY, double cameraZ) { + this.distanceCuller.setPosition(cameraX, cameraY, cameraZ); + super.prepare(cameraX, cameraY, cameraZ); + } + + @Override + public boolean isVisible(AABB aabb) { + if (this.distanceCuller.isCulled(aabb)) { + return false; + } + + if (this.boxCuller != null && !this.boxCuller.isCulled(aabb)) { + return true; + } + + return this.isVisibleBool(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ); + } + + @Override + public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { + if (this.distanceCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) { + return false; + } + + if (this.boxCuller != null && !this.boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ)) { + return true; + } + + return this.checkCornerVisibilityBool(minX, minY, minZ, maxX, maxY, maxZ); + } + + @Override + public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { + var distanceResult = this.distanceCuller.intersectAab(minX, minY, minZ, maxX, maxY, maxZ); + if (distanceResult == FrustumIntersection.OUTSIDE) { + return FrustumIntersection.OUTSIDE; + } + + var safeZoneResult = FrustumIntersection.OUTSIDE; + if (this.boxCuller != null) { + safeZoneResult = this.boxCuller.intersectAab(minX, minY, minZ, maxX, maxY, maxZ); + if (safeZoneResult == FrustumIntersection.INSIDE) { + return FrustumIntersection.INSIDE; + } + } + + if (distanceResult == FrustumIntersection.INTERSECT && safeZoneResult == FrustumIntersection.INTERSECT) { + return FrustumIntersection.INTERSECT; + } + + var frustumResult = this.checkCornerVisibility(minX, minY, minZ, maxX, maxY, maxZ); + + if (safeZoneResult == FrustumIntersection.OUTSIDE && frustumResult == FrustumIntersection.OUTSIDE) { + return FrustumIntersection.OUTSIDE; + } + + if (frustumResult == FrustumIntersection.INSIDE && distanceResult == FrustumIntersection.INSIDE) { + return FrustumIntersection.INSIDE; + } + + return FrustumIntersection.INTERSECT; + } +} diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/BoxCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/BoxCullingFrustum.java index dbd2039c0c..3da41a629f 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/BoxCullingFrustum.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/BoxCullingFrustum.java @@ -5,6 +5,7 @@ import net.irisshaders.iris.shadows.frustum.BoxCuller; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.world.phys.AABB; +import org.joml.FrustumIntersection; import org.joml.Matrix4f; import org.joml.Vector3d; @@ -31,17 +32,22 @@ public boolean canDetermineInvisible(double minX, double minY, double minZ, doub return false; } + @Override + public Viewport sodium$createViewport() { + return new Viewport(this, this.position); + } + public boolean isVisible(AABB box) { - return !boxCuller.isCulled(box); + return !this.boxCuller.isCulled(box); } @Override - public Viewport sodium$createViewport() { - return new Viewport(this, position); + public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { + return !this.boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ); } @Override - public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { - return !boxCuller.isCulledSodium(minX, minY, minZ, maxX, maxY, maxZ); + public int intersectAab(float v, float v1, float v2, float v3, float v4, float v5) { + return this.boxCuller.intersectAab(v, v1, v2, v3, v4, v5); } } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/NonCullingFrustum.java b/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/NonCullingFrustum.java index 991a957f58..dadd62e148 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/NonCullingFrustum.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/frustum/fallback/NonCullingFrustum.java @@ -24,10 +24,6 @@ public boolean canDetermineInvisible(double minX, double minY, double minZ, doub return false; } - public boolean isVisible(AABB box) { - return true; - } - @Override public int cubeInFrustum(BoundingBox boundingBox) { return FrustumIntersection.INSIDE; @@ -55,11 +51,20 @@ public void prepare(double d, double e, double f) { @Override public Viewport sodium$createViewport() { - return new Viewport(this, position); + return new Viewport(this, this.position); + } + + public boolean isVisible(AABB box) { + return true; } @Override public boolean testAab(float v, float v1, float v2, float v3, float v4, float v5) { return true; } + + @Override + public int intersectAab(float v, float v1, float v2, float v3, float v4, float v5) { + return FrustumIntersection.INSIDE; + } } diff --git a/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/XHFPTerrainVertex.java b/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/XHFPTerrainVertex.java index 2328b30d21..541cd3ee50 100644 --- a/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/XHFPTerrainVertex.java +++ b/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/XHFPTerrainVertex.java @@ -3,7 +3,6 @@ import net.caffeinemc.mods.sodium.api.util.ColorABGR; import net.caffeinemc.mods.sodium.api.util.ColorARGB; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; -import net.caffeinemc.mods.sodium.client.render.frapi.helper.ColorHelper; import net.irisshaders.iris.shaderpack.materialmap.WorldRenderingSettings; import net.irisshaders.iris.vertices.ExtendedDataHelper; import net.irisshaders.iris.vertices.NormI8; diff --git a/common/src/main/resources/mixins.iris.compat.sodium.json b/common/src/main/resources/mixins.iris.compat.sodium.json index d6c1f4f0d1..5864d18332 100644 --- a/common/src/main/resources/mixins.iris.compat.sodium.json +++ b/common/src/main/resources/mixins.iris.compat.sodium.json @@ -25,7 +25,8 @@ "MixinSodiumGameOptionPages", "MixinSodiumGameOptions", "MixinSodiumOptionsGUI", - "MixinSodiumWorldRenderer" + "MixinSodiumWorldRenderer", + "MixinRenderRegion" ], "injectors": { "defaultRequire": 1 diff --git a/common/src/main/resources/mixins.iris.json b/common/src/main/resources/mixins.iris.json index 43cdde4150..255b35b910 100644 --- a/common/src/main/resources/mixins.iris.json +++ b/common/src/main/resources/mixins.iris.json @@ -47,7 +47,6 @@ "MixinParticleEngine", "MixinShaderManager_Overrides", "MixinQuickPlayDev", - "MixinRenderSection", "MixinRenderSystem", "MixinRenderTarget", "MixinRenderType", diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 96d30c2fd7..aac0e3e8fa 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -64,7 +64,10 @@ dependencies { addRuntimeFabricModule("fabric-rendering-fluids-v1") addRuntimeFabricModule("fabric-resource-loader-v0") - modImplementation("maven.modrinth", "sodium", "mc1.21.4-0.6.3-fabric") + // modImplementation("maven.modrinth", "sodium", "mc1.21-0.6.0-beta.2-fabric") + modImplementation("net.caffeinemc", "fabric", "0.6.6-snapshot+mc1.21.4-local") { + isChanging = true + } implementAndInclude("org.antlr:antlr4-runtime:4.13.1") implementAndInclude("io.github.douira:glsl-transformer:2.0.1") implementAndInclude("org.anarres:jcpp:1.4.14") diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index efdf71590a..e49f7a09f9 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -134,7 +134,10 @@ dependencies { runtimeOnly("org.sinytra.forgified-fabric-api:fabric-rendering-data-attachment-v1:0.3.48+73761d2e19") runtimeOnly("org.sinytra.forgified-fabric-api:fabric-block-view-api-v2:1.0.10+9afaaf8c19") - implementation("maven.modrinth", "sodium", "mc1.21.4-0.6.3-neoforge") + // implementation("maven.modrinth", "sodium", "mc1.21-0.6.0-beta.2-neoforge") + implementation("net.caffeinemc", "neoforge", "0.6.6-snapshot+mc1.21.4-local") { + isChanging = true + } includeAdditional("io.github.douira:glsl-transformer:2.0.1") includeAdditional("org.anarres:jcpp:1.4.14") includeAdditional("org.antlr:antlr4-runtime:4.13.1") diff --git a/settings.gradle.kts b/settings.gradle.kts index a48a25c429..98f74668e2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,4 +8,4 @@ pluginManagement { } } -include("common", "fabric", "neoforge") +include("common", "fabric")