diff --git a/src/main/java/me/cortex/voxy/client/VoxyClient.java b/src/main/java/me/cortex/voxy/client/VoxyClient.java index abe64537..a0ea47e9 100644 --- a/src/main/java/me/cortex/voxy/client/VoxyClient.java +++ b/src/main/java/me/cortex/voxy/client/VoxyClient.java @@ -19,13 +19,13 @@ public class VoxyClient implements ClientModInitializer { @Override public void onInitializeClient() { ClientLifecycleEvents.CLIENT_STARTED.register(client->{ - BudgetBufferRenderer.init(); boolean systemSupported = Capabilities.INSTANCE.compute && Capabilities.INSTANCE.indirectParameters; if (systemSupported) { VoxyCommon.setInstanceFactory(VoxyClientInstance::new); } else { Logger.error("Voxy is unsupported on your system."); } + BudgetBufferRenderer.init(); }); diff --git a/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java b/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java index 012e049a..c7f0c311 100644 --- a/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java +++ b/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java @@ -31,6 +31,7 @@ public class VoxyConfig implements OptionStorage { public int serviceThreads = (int) Math.max(CpuLayout.CORES.length/1.5, 1); public float subDivisionSize = 64; public boolean renderVanillaFog = false; + public boolean useEnvironmentalFog = false; public boolean renderStatistics = false; public static VoxyConfig loadOrCreate() { diff --git a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java index 73735460..54f3b68e 100644 --- a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java +++ b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java @@ -129,6 +129,14 @@ public abstract class VoxyConfigScreenPages { }, s -> s.sectionRenderDistance) .setImpact(OptionImpact.LOW) .build() + ).add(OptionImpl.createBuilder(boolean.class, storage) + .setName(Text.translatable("voxy.config.general.environmental_fog")) + .setTooltip(Text.translatable("voxy.config.general.environmental_fog.tooltip")) + .setControl(TickBoxControl::new) + .setImpact(OptionImpact.VARIES) + .setBinding((s, v)-> s.useEnvironmentalFog = v, s -> s.useEnvironmentalFog) + .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) + .build() ).add(OptionImpl.createBuilder(boolean.class, storage) .setName(Text.translatable("voxy.config.general.vanilla_fog")) .setTooltip(Text.translatable("voxy.config.general.vanilla_fog.tooltip")) diff --git a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java index a866648b..a1e6134d 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java @@ -21,6 +21,7 @@ import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.thread.ServiceThreadPool; import me.cortex.voxy.common.world.WorldEngine; import net.caffeinemc.mods.sodium.client.render.chunk.ChunkRenderMatrices; +import net.caffeinemc.mods.sodium.client.util.FogParameters; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; @@ -127,7 +128,7 @@ public class VoxyRenderSystem { ).mulLocal(makeProjectionMatrix(16, 16*3000)); } - public void renderOpaque(ChunkRenderMatrices matrices, double cameraX, double cameraY, double cameraZ) { + public void renderOpaque(ChunkRenderMatrices matrices, FogParameters fogParameters, double cameraX, double cameraY, double cameraZ) { if (IrisUtil.irisShadowActive()) { return; } @@ -164,11 +165,13 @@ public class VoxyRenderSystem { int[] dims = new int[4]; glGetIntegerv(GL_VIEWPORT, dims); var viewport = this.renderer.getViewport(); + viewport .setProjection(projection) .setModelView(new Matrix4f(matrices.modelView())) .setCamera(cameraX, cameraY, cameraZ) .setScreenSize(dims[2], dims[3]) + .setFogParameters(fogParameters) .update(); viewport.frameId++; @@ -195,7 +198,7 @@ public class VoxyRenderSystem { TimingStatistics.F.start(); - this.postProcessing.renderPost(projection, matrices.projection(), boundFB); + this.postProcessing.renderPost(viewport, matrices.projection(), boundFB); TimingStatistics.F.stop(); TimingStatistics.main.stop(); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/Viewport.java b/src/main/java/me/cortex/voxy/client/core/rendering/Viewport.java index 041dd537..cb06cdae 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/Viewport.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/Viewport.java @@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.rendering; import me.cortex.voxy.client.core.gl.GlBuffer; import me.cortex.voxy.client.core.rendering.util.HiZBuffer; +import net.caffeinemc.mods.sodium.client.util.FogParameters; import net.minecraft.util.math.MathHelper; import org.joml.*; @@ -29,6 +30,7 @@ public abstract class Viewport > { public double cameraX; public double cameraY; public double cameraZ; + public FogParameters fogParameters; public final Matrix4f MVP = new Matrix4f(); public final Vector3i section = new Vector3i(); @@ -75,6 +77,11 @@ public abstract class Viewport > { return (A) this; } + public A setFogParameters(FogParameters fogParameters) { + this.fogParameters = fogParameters; + return (A) this; + } + public A update() { //MVP this.projection.mul(this.modelView, this.MVP); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/post/FullscreenBlit.java b/src/main/java/me/cortex/voxy/client/core/rendering/post/FullscreenBlit.java index 1436e940..a1f6eb05 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/post/FullscreenBlit.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/post/FullscreenBlit.java @@ -3,6 +3,8 @@ package me.cortex.voxy.client.core.rendering.post; import me.cortex.voxy.client.core.gl.shader.Shader; import me.cortex.voxy.client.core.gl.shader.ShaderType; +import java.util.function.Function; + import static org.lwjgl.opengl.GL11C.GL_TRIANGLES; import static org.lwjgl.opengl.GL11C.glDrawArrays; import static org.lwjgl.opengl.GL30C.glBindVertexArray; @@ -13,9 +15,12 @@ public class FullscreenBlit { private final Shader shader; public FullscreenBlit(String fragId) { - this.shader = Shader.make() + this(fragId, (a)->a); + } + public FullscreenBlit(String fragId, Function, Shader.Builder> builder) { + this.shader = builder.apply((Shader.Builder) Shader.make() .add(ShaderType.VERTEX, "voxy:post/fullscreen.vert") - .add(ShaderType.FRAGMENT, fragId) + .add(ShaderType.FRAGMENT, fragId)) .compile(); } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java b/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java index 6f963333..c381909f 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/post/PostProcessing.java @@ -1,14 +1,14 @@ package me.cortex.voxy.client.core.rendering.post; +import me.cortex.voxy.client.config.VoxyConfig; import me.cortex.voxy.client.core.gl.GlFramebuffer; import me.cortex.voxy.client.core.gl.GlTexture; import me.cortex.voxy.client.core.gl.shader.Shader; import me.cortex.voxy.client.core.gl.shader.ShaderType; +import me.cortex.voxy.client.core.rendering.Viewport; import me.cortex.voxy.client.core.rendering.util.GlStateCapture; -import net.minecraft.client.util.math.MatrixStack; import org.joml.Matrix4f; import org.joml.Matrix4fc; -import org.lwjgl.opengl.GL11C; import static org.lwjgl.opengl.ARBComputeShader.glDispatchCompute; import static org.lwjgl.opengl.ARBShaderImageLoadStore.glBindImageTexture; @@ -20,6 +20,7 @@ import static org.lwjgl.opengl.GL43.GL_DEPTH_STENCIL_TEXTURE_MODE; import static org.lwjgl.opengl.GL45C.*; public class PostProcessing { + private final boolean useEnvFog = VoxyConfig.CONFIG.useEnvironmentalFog; private final GlFramebuffer framebuffer; private final GlFramebuffer framebufferSSAO; private int width; @@ -31,7 +32,8 @@ public class PostProcessing { private final FullscreenBlit setDepth0 = new FullscreenBlit("voxy:post/depth0.frag"); private final FullscreenBlit emptyBlit = new FullscreenBlit("voxy:post/noop.frag"); //private final FullscreenBlit blitTexture = new FullscreenBlit("voxy:post/blit_texture_cutout.frag"); - private final FullscreenBlit blitTexture = new FullscreenBlit("voxy:post/blit_texture_depth_cutout.frag"); + private final FullscreenBlit blitTexture = new FullscreenBlit("voxy:post/blit_texture_depth_cutout.frag", + a->a.defineIf("USE_ENV_FOG", useEnvFog)); private final Shader ssaoComp = Shader.make() .add(ShaderType.COMPUTE, "voxy:post/ssao.comp") .compile(); @@ -158,7 +160,7 @@ public class PostProcessing { //Executes the post processing and emits to whatever framebuffer is currently bound via a blit - public void renderPost(Matrix4f fromProjection, Matrix4fc tooProjection, int outputFB) { + public void renderPost(Viewport vp, Matrix4fc tooProjection, int outputFB) { glDisable(GL_STENCIL_TEST); @@ -172,12 +174,17 @@ public class PostProcessing { this.blitTexture.bind(); float[] data = new float[4*4]; - var mat = new Matrix4f(fromProjection).invert(); - mat.get(data); + new Matrix4f(vp.MVP).invert().get(data); glUniformMatrix4fv(2, false, data);//inverse fromProjection - tooProjection.get(data); + new Matrix4f(tooProjection).mul(vp.modelView).get(data); glUniformMatrix4fv(3, false, data);//tooProjection - + if (useEnvFog) { + float start = vp.fogParameters.environmentalStart(); + float end = vp.fogParameters.environmentalEnd(); + float invEndFogDelta = 1f/(end-start); + glUniform3f(4, vp.fogParameters.environmentalEnd()/2f, invEndFogDelta, start*invEndFogDelta); + glUniform3f(5, vp.fogParameters.red(), vp.fogParameters.green(), vp.fogParameters.blue()); + } glBindTextureUnit(0, this.didSSAO?this.colourSSAO.id:this.colour.id); diff --git a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinFogRenderer.java b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinFogRenderer.java index d91c2ca4..711daedc 100644 --- a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinFogRenderer.java +++ b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinFogRenderer.java @@ -15,11 +15,16 @@ public class MixinFogRenderer { @Redirect(method = "applyFog(Lnet/minecraft/client/render/Camera;IZLnet/minecraft/client/render/RenderTickCounter;FLnet/minecraft/client/world/ClientWorld;)Lorg/joml/Vector4f;", at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/fog/FogData;renderDistanceEnd:F", opcode = Opcodes.PUTFIELD), require = 0) private void voxy$modifyFog(FogData instance, float distance) { var vrs = (IGetVoxyRenderSystem) MinecraftClient.getInstance().worldRenderer; + if (VoxyConfig.CONFIG.renderVanillaFog || vrs == null || vrs.getVoxyRenderSystem() == null) { instance.renderDistanceEnd = distance; } else { + instance.renderDistanceStart = 999999999; instance.renderDistanceEnd = 999999999; - instance.environmentalEnd = 999999999; + if (!VoxyConfig.CONFIG.useEnvironmentalFog) { + instance.environmentalStart = 99999999; + instance.environmentalEnd = 99999999; + } } } } diff --git a/src/main/java/me/cortex/voxy/client/mixin/nvidium/MixinRenderPipeline.java b/src/main/java/me/cortex/voxy/client/mixin/nvidium/MixinRenderPipeline.java index 4a49bc1e..6637eadf 100644 --- a/src/main/java/me/cortex/voxy/client/mixin/nvidium/MixinRenderPipeline.java +++ b/src/main/java/me/cortex/voxy/client/mixin/nvidium/MixinRenderPipeline.java @@ -18,7 +18,7 @@ public class MixinRenderPipeline { private void voxy$injectRender(TerrainRenderPass pass, Viewport frustum, FogParameters fogParameters, ChunkRenderMatrices crm, double px, double py, double pz, CallbackInfo ci) { var renderer = ((IGetVoxyRenderSystem) MinecraftClient.getInstance().worldRenderer).getVoxyRenderSystem(); if (renderer != null) { - renderer.renderOpaque(crm, px, py, pz); + renderer.renderOpaque(crm, fogParameters, px, py, pz); } } } diff --git a/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinDefaultChunkRenderer.java b/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinDefaultChunkRenderer.java index 0ca86895..d244fca2 100644 --- a/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinDefaultChunkRenderer.java +++ b/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinDefaultChunkRenderer.java @@ -21,11 +21,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; public class MixinDefaultChunkRenderer { @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/ShaderChunkRenderer;end(Lnet/caffeinemc/mods/sodium/client/render/chunk/terrain/TerrainRenderPass;)V", shift = At.Shift.BEFORE)) - private void injectRender(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderListIterable renderLists, TerrainRenderPass renderPass, CameraTransform camera, FogParameters parameters, CallbackInfo ci) { + private void injectRender(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderListIterable renderLists, TerrainRenderPass renderPass, CameraTransform camera, FogParameters fogParameters, CallbackInfo ci) { if (renderPass == DefaultTerrainRenderPasses.CUTOUT) { var renderer = ((IGetVoxyRenderSystem) MinecraftClient.getInstance().worldRenderer).getVoxyRenderSystem(); if (renderer != null) { - renderer.renderOpaque(matrices, camera.x, camera.y, camera.z); + renderer.renderOpaque(matrices, fogParameters, camera.x, camera.y, camera.z); } } } diff --git a/src/main/resources/assets/voxy/lang/en_us.json b/src/main/resources/assets/voxy/lang/en_us.json index 6ccf31d6..d688d558 100644 --- a/src/main/resources/assets/voxy/lang/en_us.json +++ b/src/main/resources/assets/voxy/lang/en_us.json @@ -19,6 +19,9 @@ "voxy.config.general.renderDistance": "Render distance", "voxy.config.general.renderDistance.tooltip": "Render distance of voxy in chunks", + "voxy.config.general.environmental_fog": "Enable environmental fog", + "voxy.config.general.environmental_fog.tooltip": "Enables or disables voxy rendering environmental fog", + "voxy.config.general.vanilla_fog": "Enable vanilla fog", "voxy.config.general.vanilla_fog.tooltip": "Enables or disables vanilla fog effect", diff --git a/src/main/resources/assets/voxy/shaders/post/blit_texture_depth_cutout.frag b/src/main/resources/assets/voxy/shaders/post/blit_texture_depth_cutout.frag index 805e43ca..0b3c0487 100644 --- a/src/main/resources/assets/voxy/shaders/post/blit_texture_depth_cutout.frag +++ b/src/main/resources/assets/voxy/shaders/post/blit_texture_depth_cutout.frag @@ -4,6 +4,10 @@ layout(binding = 0) uniform sampler2D colourTex; layout(binding = 1) uniform sampler2D depthTex; layout(location = 2) uniform mat4 invProjMat; layout(location = 3) uniform mat4 projMat; +#ifdef USE_ENV_FOG +layout(location = 4) uniform vec3 endParams; +layout(location = 5) uniform vec3 fogColour; +#endif out vec4 colour; in vec2 UV; @@ -28,7 +32,16 @@ void main() { discard; } - depth = projDepth(rev3d(vec3(UV.xy, depth))); + vec3 point = rev3d(vec3(UV.xy, depth)); + + #ifdef USE_ENV_FOG + { + float fogLerp = max(fma(min(length(point.xyz), endParams.x),endParams.y,endParams.z),0);//512 is 32*16 which is the render distance in blocks + colour.rgb = mix(colour.rgb, fogColour, fogLerp); + } + #endif + + depth = projDepth(point); depth = min(1.0f-(2.0f/((1<<24)-1)), depth); depth = depth * 0.5f + 0.5f; depth = gl_DepthRange.diff * depth + gl_DepthRange.near;