Skip to content

Commit

Permalink
modify chunk culling shader
Browse files Browse the repository at this point in the history
  • Loading branch information
RogoShum committed Apr 28, 2024
1 parent ca3aebe commit e0fd61d
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 141 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/rogo/renderingculling/api/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ public static boolean getAsyncChunkRebuild() {
if(!shouldCullChunk())
return false;

if (CullingHandler.needPauseRebuild())
return false;

if(ModLoader.hasNvidium())
return false;

Expand All @@ -91,6 +94,9 @@ public static void setAsyncChunkRebuild(boolean value) {
if(ModLoader.hasNvidium())
return;

if (CullingHandler.needPauseRebuild())
return;

if(!ModLoader.hasSodium())
return;

Expand Down
54 changes: 13 additions & 41 deletions src/main/java/rogo/renderingculling/api/CullingHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -358,35 +344,19 @@ public static void onProfilerPopPush(String s) {
}
checkShader();
}
case "terrain_setup" -> {
applyFrustum = true;
}
case "compilechunks" -> {
applyFrustum = false;
}
case "destroyProgress" -> {
updatingDepth = true;
updateDepthMap();
readMapData();
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -717,7 +689,7 @@ public static boolean gl33() {
}

public static boolean needPauseRebuild() {
return false;
return fullChunkUpdateCooldown > 0;
}

public static int mapChunkY(double posY) {
Expand Down
21 changes: 5 additions & 16 deletions src/main/java/rogo/renderingculling/api/CullingRenderEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -139,16 +130,15 @@ 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();
BufferUploader.drawWithShader(bufferbuilder.end());
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();
Expand All @@ -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)
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/rogo/renderingculling/api/data/CullingMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/rogo/renderingculling/gui/ConfigScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/rogo/renderingculling/mixin/MixinFrustum.java
Original file line number Diff line number Diff line change
@@ -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<Boolean> cir) {
if (CullingHandler.applyFrustum && Config.shouldCullChunk() && cir.getReturnValue() && !CullingHandler.shouldRenderChunk(new DummySection(aabb), true))
cir.setReturnValue(false);
}
}
Loading

0 comments on commit e0fd61d

Please sign in to comment.