From ba4bb1d44c9f70edbf4fd4e47f513a01563514e0 Mon Sep 17 00:00:00 2001 From: Rogo Date: Fri, 12 Apr 2024 16:30:13 +0800 Subject: [PATCH] update depth check --- .../renderingculling/api/ChunkCullingMap.java | 51 +++++-------------- .../renderingculling/api/CullingHandler.java | 28 +++++----- .../api/CullingRenderEvent.java | 2 +- 3 files changed, 27 insertions(+), 54 deletions(-) diff --git a/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java b/src/main/java/rogo/renderingculling/api/ChunkCullingMap.java index f55f5ee..eb9f62e 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,9 @@ 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,14 +35,16 @@ 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; + + int index = 1 + (posX * spacePartitionSize * CullingHandler.LEVEL_HEIGHT_OFFSET + posZ * CullingHandler.LEVEL_HEIGHT_OFFSET + chunkY) << 2; + + if (index > 0 && index < cullingBuffer.limit()) { + return (cullingBuffer.get(index) & 0xFF) > 0; } return false; diff --git a/src/main/java/rogo/renderingculling/api/CullingHandler.java b/src/main/java/rogo/renderingculling/api/CullingHandler.java index 23f8102..bfc6d93 100644 --- a/src/main/java/rogo/renderingculling/api/CullingHandler.java +++ b/src/main/java/rogo/renderingculling/api/CullingHandler.java @@ -29,27 +29,29 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; -import org.joml.Vector3f; import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.system.Checks; import org.slf4j.Logger; import rogo.renderingculling.event.WorldUnloadEvent; import rogo.renderingculling.gui.ConfigScreen; import rogo.renderingculling.mixin.AccessorLevelRender; import rogo.renderingculling.mixin.AccessorMinecraft; -import rogo.renderingculling.util.*; +import rogo.renderingculling.util.DepthContext; +import rogo.renderingculling.util.LifeTimer; +import rogo.renderingculling.util.ShaderLoader; import java.io.IOException; import java.lang.reflect.Field; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.function.Supplier; import static org.lwjgl.opengl.GL11.GL_TEXTURE; import static org.lwjgl.opengl.GL30.*; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME; public class CullingHandler implements ModInitializer { public static CullingHandler INSTANCE; @@ -196,14 +198,14 @@ public static String fromID(String s) { public static final KeyMapping CONFIG_KEY = KeyBindingHelper.registerKeyBinding( new KeyMapping(MOD_ID + ".key.config", InputConstants.Type.KEYSYM, - GLFW.GLFW_KEY_R, - "key.category." + MOD_ID)); + GLFW.GLFW_KEY_R, + "key.category." + MOD_ID)); public static final KeyMapping DEBUG_KEY = KeyBindingHelper.registerKeyBinding( new KeyMapping(MOD_ID + ".key.debug", InputConstants.Type.KEYSYM, - GLFW.GLFW_KEY_X, - "key.category." + MOD_ID)); + GLFW.GLFW_KEY_X, + "key.category." + MOD_ID)); private void registerEvents() { WorldUnloadEvent.WORLD_UNLOAD.register(this::onWorldUnload); @@ -260,10 +262,9 @@ public boolean shouldRenderChunk(IRenderSectionVisibility section) { 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)) { render = true; @@ -272,8 +273,6 @@ public boolean shouldRenderChunk(IRenderSectionVisibility section) { render = actualRender; } - preChunkCullingTime += System.nanoTime() - time; - if (checkCulling) render = !render; @@ -282,7 +281,8 @@ public boolean shouldRenderChunk(IRenderSectionVisibility section) { } else if(actualRender) { section.updateVisibleTick(clientTickCount); } - + long costTime = System.nanoTime() - time; + preChunkCullingTime += costTime; return render; } diff --git a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java index eef734e..1379c9c 100644 --- a/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java +++ b/src/main/java/rogo/renderingculling/api/CullingRenderEvent.java @@ -56,7 +56,7 @@ public void onOverlayRender(GuiGraphics guiGraphics, float tickDelta ) { String cullingInitTime = Component.translatable("brute_force_rendering_culling.chunk_culling_init").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingInitTime /1000/CullingHandler.INSTANCE.cullingInitCount) + " μs"; drawString(guiGraphics, cullingInitTime, width, height - heightScale); - String chunkCullingTime = Component.translatable("brute_force_rendering_culling.chunk_culling_time").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingTime/1000/CullingHandler.INSTANCE.fps) + " μs"; + String chunkCullingTime = Component.translatable("brute_force_rendering_culling.chunk_culling_time").getString() + ": " + (CullingHandler.INSTANCE.chunkCullingTime / CullingHandler.INSTANCE.chunkCount) + " ns"; drawString(guiGraphics, chunkCullingTime, width, height - heightScale); }