diff --git a/gradle.properties b/gradle.properties index ccd2460..7230fdc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ loader_version=0.15.9 fiber_version = 0.23.0-SNAPSHOT # Mod Properties -mod_version=0.4.6 +mod_version=0.4.7 maven_group=rogo.renderingculling archives_base_name=BruteForceRenderingCulling-fabric-1.18.2 diff --git a/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java b/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java index f55f5ee..88df193 100644 --- a/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java +++ b/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java @@ -1,14 +1,11 @@ package rogo.renderingculling.api; import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; -import rogo.renderingculling.util.Vec2i; - -import java.util.HashMap; public class ChunkCullingMap extends CullingMap { - private final HashMap screenIndex = new HashMap<>(); + private int renderDistance = 0; + private int spacePartitionSize = 0; public ChunkCullingMap(int width, int height) { super(width, height); @@ -24,35 +21,10 @@ int bindFrameBufferId() { return CullingHandler.CHUNK_CULLING_MAP_TARGET.frameBufferId; } - public int getPosIndex(BlockPos pos) { - int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance(); - int spacePartitionSize = 2 * renderDistance + 1; - int x = pos.getX() + renderDistance; - int z = pos.getZ() + renderDistance; - int y = pos.getY(); - - return x * spacePartitionSize * CullingHandler.LEVEL_HEIGHT_OFFSET + z * CullingHandler.LEVEL_HEIGHT_OFFSET + y; - } - - public Vec2i getScreenPosFromIndex(int idx) { - int y = idx / width; - int x = idx - (y*width); - return new Vec2i(x, y); - } - public void generateIndex(int renderDistance) { - screenIndex.clear(); - for(int x = -renderDistance; x <= renderDistance; ++x) { - for (int z = -renderDistance; z <= renderDistance; ++z) { - for (int y = 0; y < CullingHandler.LEVEL_HEIGHT_OFFSET; ++y) { - BlockPos pos = new BlockPos(x, y, z); - Vec2i coord = getScreenPosFromIndex(getPosIndex(pos)); - if(coord.x() >= 0 && coord.y() >= 0 && coord.x() < this.width && coord.y() < this.height) { - screenIndex.put(pos, getPosIndex(pos)); - } - } - } - } + this.renderDistance = renderDistance; + spacePartitionSize = 2 * renderDistance + 1; + } public boolean isChunkVisible(double x, double y, double z) { @@ -64,24 +36,18 @@ public boolean isChunkVisible(double x, double y, double z) { y -= 9; int chunkX = (int) x >> 4; - int chunkY = (int) y / 16 + CullingHandler.LEVEL_MIN_SECTION_ABS; + int chunkY = (int) (y * 0.0625) + CullingHandler.LEVEL_MIN_SECTION_ABS; int chunkZ = (int) z >> 4; - BlockPos pos = new BlockPos(chunkX - cameraX, chunkY, chunkZ - cameraZ); - if(screenIndex.containsKey(pos)) { - Integer index = screenIndex.get(pos); - float cullingValue = (float) (cullingBuffer.get(1+index*4) & 0xFF) / 255.0f; - return cullingValue > 0.5; - } + int posX = chunkX - cameraX + renderDistance; + int posZ = chunkZ - cameraZ + renderDistance; - return false; - } + int index = 1 + (((posX * spacePartitionSize * CullingHandler.LEVEL_HEIGHT_OFFSET + posZ * CullingHandler.LEVEL_HEIGHT_OFFSET + chunkY) << 2)); - public boolean isTransferred() { - return transferred; - } + if (index > 0 && index < cullingBuffer.limit()) { + return (cullingBuffer.get(index) & 0xFF) > 0; + } - public void setTransferred(boolean transferred) { - this.transferred = transferred; + return false; } } diff --git a/src/main/java/rogo/renderingculling/api/Config.java b/src/main/java/rogo/renderingculling/api/Config.java index 0fca288..afb644c 100644 --- a/src/main/java/rogo/renderingculling/api/Config.java +++ b/src/main/java/rogo/renderingculling/api/Config.java @@ -58,7 +58,8 @@ public static void setCullChunk(boolean value) { public static int getDepthUpdateDelay() { if(unload()) return 1; - return UPDATE_DELAY.getValue(); + int dynamicWithShader = CullingHandler.INSTANCE.renderingShader() ? 1 : 0; + return UPDATE_DELAY.getValue() + dynamicWithShader; } public static void setDepthUpdateDelay(int value) { diff --git a/src/main/java/rogo/renderingculling/api/CullingHandler.java b/src/main/java/rogo/renderingculling/api/CullingHandler.java index c3c1299..383749e 100644 --- a/src/main/java/rogo/renderingculling/api/CullingHandler.java +++ b/src/main/java/rogo/renderingculling/api/CullingHandler.java @@ -118,6 +118,7 @@ public class CullingHandler implements ModInitializer { public static Camera CAMERA; private static final HashMap SHADER_DEPTH_BUFFER_ID = new HashMap<>(); public static boolean SHADER_ENABLED = false; + private int frame; static { RenderSystem.recordRenderCall(() -> { @@ -252,39 +253,47 @@ private void cleanup() { SHADER_DEPTH_BUFFER_ID.clear(); } - public boolean shouldRenderChunk(IRenderSectionVisibility section) { - chunkCount++; + public boolean shouldRenderChunk(IRenderSectionVisibility section, boolean count) { + if(count) + chunkCount++; if (!Config.getCullChunk() || CHUNK_CULLING_MAP == null || !CHUNK_CULLING_MAP.isDone()) { return true; } + long time = System.nanoTime(); boolean render; boolean actualRender = false; - long time = System.nanoTime(); - if (!section.shouldCheckVisibility(clientTickCount)) { + if (!section.shouldCheckVisibility(frame)) { render = true; } else { actualRender = CHUNK_CULLING_MAP.isChunkVisible(section.getPositionX(), section.getPositionY(), section.getPositionZ()); render = actualRender; } - preChunkCullingTime += System.nanoTime() - time; if (checkCulling) render = !render; - if (!render) { + if (!render && count) { chunkCulling++; } else if(actualRender) { - section.updateVisibleTick(clientTickCount); + section.updateVisibleTick(frame); } - + if(count) + preChunkCullingTime += System.nanoTime() - time; return render; } public boolean shouldSkipBlock(BlockEntity blockEntity, AABB aabb, BlockPos pos) { blockCount++; + + //for valkyrien skies + if(CAMERA.getPosition().distanceToSqr(pos.getX(), pos.getY(), pos.getZ()) > + Minecraft.getInstance().options.getEffectiveRenderDistance() * Minecraft.getInstance().options.getEffectiveRenderDistance() * 2) { + return false; + } + if (ENTITY_CULLING_MAP == null || !Config.getCullEntity()) return false; if (FRUSTUM == null || !FRUSTUM.isVisible(aabb)) return true; String type = BlockEntityType.getKey(blockEntity.getType()).toString(); @@ -435,6 +444,7 @@ public void onProfilerPush(String s) { } public void beforeRenderingWorld() { + ++frame; if(SHADER_LOADER != null) { boolean clear = false; if(SHADER_LOADER.renderingShader() && !usingShader) { @@ -654,7 +664,11 @@ public static void callDepthTexture() { } public boolean renderingOculus() { - return SHADER_LOADER != null && OptiFine == null && SHADER_LOADER.renderingShader(); + return renderingShader() && OptiFine == null; + } + + public boolean renderingShader() { + return SHADER_LOADER != null && SHADER_LOADER.renderingShader(); } public boolean isNextTick(int tick) { diff --git a/src/main/java/rogo/renderingculling/api/CullingMap.java b/src/main/java/rogo/renderingculling/api/CullingMap.java index 115caef..958ae0a 100644 --- a/src/main/java/rogo/renderingculling/api/CullingMap.java +++ b/src/main/java/rogo/renderingculling/api/CullingMap.java @@ -59,8 +59,8 @@ public void readData() { abstract int configDelayCount(); public int dynamicDelayCount() { - if(CullingHandler.INSTANCE.fps > 100) { - return CullingHandler.INSTANCE.fps / 100; + if(CullingHandler.INSTANCE.fps > 200) { + return CullingHandler.INSTANCE.fps / 200; } return 0; diff --git a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java index d4048e8..ce45b26 100644 --- a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java +++ b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java @@ -9,6 +9,7 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.world.phys.Vec3; import rogo.renderingculling.instanced.EntityCullingInstanceRenderer; @@ -55,7 +56,7 @@ public void onOverlayRender(PoseStack matrixStack, float tickDelta ) { String cullingInitTime = new TranslatableComponent("brute_force_rendering_culling.chunk_culling_init").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingInitTime /1000/CullingHandler.INSTANCE.cullingInitCount) + " μs"; drawString(cullingInitTime, width, height - heightScale); - String chunkCullingTime = new TranslatableComponent("brute_force_rendering_culling.chunk_culling_time").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingTime/1000/CullingHandler.INSTANCE.fps) + " μs"; + String chunkCullingTime = new TranslatableComponent("brute_force_rendering_culling.chunk_culling_time").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingTime / 1000 / CullingHandler.INSTANCE.chunkCount) + " μs"; drawString(chunkCullingTime, width, height - heightScale); } diff --git a/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java b/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java index f959b1e..2df14a9 100644 --- a/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java +++ b/src/main/java/rogo/renderingculling/mixin/MixinLevelRender.java @@ -38,7 +38,7 @@ public void onapplyFrustum(Frustum p_194355_, CallbackInfo ci) { if (value instanceof ObjectArrayList) { ((ObjectArrayList)value).removeIf((o -> { ChunkRenderDispatcher.RenderChunk chunk = ((IRenderChunkInfo) o).getRenderChunk(); - return !CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) chunk); + return !CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) chunk, true); })); } } catch (NoSuchFieldException | IllegalAccessException ignored) { @@ -47,7 +47,7 @@ public void onapplyFrustum(Frustum p_194355_, CallbackInfo ci) { this.renderChunksInFrustum.removeIf((o -> { ChunkRenderDispatcher.RenderChunk chunk = ((IRenderChunkInfo) o).getRenderChunk(); - return !CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) chunk); + return !CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) chunk, true); })); } } diff --git a/src/main/java/rogo/renderingculling/mixin/MixinRenderChunk.java b/src/main/java/rogo/renderingculling/mixin/MixinRenderChunk.java index 5592b85..a441bee 100644 --- a/src/main/java/rogo/renderingculling/mixin/MixinRenderChunk.java +++ b/src/main/java/rogo/renderingculling/mixin/MixinRenderChunk.java @@ -13,16 +13,16 @@ public abstract class MixinRenderChunk implements IRenderSectionVisibility { @Shadow @Final private BlockPos.MutableBlockPos origin; @Unique - private int cullingLastVisibleTick; + private int cullingLastVisibleFrame; @Override - public boolean shouldCheckVisibility(int clientTick) { - return clientTick - cullingLastVisibleTick > 20; + public boolean shouldCheckVisibility(int frame) { + return frame != cullingLastVisibleFrame; } @Override - public void updateVisibleTick(int clientTick) { - cullingLastVisibleTick = clientTick; + public void updateVisibleTick(int frame) { + cullingLastVisibleFrame = frame; } @Override diff --git a/src/main/java/rogo/renderingculling/mixin/MixinRenderSection.java b/src/main/java/rogo/renderingculling/mixin/MixinRenderSection.java index 8cb0ee2..47f4f49 100644 --- a/src/main/java/rogo/renderingculling/mixin/MixinRenderSection.java +++ b/src/main/java/rogo/renderingculling/mixin/MixinRenderSection.java @@ -16,16 +16,16 @@ public abstract class MixinRenderSection implements IRenderSectionVisibility { @Shadow(remap = false) public abstract int getOriginZ(); @Unique - private int cullingLastVisibleTick; + private int cullingLastVisibleFrame; @Override - public boolean shouldCheckVisibility(int clientTick) { - return clientTick - cullingLastVisibleTick > 20; + public boolean shouldCheckVisibility(int frame) { + return frame != cullingLastVisibleFrame; } @Override - public void updateVisibleTick(int clientTick) { - cullingLastVisibleTick = clientTick; + public void updateVisibleTick(int frame) { + cullingLastVisibleFrame = frame; } @Override diff --git a/src/main/java/rogo/renderingculling/mixin/MixinRenderSectionManager.java b/src/main/java/rogo/renderingculling/mixin/MixinRenderSectionManager.java index 86ff0e3..8f1ebeb 100644 --- a/src/main/java/rogo/renderingculling/mixin/MixinRenderSectionManager.java +++ b/src/main/java/rogo/renderingculling/mixin/MixinRenderSectionManager.java @@ -7,14 +7,14 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import rogo.renderingculling.api.CullingHandler; import rogo.renderingculling.api.IRenderSectionVisibility; @Mixin(RenderSectionManager.class) public abstract class MixinRenderSectionManager { - @Inject(method = "addVisible", at = @At(value = "HEAD"), remap = false, cancellable = true) - public void onBfsEnqueue(RenderSection section, Direction flow, CallbackInfo ci) { - if(!section.isEmpty() && !CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) section)) - ci.cancel(); + @Inject(method = "isWithinRenderDistance", at = @At(value = "HEAD"), remap = false, cancellable = true) + public void onIsWithinRenderDistance(RenderSection section, CallbackInfoReturnable cir) { + cir.setReturnValue(CullingHandler.INSTANCE.shouldRenderChunk((IRenderSectionVisibility) section, true)); } } \ No newline at end of file