From 9daf5a013c937fa3f44b2042f51bde8a0b4d6aa1 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 1 Jan 2022 21:28:56 -0700 Subject: [PATCH] Changed cloud projection matrix to have custom clip values. --- .../common/clouds/CloudBufferSingleton.java | 22 +++++++++ .../lod/fabric/mixins/MixinWorldRenderer.java | 45 ++++++++++++++++--- .../lod/forge/mixins/MixinWorldRenderer.java | 39 +++++++++++++--- 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 common/src/main/java/com/seibel/lod/common/clouds/CloudBufferSingleton.java diff --git a/common/src/main/java/com/seibel/lod/common/clouds/CloudBufferSingleton.java b/common/src/main/java/com/seibel/lod/common/clouds/CloudBufferSingleton.java new file mode 100644 index 000000000..8777a83f8 --- /dev/null +++ b/common/src/main/java/com/seibel/lod/common/clouds/CloudBufferSingleton.java @@ -0,0 +1,22 @@ +package com.seibel.lod.common.clouds; + +import org.lwjgl.system.MemoryUtil; + +import java.nio.FloatBuffer; + +//I'm not sure if there is a better place to put these, if there is feel free to move them. +/** + * This exists because creating a new Floatbuffer every tick to simply store floats seems to be a bad idea. + */ +public class CloudBufferSingleton +{ + + public static final CloudBufferSingleton INSTANCE = new CloudBufferSingleton(); + + public FloatBuffer customBuffer = MemoryUtil.memAllocFloat(16); + public FloatBuffer mcBuffer = MemoryUtil.memAllocFloat(16); + + public CloudBufferSingleton(){ + + } +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java index a7d3459fe..63daa97cf 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java @@ -19,13 +19,23 @@ package com.seibel.lod.fabric.mixins; +import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; import com.seibel.lod.common.Config; +import com.seibel.lod.common.clouds.CloudBufferSingleton; import com.seibel.lod.common.clouds.CloudTexture; import com.seibel.lod.common.clouds.NoiseCloudHandler; import com.seibel.lod.common.wrappers.McObjectConverter; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.util.SingletonHandler; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import net.minecraft.client.renderer.LevelRenderer; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL32; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -51,6 +61,7 @@ import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.*; +import java.nio.FloatBuffer; import java.util.Random; /** @@ -88,7 +99,7 @@ public class MixinWorldRenderer } @Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true) - public void renderClouds(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { + public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { if (Config.Client.Graphics.CloudQuality.customClouds) { TextureManager textureManager = Minecraft.getInstance().getTextureManager(); registerClouds(textureManager); @@ -96,7 +107,7 @@ public class MixinWorldRenderer if (minecraft.level.dimension() == ClientLevel.OVERWORLD) { CloudTexture cloudTexture = NoiseCloudHandler.cloudTextures.get(NoiseCloudHandler.cloudTextures.size() - 1); - renderCloudLayer(poseStack, model, tickDelta, cameraX, cameraY, cameraZ, (float) (Config.Client.Graphics.CloudQuality.cloudHeight + 0.01 /* Make clouds a bit higher so it dosnt do janky stuff */), 0, 1, 1, cloudTexture.resourceLocation); + renderCloudLayer(poseStack, projectionMatrix, tickDelta, cameraX, cameraY, cameraZ, (float) (Config.Client.Graphics.CloudQuality.cloudHeight + 0.01 /* Make clouds a bit higher so it dosnt do janky stuff */), 0, 1, 1, cloudTexture.resourceLocation); } ci.cancel(); @@ -149,7 +160,7 @@ public class MixinWorldRenderer } } - private void renderCloudLayer(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) { + private void renderCloudLayer(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) { RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.enableDepthTest(); @@ -179,6 +190,29 @@ public class MixinWorldRenderer } RenderSystem.setShader(GameRenderer::getPositionTexColorNormalShader); + + //Setup custom projection matrix and override minecraft's. + //create needed objects + ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + FloatBuffer customBuffer = CloudBufferSingleton.INSTANCE.customBuffer; + FloatBuffer mcBuffer = CloudBufferSingleton.INSTANCE.mcBuffer; + //create clip values. + //far clip is our clip plane value + float farClip = (CONFIG.client().graphics().quality().getLodChunkRenderDistance() * LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH / 2; + //near clip is mc clip plane value + float nearClip = 0.05f; + float matNearClip = -((farClip + nearClip) / (farClip - nearClip)); + float matFarClip = -((2 * farClip * nearClip) / (farClip - nearClip)); + + //store ProjectionMatrix values to buffers + projectionMatrix.store(customBuffer); + projectionMatrix.store(mcBuffer); + //change values on our custom buffer + customBuffer.put(10, matNearClip); + customBuffer.put(14, matFarClip); + //load values from our buffer to the projection matrix + projectionMatrix.load(customBuffer); + if (this.generateClouds) { this.generateClouds = false; Tesselator tessellator = Tesselator.getInstance(); @@ -207,10 +241,11 @@ public class MixinWorldRenderer } ShaderInstance shader = RenderSystem.getShader(); - this.cloudBuffer.drawWithShader(poseStack.last().pose(), model, shader); + this.cloudBuffer.drawWithShader(poseStack.last().pose(), projectionMatrix, shader); } } - + //reset the projection matrix to original values + projectionMatrix.load(mcBuffer); poseStack.popPose(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.enableCull(); diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java b/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java index 705c1114d..3ecfbb999 100644 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java +++ b/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java @@ -22,9 +22,13 @@ package com.seibel.lod.forge.mixins; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; import com.seibel.lod.common.Config; +import com.seibel.lod.common.clouds.CloudBufferSingleton; import com.seibel.lod.common.clouds.CloudTexture; import com.seibel.lod.common.clouds.NoiseCloudHandler; import com.seibel.lod.common.wrappers.McObjectConverter; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.util.SingletonHandler; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import net.minecraft.client.renderer.LevelRenderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -51,6 +55,7 @@ import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.*; +import java.nio.FloatBuffer; import java.util.Random; /** @@ -88,7 +93,7 @@ public class MixinWorldRenderer } @Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true) - public void renderClouds(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { + public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { if (Config.Client.Graphics.CloudQuality.customClouds) { TextureManager textureManager = Minecraft.getInstance().getTextureManager(); registerClouds(textureManager); @@ -96,7 +101,7 @@ public class MixinWorldRenderer if (minecraft.level.dimension() == ClientLevel.OVERWORLD) { CloudTexture cloudTexture = NoiseCloudHandler.cloudTextures.get(NoiseCloudHandler.cloudTextures.size() - 1); - renderCloudLayer(poseStack, model, tickDelta, cameraX, cameraY, cameraZ, (float) (Config.Client.Graphics.CloudQuality.cloudHeight + 0.01 /* Make clouds a bit higher so it dosnt do janky stuff */), 0, 1, 1, cloudTexture.resourceLocation); + renderCloudLayer(poseStack, projectionMatrix, tickDelta, cameraX, cameraY, cameraZ, (float) (Config.Client.Graphics.CloudQuality.cloudHeight + 0.01 /* Make clouds a bit higher so it dosnt do janky stuff */), 0, 1, 1, cloudTexture.resourceLocation); } ci.cancel(); @@ -149,7 +154,7 @@ public class MixinWorldRenderer } } - private void renderCloudLayer(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) { + private void renderCloudLayer(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) { RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.enableDepthTest(); @@ -179,6 +184,29 @@ public class MixinWorldRenderer } RenderSystem.setShader(GameRenderer::getPositionTexColorNormalShader); + + //Setup custom projection matrix and override minecraft's. + //create needed objects + ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + FloatBuffer customBuffer = CloudBufferSingleton.INSTANCE.customBuffer; + FloatBuffer mcBuffer = CloudBufferSingleton.INSTANCE.mcBuffer; + //create clip values. + //far clip is our clip plane value + float farClip = (CONFIG.client().graphics().quality().getLodChunkRenderDistance() * LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH / 2; + //near clip is mc clip plane value + float nearClip = 0.05f; + float matNearClip = -((farClip + nearClip) / (farClip - nearClip)); + float matFarClip = -((2 * farClip * nearClip) / (farClip - nearClip)); + + //store projectionMatrix values to buffers + projectionMatrix.store(customBuffer); + projectionMatrix.store(mcBuffer); + //change values on our custom buffer + customBuffer.put(10, matNearClip); + customBuffer.put(14, matFarClip); + //load values from our buffer to the projection matrix + projectionMatrix.load(customBuffer); + if (this.generateClouds) { this.generateClouds = false; Tesselator tessellator = Tesselator.getInstance(); @@ -207,10 +235,11 @@ public class MixinWorldRenderer } ShaderInstance shader = RenderSystem.getShader(); - this.cloudBuffer.drawWithShader(poseStack.last().pose(), model, shader); + this.cloudBuffer.drawWithShader(poseStack.last().pose(), projectionMatrix, shader); } } - + //reset the projection matrix to original values + projectionMatrix.load(mcBuffer); poseStack.popPose(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.enableCull();