aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/xmrvizzy
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2023-07-16 04:04:42 -0400
committerAaron <51387595+AzureAaron@users.noreply.github.com>2023-07-16 04:04:42 -0400
commitf05ef4128f4b0bcb9d0bf1a691ce17037f1bc765 (patch)
treef211ee0cdb48efd376bfe4062843d014802d8496 /src/main/java/me/xmrvizzy
parentb63b73b2815db7e1442981e550980e5784c33e78 (diff)
downloadSkyblocker-f05ef4128f4b0bcb9d0bf1a691ce17037f1bc765.tar.gz
Skyblocker-f05ef4128f4b0bcb9d0bf1a691ce17037f1bc765.tar.bz2
Skyblocker-f05ef4128f4b0bcb9d0bf1a691ce17037f1bc765.zip
Rendering Improvements, Fixes + Occlusion Culling
Diffstat (limited to 'src/main/java/me/xmrvizzy')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java45
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java48
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java29
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java4
6 files changed, 117 insertions, 13 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
index cc712405..3692db1b 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
@@ -19,6 +19,7 @@ import me.xmrvizzy.skyblocker.skyblock.rift.TheRift;
import me.xmrvizzy.skyblocker.skyblock.tabhud.TabHud;
import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import me.xmrvizzy.skyblocker.utils.*;
+import me.xmrvizzy.skyblocker.utils.culling.OcclusionCulling;
import me.xmrvizzy.skyblocker.utils.title.TitleContainer;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
@@ -83,6 +84,7 @@ public class SkyblockerMod implements ClientModInitializer {
DungeonMap.init();
TheRift.init();
TitleContainer.init();
+ OcclusionCulling.init();
containerSolverManager.init();
scheduler.scheduleCyclic(Utils::update, 20);
scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100);
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
index 6fa93735..a1221549 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
@@ -2,22 +2,29 @@ package me.xmrvizzy.skyblocker.utils;
import me.x150.renderer.render.Renderer3d;
import me.xmrvizzy.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
+import me.xmrvizzy.skyblocker.utils.culling.OcclusionCulling;
import me.xmrvizzy.skyblocker.utils.title.Title;
import me.xmrvizzy.skyblocker.utils.title.TitleContainer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.render.block.entity.BeaconBlockEntityRenderer;
+import net.minecraft.client.render.BufferBuilder;
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.Tessellator;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
-
import java.awt.*;
+import com.mojang.blaze3d.systems.RenderSystem;
+
public class RenderHelper {
private static final Vec3d ONE = new Vec3d(1, 1, 1);
+ private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
renderFilledThroughWalls(context, pos, colorComponents, alpha);
@@ -25,26 +32,40 @@ public class RenderHelper {
}
public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- Renderer3d.renderThroughWalls();
- renderFilled(context, pos, colorComponents, alpha);
- Renderer3d.stopRenderThroughWalls();
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ Renderer3d.renderThroughWalls();
+ renderFilled(context, pos, colorComponents, alpha);
+ Renderer3d.stopRenderThroughWalls();
+ }
}
public static void renderFilledIfVisible(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
renderFilled(context, pos, colorComponents, alpha);
}
}
- public static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
+ private static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
Renderer3d.renderFilled(context.matrixStack(), new Color(colorComponents[0], colorComponents[1], colorComponents[2], alpha), Vec3d.of(pos), ONE);
}
- public static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
- context.matrixStack().push();
- context.matrixStack().translate(pos.getX() - context.camera().getPos().x, pos.getY() - context.camera().getPos().y, pos.getZ() - context.camera().getPos().z);
- BeaconBlockEntityRendererInvoker.renderBeam(context.matrixStack(), context.consumers(), context.tickDelta(), context.world().getTime(), 0, BeaconBlockEntityRenderer.MAX_BEAM_HEIGHT, colorComponents);
- context.matrixStack().pop();
+ private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, MAX_OVERWORLD_BUILD_HEIGHT, pos.getZ() + 1)) {
+ MatrixStack matrices = context.matrixStack();
+ Vec3d camera = context.camera().getPos();
+
+ matrices.push();
+ matrices.translate(pos.getX() - camera.x, pos.getY() - camera.y, pos.getZ() - camera.z);
+
+ Tessellator tessellator = RenderSystem.renderThreadTesselator();
+ BufferBuilder buffer = tessellator.getBuffer();
+ VertexConsumerProvider.Immediate consumer = VertexConsumerProvider.immediate(buffer);
+
+ BeaconBlockEntityRendererInvoker.renderBeam(matrices, consumer, context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
+
+ consumer.draw();
+ matrices.pop();
+ }
}
public static void displayTitleAndPlaySound(int stayTicks, int fadeOutTicks, String titleKey, Formatting formatting) {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
index 73ad468f..61f79ae1 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
@@ -82,7 +82,7 @@ public class RenderUtils {
e.getZ() - MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()));
}
- public static Boolean pointExistsInArea(int x, int y, int x1, int y1, int x2, int y2) {
+ public static boolean pointExistsInArea(int x, int y, int x1, int y1, int x2, int y2) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java
new file mode 100644
index 00000000..e9a25fc3
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java
@@ -0,0 +1,48 @@
+package me.xmrvizzy.skyblocker.utils.culling;
+
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
+import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache;
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+import me.xmrvizzy.skyblocker.utils.FrustumUtils;
+import net.minecraft.client.MinecraftClient;
+
+public class OcclusionCulling {
+ private static final int TRACING_DISTANCE = 128;
+ private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
+ private static OcclusionCullingInstance instance = null;
+
+ // Reused objects to reduce allocation overhead
+ private static Vec3d cameraPos = new Vec3d(0, 0, 0);
+ private static Vec3d min = new Vec3d(0, 0, 0);
+ private static Vec3d max = new Vec3d(0, 0, 0);
+
+ /**
+ * Initializes the occlusion culling instance
+ */
+ public static void init() {
+ instance = new OcclusionCullingInstance(TRACING_DISTANCE, new WorldProvider(), new ArrayOcclusionCache(TRACING_DISTANCE), 2);
+ }
+
+ private static void updateCameraPos() {
+ var camera = CLIENT.gameRenderer.getCamera().getPos();
+ cameraPos.set(camera.x, camera.y, camera.z);
+ }
+
+ /**
+ * This first checks checks if the bounding box is within the camera's FOV, if
+ * it is then it checks for whether it's occluded or not.
+ *
+ * @return A boolean representing whether the bounding box is fully visible or
+ * not.
+ */
+ public static boolean isVisible(double x1, double y1, double z1, double x2, double y2, double z2) {
+ if (!FrustumUtils.isVisible(x1, y1, z1, x2, y2, z2)) return false;
+
+ updateCameraPos();
+ min.set(x1, y1, z1);
+ max.set(x2, y2, z2);
+
+ return instance.isAABBVisible(min, max, cameraPos);
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java
new file mode 100644
index 00000000..47d92c1f
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java
@@ -0,0 +1,29 @@
+package me.xmrvizzy.skyblocker.utils.culling;
+
+import com.logisticscraft.occlusionculling.DataProvider;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.util.math.BlockPos;
+
+public class WorldProvider implements DataProvider {
+ private final static MinecraftClient CLIENT = MinecraftClient.getInstance();
+ private ClientWorld world = null;
+
+ @Override
+ public boolean prepareChunk(int chunkX, int chunkZ) {
+ this.world = CLIENT.world;
+ return this.world != null;
+ }
+
+ @Override
+ public boolean isOpaqueFullCube(int x, int y, int z) {
+ BlockPos pos = new BlockPos(x, y, z);
+ return this.world.getBlockState(pos).isOpaqueFullCube(this.world, pos);
+ }
+
+ @Override
+ public void cleanup() {
+ this.world = null;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java
new file mode 100644
index 00000000..c25e7f7a
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Package dedicated to occlusion culling utilities
+ */
+package me.xmrvizzy.skyblocker.utils.culling; \ No newline at end of file