From e0fd61d181bf22890320ab4d42be05904082bcd3 Mon Sep 17 00:00:00 2001 From: RogoShum <1269314290@qq.com> Date: Mon, 29 Apr 2024 01:29:24 +0800 Subject: [PATCH] modify chunk culling shader --- gradle.properties | 2 +- .../rogo/renderingculling/api/Config.java | 6 +++ .../renderingculling/api/CullingHandler.java | 54 +++++-------------- .../api/CullingRenderEvent.java | 21 ++------ .../api/data/ChunkCullingMap.java | 13 ++--- .../renderingculling/api/data/CullingMap.java | 7 ++- .../renderingculling/gui/ConfigScreen.java | 2 +- .../renderingculling/mixin/MixinFrustum.java | 21 ++++++++ .../mixin/MixinLevelRender.java | 45 +--------------- .../sodium/MixinRenderSectionManager.java | 17 +++++- .../sodium/MixinSodiumWorldRenderer.java | 4 +- .../renderingculling/util/DummySection.java | 42 +++++++++++++++ .../util/OcclusionCullerThread.java | 18 ++++--- .../util/SodiumSectionAsyncUtil.java | 11 ++-- .../util/VanillaAsyncUtil.java | 14 ++++- .../shaders/core/chunk_culling.fsh | 31 ++++++----- src/main/resources/mixins.bfrc.json | 3 +- 17 files changed, 170 insertions(+), 141 deletions(-) create mode 100644 src/main/java/rogo/renderingculling/mixin/MixinFrustum.java create mode 100644 src/main/java/rogo/renderingculling/util/DummySection.java diff --git a/gradle.properties b/gradle.properties index 5300f06..a0f72b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.20.1+build.10 loader_version=0.15.9 # Mod Properties -mod_version=0.5.5 +mod_version=0.5.7 maven_group=rogo.renderingculling archives_base_name=BruteForceRenderingCulling-fabric-1.20.1 diff --git a/src/main/java/rogo/renderingculling/api/Config.java b/src/main/java/rogo/renderingculling/api/Config.java index 62cbe86..2e18357 100644 --- a/src/main/java/rogo/renderingculling/api/Config.java +++ b/src/main/java/rogo/renderingculling/api/Config.java @@ -75,6 +75,9 @@ public static boolean getAsyncChunkRebuild() { if(!shouldCullChunk()) return false; + if (CullingHandler.needPauseRebuild()) + return false; + if(ModLoader.hasNvidium()) return false; @@ -91,6 +94,9 @@ public static void setAsyncChunkRebuild(boolean value) { if(ModLoader.hasNvidium()) return; + if (CullingHandler.needPauseRebuild()) + return; + if(!ModLoader.hasSodium()) return; diff --git a/src/main/java/rogo/renderingculling/api/CullingHandler.java b/src/main/java/rogo/renderingculling/api/CullingHandler.java index 9db2379..5f39bc5 100644 --- a/src/main/java/rogo/renderingculling/api/CullingHandler.java +++ b/src/main/java/rogo/renderingculling/api/CullingHandler.java @@ -95,7 +95,7 @@ public class CullingHandler { public static long preApplyFrustumTime = 0; public static long applyFrustumTime = 0; public static int chunkCulling = 0; - public static int chunkCount = 0; + public static int singleFrameInjectCount = 0; public static long chunkCullingInitTime = 0; public static long preChunkCullingInitTime = 0; public static long entityCullingInitTime = 0; @@ -177,7 +177,7 @@ protected static void cleanup() { SHADER_DEPTH_BUFFER_ID.clear(); } - public static boolean shouldRenderChunk(IRenderSectionVisibility section, boolean count) { + public static boolean shouldRenderChunk(IRenderSectionVisibility section, boolean checkForChunk) { if (section == null) { return false; } @@ -188,48 +188,34 @@ public static boolean shouldRenderChunk(IRenderSectionVisibility section, boolea } if (!section.shouldCheckVisibility(lastVisibleUpdatedFrame)) { return true; - } else if (CHUNK_CULLING_MAP.isChunkOffsetCameraVisible(section.getPositionX(), section.getPositionY(), section.getPositionZ())) { + } else if (CHUNK_CULLING_MAP.isChunkOffsetCameraVisible(section.getPositionX(), section.getPositionY(), section.getPositionZ(), checkForChunk)) { section.updateVisibleTick(lastVisibleUpdatedFrame); return true; } return false; } - if (Config.getAsyncChunkRebuild()) { - if (!useOcclusionCulling) { - return true; - } - - count = false; + if (Config.getAsyncChunkRebuild() && !useOcclusionCulling) { + return true; } - long time = System.nanoTime(); - - if (count) - chunkCount++; - boolean render; boolean actualRender = false; if (!section.shouldCheckVisibility(lastVisibleUpdatedFrame)) { render = true; } else { - actualRender = CHUNK_CULLING_MAP.isChunkOffsetCameraVisible(section.getPositionX(), section.getPositionY(), section.getPositionZ()); + actualRender = CHUNK_CULLING_MAP.isChunkOffsetCameraVisible(section.getPositionX(), section.getPositionY(), section.getPositionZ(), checkForChunk); render = actualRender; } if (checkCulling) render = !render; - if (!render && count) { - chunkCulling++; - } else if (actualRender) { + if (actualRender) { section.updateVisibleTick(lastVisibleUpdatedFrame); } - if (count) - preChunkCullingTime += System.nanoTime() - time; - return render; } @@ -329,8 +315,8 @@ public static void onProfilerPopPush(String s) { switch (s) { case "beforeRunTick" -> { if (((AccessorLevelRender) Minecraft.getInstance().levelRenderer).getNeedsFullRenderChunkUpdate() && Minecraft.getInstance().level != null) { - if(ModLoader.hasMod("embeddium")) { - fullChunkUpdateCooldown = 20; + if (ModLoader.hasMod("embeddium")) { + fullChunkUpdateCooldown = 60; } LEVEL_SECTION_RANGE = Minecraft.getInstance().level.getMaxSection() - Minecraft.getInstance().level.getMinSection(); @@ -358,12 +344,6 @@ public static void onProfilerPopPush(String s) { } checkShader(); } - case "terrain_setup" -> { - applyFrustum = true; - } - case "compilechunks" -> { - applyFrustum = false; - } case "destroyProgress" -> { updatingDepth = true; updateDepthMap(); @@ -371,22 +351,12 @@ public static void onProfilerPopPush(String s) { CullingRenderEvent.updateCullingMap(); updatingDepth = false; } - case "chunk_render_lists" -> { - chunkCount = 0; - chunkCulling = 0; - } } } public static void onProfilerPush(String s) { if (s.equals("onKeyboardInput")) { ModLoader.onKeyPress(); - } - if (Config.shouldCullChunk() && s.equals("apply_frustum")) { - if (SHADER_LOADER == null || OptiFine != null) { - chunkCount = 0; - chunkCulling = 0; - } } else if (s.equals("center")) { CAMERA = Minecraft.getInstance().gameRenderer.getMainCamera(); int thisTick = clientTickCount % 20; @@ -564,7 +534,9 @@ public static void updateDepthMap() { public static void updateMapData() { if (anyCulling()) { - preCullingInitCount++; + if (anyNeedTransfer()) { + preCullingInitCount++; + } if (Config.getCullChunk()) { int renderingDiameter = Minecraft.getInstance().options.getEffectiveRenderDistance() * 2 + 1; @@ -717,7 +689,7 @@ public static boolean gl33() { } public static boolean needPauseRebuild() { - return false; + return fullChunkUpdateCooldown > 0; } public static int mapChunkY(double posY) { diff --git a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java index 310b188..7867ab9 100644 --- a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java +++ b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java @@ -57,10 +57,6 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta) { CullingHandler.cullingInitCount++; } - if (CullingHandler.chunkCount == 0) { - CullingHandler.chunkCount++; - } - int index = Minecraft.getInstance().fpsString.indexOf("fps"); if (index != -1) { String extractedString = Minecraft.getInstance().fpsString.substring(0, index + 3); @@ -97,23 +93,18 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta) { addString(monitorTexts, initTime); } - String chunkCulling = Component.translatable("brute_force_rendering_culling.chunk_culling").getString() + ": " + CullingHandler.chunkCulling + " / " + CullingHandler.chunkCount; - addString(monitorTexts, chunkCulling); - if (Config.getCullChunk()) { if (CullingHandler.CHUNK_CULLING_MAP != null) { String chunkCullingCount = Component.translatable("brute_force_rendering_culling.chunk_update_count").getString() + ": " + CullingHandler.CHUNK_CULLING_MAP.lastQueueUpdateCount; addString(monitorTexts, chunkCullingCount); } - String chunkCullingTime = Component.translatable("brute_force_rendering_culling.chunk_culling_time").getString() + ": " + (CullingHandler.chunkCullingTime / 1000 / CullingHandler.fps) + " μs"; - addString(monitorTexts, chunkCullingTime); - - String cullingInitTime = Component.translatable("brute_force_rendering_culling.chunk_culling_init").getString() + ": " + (CullingHandler.chunkCullingInitTime / 1000 / CullingHandler.cullingInitCount) + " μs"; + String cullingInitTime = Component.translatable("brute_force_rendering_culling.chunk_culling_init").getString() + ": " + (CullingHandler.chunkCullingInitTime / CullingHandler.cullingInitCount / CullingHandler.fps) + " ns"; addString(monitorTexts, cullingInitTime); } } + int heightOffset = minecraft.font.lineHeight * monitorTexts.size(); int top = height; int bottom = height + heightOffset; @@ -139,8 +130,7 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta) { RenderSystem.setShaderTexture(0, Minecraft.getInstance().getMainRenderTarget().getColorTextureId()); CullingHandler.useShader(CullingHandler.REMOVE_COLOR_SHADER); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 0.1f); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); + RenderSystem.disableBlend(); RenderSystem.getModelViewStack().pushPose(); RenderSystem.getModelViewStack().translate(0, 0, -1); RenderSystem.applyModelViewMatrix(); @@ -148,7 +138,7 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta) { RenderSystem.getModelViewStack().popPose(); RenderSystem.applyModelViewMatrix(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0f); - + RenderSystem.enableBlend(); RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE_MINUS_DST_COLOR, GlStateManager.DestFactor.ZERO); bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); bufferbuilder.vertex(right, bottom, 0.0D).color(1.0F, 1.0F, 1.0F, 1.0F).endVertex(); @@ -159,7 +149,6 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta) { BufferUploader.drawWithShader(bufferbuilder.end()); RenderSystem.defaultBlendFunc(); RenderSystem.disableBlend(); - renderText(guiGraphics, monitorTexts, width, top); if (!CullingHandler.checkTexture) @@ -271,7 +260,7 @@ public static void setUniform(ShaderInstance shader) { shaderInstance.getCullingCameraDir().set(array); } if (shaderInstance.getBoxScale() != null) { - shaderInstance.getBoxScale().set(4.0f); + shaderInstance.getBoxScale().set(8.0f); } if (shaderInstance.getFrustumPos() != null && CullingHandler.FRUSTUM != null) { Vec3 pos = new Vec3( diff --git a/src/main/java/rogo/renderingculling/api/data/ChunkCullingMap.java b/src/main/java/rogo/renderingculling/api/data/ChunkCullingMap.java index 5f98215..9afba45 100644 --- a/src/main/java/rogo/renderingculling/api/data/ChunkCullingMap.java +++ b/src/main/java/rogo/renderingculling/api/data/ChunkCullingMap.java @@ -9,10 +9,7 @@ import rogo.renderingculling.api.Config; import rogo.renderingculling.api.CullingHandler; -import java.util.ArrayDeque; -import java.util.HashSet; -import java.util.Queue; -import java.util.Set; +import java.util.*; public class ChunkCullingMap extends CullingMap { private int renderDistance = 0; @@ -47,14 +44,14 @@ public void updateCamera() { cameraZ = (int) camera.z >> 4; } - public boolean isChunkOffsetCameraVisible(int x, int y, int z) { - return isChunkVisible((x >> 4) - cameraX, CullingHandler.mapChunkY(y), (z >> 4) - cameraZ); + public boolean isChunkOffsetCameraVisible(int x, int y, int z, boolean checkForChunk) { + return isChunkVisible((x >> 4) - cameraX, CullingHandler.mapChunkY(y), (z >> 4) - cameraZ, checkForChunk); } - public boolean isChunkVisible(int posX, int posY, int posZ) { + public boolean isChunkVisible(int posX, int posY, int posZ, boolean checkForChunk) { int index = 1 + (((posX + renderDistance) * spacePartitionSize * CullingHandler.LEVEL_SECTION_RANGE + (posZ + renderDistance) * CullingHandler.LEVEL_SECTION_RANGE + posY) << 2); if (index > 0 && index < cullingBuffer.limit()) { - return (cullingBuffer.get(index) & 0xFF) > 0; + return (cullingBuffer.get(index) & 0xFF) > (checkForChunk ? 0 : 127); } return false; } diff --git a/src/main/java/rogo/renderingculling/api/data/CullingMap.java b/src/main/java/rogo/renderingculling/api/data/CullingMap.java index f332b34..e755c4a 100644 --- a/src/main/java/rogo/renderingculling/api/data/CullingMap.java +++ b/src/main/java/rogo/renderingculling/api/data/CullingMap.java @@ -29,6 +29,7 @@ public CullingMap(int width, int height) { GL15.glBindBuffer(GL31.GL_PIXEL_PACK_BUFFER, pboId); GL15.glBufferData(GL31.GL_PIXEL_PACK_BUFFER, (long) width * height * 4 * Float.BYTES, GL15.GL_DYNAMIC_READ); GL15.glBindBuffer(GL31.GL_PIXEL_PACK_BUFFER, 0); + CullingHandler.bindMainFrameTarget(); } public boolean needTransferData() { @@ -56,19 +57,17 @@ public void transferData() { } public void readData() { - GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, bindFrameBufferId()); GL15.glBindBuffer(GL31.GL_PIXEL_PACK_BUFFER, pboId); GL15.glGetBufferSubData(GL31.GL_PIXEL_PACK_BUFFER, 0, cullingBuffer); GL15.glBindBuffer(GL31.GL_PIXEL_PACK_BUFFER, 0); - CullingHandler.bindMainFrameTarget(); setTransferred(false); } abstract int configDelayCount(); public int dynamicDelayCount() { - if (CullingHandler.fps > 200) { - return CullingHandler.fps / 200; + if (CullingHandler.fps > 100) { + return CullingHandler.fps / 100; } return 0; diff --git a/src/main/java/rogo/renderingculling/gui/ConfigScreen.java b/src/main/java/rogo/renderingculling/gui/ConfigScreen.java index cfce8ef..13a3e37 100644 --- a/src/main/java/rogo/renderingculling/gui/ConfigScreen.java +++ b/src/main/java/rogo/renderingculling/gui/ConfigScreen.java @@ -48,7 +48,7 @@ public static float v(int height) { public void renderBackground(GuiGraphics guiGraphics) { Minecraft minecraft = Minecraft.getInstance(); int width = minecraft.getWindow().getGuiScaledWidth() / 2; - int widthScale = width / 4; + int widthScale = 60; int right = width - widthScale; int left = width + widthScale; int bottom = (int) (minecraft.getWindow().getGuiScaledHeight() * 0.8) + 20; diff --git a/src/main/java/rogo/renderingculling/mixin/MixinFrustum.java b/src/main/java/rogo/renderingculling/mixin/MixinFrustum.java new file mode 100644 index 0000000..b3ac891 --- /dev/null +++ b/src/main/java/rogo/renderingculling/mixin/MixinFrustum.java @@ -0,0 +1,21 @@ +package rogo.renderingculling.mixin; + +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import rogo.renderingculling.api.Config; +import rogo.renderingculling.api.CullingHandler; +import rogo.renderingculling.util.DummySection; + +@Mixin(Frustum.class) +public abstract class MixinFrustum { + + @Inject(method = "isVisible", at = @At(value = "RETURN"), cancellable = true) + public void afterVisible(AABB aabb, CallbackInfoReturnable cir) { + if (CullingHandler.applyFrustum && Config.shouldCullChunk() && cir.getReturnValue() && !CullingHandler.shouldRenderChunk(new DummySection(aabb), true)) + cir.setReturnValue(false); + } +} diff --git a/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java b/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java index 528cde2..41b1717 100644 --- a/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java +++ b/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java @@ -19,16 +19,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import rogo.renderingculling.api.Config; import rogo.renderingculling.api.CullingHandler; import rogo.renderingculling.api.impl.IEntitiesForRender; -import rogo.renderingculling.api.impl.IRenderChunkInfo; -import rogo.renderingculling.api.impl.IRenderSectionVisibility; import rogo.renderingculling.util.VanillaAsyncUtil; import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.util.concurrent.atomic.AtomicReference; @Mixin(LevelRenderer.class) public abstract class MixinLevelRender implements IEntitiesForRender { @@ -46,37 +41,6 @@ public abstract class MixinLevelRender implements IEntitiesForRender { @Nullable private ViewArea viewArea; - @Shadow - @Final - private AtomicReference renderChunkStorage; - private LevelRenderer.RenderChunkStorage renderChunkStorageTemp; - - @Inject(method = "applyFrustum", at = @At(value = "RETURN")) - public void onApplyFrustum(Frustum p_194355_, CallbackInfo ci) { - if (Config.shouldCullChunk() && !VanillaAsyncUtil.shouldReplaceStorage()) { - if (CullingHandler.OptiFine != null) { - try { - Field field = LevelRenderer.class.getDeclaredField("renderInfosTerrain"); - field.setAccessible(true); - Object value = field.get(this); - - if (value instanceof ObjectArrayList) { - ((ObjectArrayList) value).removeIf((o -> { - ChunkRenderDispatcher.RenderChunk chunk = ((IRenderChunkInfo) o).getRenderChunk(); - return !CullingHandler.shouldRenderChunk((IRenderSectionVisibility) chunk, true); - })); - } - } catch (NoSuchFieldException | IllegalAccessException ignored) { - } - } - - this.renderChunksInFrustum.removeIf((o -> { - ChunkRenderDispatcher.RenderChunk chunk = ((IRenderChunkInfo) o).getRenderChunk(); - return !CullingHandler.shouldRenderChunk((IRenderSectionVisibility) chunk, true); - })); - } - } - @Inject(method = "setupRender", at = @At(value = "HEAD")) public void onSetupRenderHead(Camera p_194339_, Frustum p_194340_, boolean p_194341_, boolean p_194342_, CallbackInfo ci) { if (this.viewArea != null) { @@ -86,17 +50,12 @@ public void onSetupRenderHead(Camera p_194339_, Frustum p_194340_, boolean p_194 @Inject(method = "applyFrustum", at = @At(value = "HEAD")) public void onApplyFrustumHead(Frustum p_194355_, CallbackInfo ci) { - if (VanillaAsyncUtil.shouldReplaceStorage()) { - renderChunkStorageTemp = this.renderChunkStorage.get(); - this.renderChunkStorage.set(VanillaAsyncUtil.getChunkStorage()); - } + CullingHandler.applyFrustum = true; } @Inject(method = "applyFrustum", at = @At(value = "RETURN")) public void onApplyFrustumReturn(Frustum p_194355_, CallbackInfo ci) { - if (VanillaAsyncUtil.shouldReplaceStorage()) { - this.renderChunkStorage.set(renderChunkStorageTemp); - } + CullingHandler.applyFrustum = false; } @Inject(method = "prepareCullFrustum", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;(Lorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V")) diff --git a/src/main/java/rogo/renderingculling/mixin/sodium/MixinRenderSectionManager.java b/src/main/java/rogo/renderingculling/mixin/sodium/MixinRenderSectionManager.java index eff2b5e..55c20e1 100644 --- a/src/main/java/rogo/renderingculling/mixin/sodium/MixinRenderSectionManager.java +++ b/src/main/java/rogo/renderingculling/mixin/sodium/MixinRenderSectionManager.java @@ -4,8 +4,12 @@ import me.jellysquid.mods.sodium.client.gl.device.CommandList; import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; import me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager; +import me.jellysquid.mods.sodium.client.render.chunk.lists.SortedRenderLists; import me.jellysquid.mods.sodium.client.render.chunk.lists.VisibleChunkCollector; +import me.jellysquid.mods.sodium.client.render.viewport.Viewport; +import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; +import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -27,6 +31,8 @@ public abstract class MixinRenderSectionManager { @Final private Long2ReferenceMap sectionByPosition; + @Shadow(remap = false) private @NotNull SortedRenderLists renderLists; + @Inject(method = "", at = @At("TAIL")) private void init(ClientLevel world, int renderDistance, CommandList commandList, CallbackInfo ci) { SodiumSectionAsyncUtil.fromSectionManager(this.sectionByPosition, world); @@ -40,10 +46,19 @@ private void onIsSectionVisible(int x, int y, int z, CallbackInfoReturnable sections, Level world) { SodiumSectionAsyncUtil.occlusionCuller = new OcclusionCuller(sections, world); @@ -59,7 +59,7 @@ public static void asyncSearchRebuildSection() { Map> rebuildList = SodiumSectionAsyncUtil.collector.getRebuildLists(); for(ArrayDeque arrayDeque : rebuildList.values()) { if (!arrayDeque.isEmpty()) { - needSync = true; + needSyncRebuild = true; break; } } @@ -126,10 +126,15 @@ public void visit(RenderSection section, boolean visible) { @Override public Map> getRebuildLists() { + if(CullingHandler.needPauseRebuild()) { + return syncRebuildLists; + } super.getRebuildLists().forEach(((chunkUpdateType, renderSections) -> { for (RenderSection section : renderSections) { if (!section.isDisposed() && section.getBuildCancellationToken() == null) { - syncRebuildLists.get(chunkUpdateType).add(section); + try { + syncRebuildLists.get(chunkUpdateType).add(section); + } catch (Exception ignored) {} } } })); diff --git a/src/main/java/rogo/renderingculling/util/VanillaAsyncUtil.java b/src/main/java/rogo/renderingculling/util/VanillaAsyncUtil.java index 2827aca..1c23e81 100644 --- a/src/main/java/rogo/renderingculling/util/VanillaAsyncUtil.java +++ b/src/main/java/rogo/renderingculling/util/VanillaAsyncUtil.java @@ -16,6 +16,7 @@ import java.util.ArrayDeque; import java.util.HashSet; import java.util.Queue; +import java.util.concurrent.Semaphore; import static net.minecraft.client.renderer.LevelRenderer.DIRECTIONS; @@ -23,8 +24,11 @@ public class VanillaAsyncUtil { private static int chunkLength = 0; private static LevelRenderer.RenderChunkStorage storage; private static LevelRenderer levelRenderer; + private static final Semaphore shouldUpdate = new Semaphore(0); + public static boolean injectedAsyncMixin; public static void asyncSearchRebuildSection() { + shouldUpdate.acquireUninterruptibly(); if (levelRenderer == null) return; LevelRenderer.RenderChunkStorage renderChunkStorage = new LevelRenderer.RenderChunkStorage(chunkLength); Queue queue = new ArrayDeque<>(); @@ -36,7 +40,7 @@ public static void asyncSearchRebuildSection() { while (!queue.isEmpty()) { LevelRenderer.RenderChunkInfo last = queue.poll(); ChunkRenderDispatcher.RenderChunk lastRenderChunk = ((IRenderChunkInfo) last).getRenderChunk(); - if (originChunk != last && (!CullingHandler.FRUSTUM.isVisible(lastRenderChunk.getBoundingBox()) || !CullingHandler.shouldRenderChunk((IRenderSectionVisibility) lastRenderChunk, false))) { + if (originChunk != last && (!CullingHandler.FRUSTUM.isVisible(lastRenderChunk.getBoundingBox()) || !CullingHandler.shouldRenderChunk((IRenderSectionVisibility) lastRenderChunk, true))) { continue; } @@ -57,6 +61,8 @@ public static void asyncSearchRebuildSection() { } } } + if(CullingHandler.CHUNK_CULLING_MAP != null) + CullingHandler.CHUNK_CULLING_MAP.queueUpdateCount++; storage = renderChunkStorage; } @@ -73,6 +79,12 @@ public static boolean shouldReplaceStorage() { return Config.getAsyncChunkRebuild() && getChunkStorage() != null; } + public static void shouldUpdate() { + if (shouldUpdate.availablePermits() < 1) { + shouldUpdate.release(); + } + } + @NotNull private static BlockPos getOriginPos() { BlockPos origin = Minecraft.getInstance().gameRenderer.getMainCamera().getBlockPosition(); diff --git a/src/main/resources/assets/brute_force_rendering_culling/shaders/core/chunk_culling.fsh b/src/main/resources/assets/brute_force_rendering_culling/shaders/core/chunk_culling.fsh index 55136de..9af7d15 100644 --- a/src/main/resources/assets/brute_force_rendering_culling/shaders/core/chunk_culling.fsh +++ b/src/main/resources/assets/brute_force_rendering_culling/shaders/core/chunk_culling.fsh @@ -27,8 +27,8 @@ float far = 1000.0; int getSampler(float xLength, float yLength) { for(int i = 0; i < DepthScreenSize.length(); ++i) { - float xStep = 3.0 / DepthScreenSize[i].x; - float yStep = 3.0 / DepthScreenSize[i].y; + float xStep = 5.0 / DepthScreenSize[i].x; + float yStep = 5.0 / DepthScreenSize[i].y; if(xStep > xLength && yStep > yLength) { return i; } @@ -135,12 +135,20 @@ void main() { return; } - if(!isVisible(chunkPos)) { + float chunkDepth = LinearizeDepth(chunkCenterDepth)-BoxScale; + if(chunkDepth < 0) { + fragColor = vec4(0.0, 0.3, 0.3, 1.0); + return; + } + + /* + if(!isVisible(chunkPos)) { fragColor = vec4(0.0, 0.0, 1.0, 1.0); return; } + */ - float sizeOffset = 16.0; + float sizeOffset = 8.0; vec3 aabb[8] = vec3[]( chunkPos+vec3(-sizeOffset, -sizeOffset, -sizeOffset), chunkPos+vec3(sizeOffset, -sizeOffset, -sizeOffset), chunkPos+vec3(-sizeOffset, sizeOffset, -sizeOffset), chunkPos+vec3(sizeOffset, sizeOffset, -sizeOffset), @@ -165,7 +173,7 @@ void main() { if (screenPos.x >= 0 && screenPos.x <= 1 && screenPos.y >= 0 && screenPos.y <= 1 && screenPos.z >= 0 && screenPos.z <= 1) { - + inside = true; } else { vec3 vectorDir = normalize(aabb[i]-CullingCameraPos); @@ -196,9 +204,8 @@ void main() { minY = screenPos.y; } - float chunkDepth = LinearizeDepth(chunkCenterDepth)-BoxScale; - if(chunkDepth < 0) { - fragColor = vec4(1.0, 1.0, 1.0, 1.0); + if(!inside) { + fragColor = vec4(0.3, 0.3, 0.0, 1.0); return; } @@ -213,10 +220,10 @@ void main() { float xStep = 1.0/DepthScreenSize[idx].x; float yStep = 1.0/DepthScreenSize[idx].y; - minX = max(minX-xStep, 0.0); - maxX = min(maxX+xStep, 1.0); - minY = max(minY-yStep, 0.0); - maxY = min(maxY+yStep, 1.0); + minX = max(minX-xStep*2, 0.0); + maxX = min(maxX+xStep*2, 1.0); + minY = max(minY-yStep*2, 0.0); + maxY = min(maxY+yStep*2, 1.0); for(float x = minX; x <= maxX; x += xStep) { for(float y = minY; y <= maxY; y += yStep) { diff --git a/src/main/resources/mixins.bfrc.json b/src/main/resources/mixins.bfrc.json index 7e718cb..2f1ffcc 100644 --- a/src/main/resources/mixins.bfrc.json +++ b/src/main/resources/mixins.bfrc.json @@ -14,6 +14,7 @@ "AccessorMinecraft", "MixinBlockEntityRender", "MixinEntityRender", + "MixinFrustum", "MixinGameRenderer", "MixinInactiveProfiler", "MixinLevelRender", @@ -23,8 +24,8 @@ "MixinRenderChunkInfo", "MixinShaderInstance", "MixinShaderInstance$MixinRenderSystem", - "fabric.MixinTooltipRenderUtil", "fabric.MixinKeyboardHandler", + "fabric.MixinTooltipRenderUtil", "fabric.MixinWindow", "sodium.AccessorRenderSectionManager", "sodium.MixinOcclusionCuller",