diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index b5d59827e..202820880 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -24,6 +24,7 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure; +import com.seibel.distanthorizons.core.level.DhClientLevel; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.renderer.FadeRenderer; @@ -552,11 +553,20 @@ public class ClientApi } /** should be called after DH and MC finish rendering so we can smooth the transition between the two */ - public void renderFade(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) + public void renderFadeOpaque(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) + { + if (Config.Client.Advanced.Graphics.Quality.fadeOutVanillaRendering.get() + && Config.Client.Advanced.Graphics.Quality.twoPassVanillaFade.get()) + { + FadeRenderer.INSTANCE.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, level); + } + } + /** should be called after DH and MC finish rendering so we can smooth the transition between the two */ + public void renderFade(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) { if (Config.Client.Advanced.Graphics.Quality.fadeOutVanillaRendering.get()) { - FadeRenderer.INSTANCE.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks); + FadeRenderer.INSTANCE.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, level); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index fcc268e79..f53156349 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -262,7 +262,22 @@ public class Config + "smoothing the transition between Distant Horizons and vanilla rendering. \n" + "") .setPerformance(EConfigEntryPerformance.LOW) - .addListener(ReloadLodsConfigEventHandler.INSTANCE) + .build(); + + public static ConfigEntry twoPassVanillaFade = new ConfigEntry.Builder() + .set(true) + .comment("" + + "TODO \n" + + "") + .setPerformance(EConfigEntryPerformance.LOW) + .build(); + + public static ConfigEntry ditherDhFade = new ConfigEntry.Builder() + .set(true) + .comment("" + + "TODO \n" + + "") + .setPerformance(EConfigEntryPerformance.LOW) .build(); // TODO fixme diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java index 058b6b63e..86e7422a2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java @@ -43,27 +43,28 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade public final AbstractVertexAttribute vao; // Uniforms - public final int uCombinedMatrix; - public final int uModelOffset; - public final int uWorldYOffset; + public int uCombinedMatrix = -1; + public int uModelOffset = -1; + public int uWorldYOffset = -1; + public int uDitherDhRendering = -1; - public final int uMircoOffset; + public int uMircoOffset = -1; - public final int uEarthRadius; + public int uEarthRadius = -1; - public final int uLightMap; + public int uLightMap = -1; // Fog/Clip Uniforms - public final int uClipDistance; + public int uClipDistance = -1; // Noise Uniforms - public final int uNoiseEnabled; - public final int uNoiseSteps; - public final int uNoiseIntensity; - public final int uNoiseDropoff; + public int uNoiseEnabled = -1; + public int uNoiseSteps = -1; + public int uNoiseIntensity = -1; + public int uNoiseDropoff = -1; // Debug Uniform - public final int uWhiteWorld; + public int uWhiteWorld = -1; @@ -85,6 +86,7 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade this.uCombinedMatrix = this.getUniformLocation("uCombinedMatrix"); this.uModelOffset = this.getUniformLocation("uModelOffset"); this.uWorldYOffset = this.tryGetUniformLocation("uWorldYOffset"); + this.uDitherDhRendering = this.tryGetUniformLocation("uDitherDhRendering"); this.uMircoOffset = this.getUniformLocation("uMircoOffset"); this.uEarthRadius = this.tryGetUniformLocation("uEarthRadius"); @@ -187,6 +189,8 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade if (this.uWorldYOffset != -1) this.setUniform(this.uWorldYOffset, (float) renderParameters.worldYOffset); + if (this.uDitherDhRendering != -1) this.setUniform(this.uDitherDhRendering, Config.Client.Advanced.Graphics.Quality.ditherDhFade.get()); + // Debug this.setUniform(this.uWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FadeRenderer.java index 8db4b8302..3fe9159c6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FadeRenderer.java @@ -20,6 +20,7 @@ package com.seibel.distanthorizons.core.render.renderer; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.level.DhClientLevel; import com.seibel.distanthorizons.core.render.glObject.GLState; import com.seibel.distanthorizons.core.render.renderer.shaders.FadeApplyShader; import com.seibel.distanthorizons.core.render.renderer.shaders.FadeShader; @@ -27,6 +28,7 @@ import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.opengl.GL32; @@ -106,7 +108,7 @@ public class FadeRenderer // render // //========// - public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) + public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) { IProfilerWrapper profiler = MC_CLIENT.getProfiler(); profiler.pop(); // get out of "terrain" @@ -134,7 +136,8 @@ public class FadeRenderer FadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; - FadeShader.INSTANCE.setProjectionMatrix(mcModelViewMatrix, mcProjectionMatrix); + FadeShader.INSTANCE.setProjectionMatrix(mcModelViewMatrix, mcProjectionMatrix, partialTicks); + FadeShader.INSTANCE.setLevelMaxHeight(level.getMaxHeight()); FadeShader.INSTANCE.render(partialTicks); // restored so we can write the fade texture to the main frame buffer diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java index 68e4ae688..80aca8663 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java @@ -101,9 +101,7 @@ public class FadeApplyShader extends AbstractShaderRenderer @Override protected void onRender() { - GL32.glEnable(GL32.GL_BLEND); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); + GL32.glDisable(GL32.GL_BLEND); // Depth testing must be disabled otherwise this application shader won't apply anything. // setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually, diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeShader.java index c3a1f0034..69df93e4a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeShader.java @@ -25,6 +25,7 @@ import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.renderer.LodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -40,20 +41,26 @@ public class FadeShader extends AbstractShaderRenderer public int frameBuffer = -1; - private Mat4f inverseMvmProjMatrix; + private Mat4f inverseMcMvmProjMatrix; + private Mat4f inverseDhMvmProjMatrix; + private float levelMaxHeight; // Uniforms public int uMcDepthTexture = -1; + public int uDhDepthTexture = -1; public int uCombinedMcDhColorTexture = -1; public int uDhColorTexture = -1; /** Inverted Model View Projection matrix */ - public int uInvMvmProj = -1; + public int uDhInvMvmProj = -1; + public int uMcInvMvmProj = -1; public int uStartFadeBlockDistance = -1; public int uEndFadeBlockDistance = -1; + public int uMaxLevelHeight = -1; + @@ -75,15 +82,19 @@ public class FadeShader extends AbstractShaderRenderer // because disabling fade can cause the GLSL to optimize out most (if not all) uniforms // near fade - this.uInvMvmProj = this.shader.tryGetUniformLocation("uInvMvmProj"); + this.uDhInvMvmProj = this.shader.tryGetUniformLocation("uDhInvMvmProj"); + this.uMcInvMvmProj = this.shader.tryGetUniformLocation("uMcInvMvmProj"); this.uMcDepthTexture = this.shader.tryGetUniformLocation("uMcDepthMap"); + this.uDhDepthTexture = this.shader.tryGetUniformLocation("uDhDepthTexture"); this.uCombinedMcDhColorTexture = this.shader.tryGetUniformLocation("uCombinedMcDhColorTexture"); this.uDhColorTexture = this.shader.tryGetUniformLocation("uDhColorTexture"); this.uStartFadeBlockDistance = this.shader.tryGetUniformLocation("uStartFadeBlockDistance"); this.uEndFadeBlockDistance = this.shader.tryGetUniformLocation("uEndFadeBlockDistance"); + this.uMaxLevelHeight = this.shader.tryGetUniformLocation("uMaxLevelHeight"); + } @@ -95,10 +106,8 @@ public class FadeShader extends AbstractShaderRenderer @Override protected void onApplyUniforms(float partialTicks) { - if (this.inverseMvmProjMatrix != null) - { - this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix); - } + if (this.inverseMcMvmProjMatrix != null) this.shader.setUniform(this.uMcInvMvmProj, this.inverseMcMvmProjMatrix); + if (this.inverseDhMvmProjMatrix != null) this.shader.setUniform(this.uDhInvMvmProj, this.inverseDhMvmProjMatrix); int vanillaBlockRenderDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; @@ -108,16 +117,27 @@ public class FadeShader extends AbstractShaderRenderer if (this.uStartFadeBlockDistance != -1) this.shader.setUniform(this.uStartFadeBlockDistance, fadeStartDistance); if (this.uEndFadeBlockDistance != -1) this.shader.setUniform(this.uEndFadeBlockDistance, fadeEndDistance); + + if (this.uMaxLevelHeight != -1) this.shader.setUniform(this.uMaxLevelHeight, this.levelMaxHeight); } - public void setProjectionMatrix(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix) + public void setProjectionMatrix(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) { - Mat4f inverseModelViewProjectionMatrix = new Mat4f(mcProjectionMatrix); - inverseModelViewProjectionMatrix.multiply(mcModelViewMatrix); - inverseModelViewProjectionMatrix.invert(); + Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(mcProjectionMatrix); + inverseMcModelViewProjectionMatrix.multiply(mcModelViewMatrix); + inverseMcModelViewProjectionMatrix.invert(); + this.inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix; - this.inverseMvmProjMatrix = inverseModelViewProjectionMatrix; + + Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix, partialTicks); + Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix); + + Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix); + inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix); + inverseDhModelViewProjectionMatrix.invert(); + this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix; } + public void setLevelMaxHeight(int levelMaxHeight) { this.levelMaxHeight = levelMaxHeight; } @@ -140,12 +160,16 @@ public class FadeShader extends AbstractShaderRenderer GL32.glUniform1i(this.uMcDepthTexture, 0); GL32.glActiveTexture(GL32.GL_TEXTURE1); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getColorTextureId()); - GL32.glUniform1i(this.uCombinedMcDhColorTexture, 1); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId()); + GL32.glUniform1i(this.uDhDepthTexture, 1); GL32.glActiveTexture(GL32.GL_TEXTURE2); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getColorTextureId()); + GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2); + + GL32.glActiveTexture(GL32.GL_TEXTURE3); GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId()); - GL32.glUniform1i(this.uDhColorTexture, 2); + GL32.glUniform1i(this.uDhColorTexture, 3); // this is necessary for MC 1.16 (IE Legacy OpenGL) // otherwise the framebuffer isn't cleared correctly and the fade smears across the screen diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json index d39a5b01f..bae2b07fc 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -118,6 +118,12 @@ "Fade Out Vanilla Rendering", "distanthorizons.config.client.advanced.graphics.quality.fadeOutVanillaRendering.@tooltip": "If true vanilla chunks will fade out the further away they are\nsmoothing the transition between Distant Horizons and vanilla rendering.", + + "distanthorizons.config.client.advanced.graphics.quality.twoPassVanillaFade": + "Two Pass Vanilla Fade", + "distanthorizons.config.client.advanced.graphics.quality.ditherDhFade": + "Dither DH Near Rendering", + "distanthorizons.config.client.advanced.graphics.quality.lodBiomeBlending": "Biome Blending", "distanthorizons.config.client.advanced.graphics.quality.lodBiomeBlending.@tooltip": diff --git a/core/src/main/resources/shaders/fade/fade.frag b/core/src/main/resources/shaders/fade/fade.frag index 0d90b2fdd..4e9c5d6e0 100644 --- a/core/src/main/resources/shaders/fade/fade.frag +++ b/core/src/main/resources/shaders/fade/fade.frag @@ -5,23 +5,26 @@ in vec2 TexCoord; out vec4 fragColor; uniform sampler2D uMcDepthTexture; +uniform sampler2D uDhDepthTexture; uniform sampler2D uCombinedMcDhColorTexture; uniform sampler2D uDhColorTexture; // inverted model view matrix and projection matrix -uniform mat4 uInvMvmProj; +uniform mat4 uDhInvMvmProj; +uniform mat4 uMcInvMvmProj; uniform float uStartFadeBlockDistance; uniform float uEndFadeBlockDistance; +uniform float uMaxLevelHeight; -vec3 calcViewPosition(float fragmentDepth) +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) { // normalized device coordinates vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); ndc.xyz = ndc.xyz * 2.0 - 1.0; - vec4 eyeCoord = uInvMvmProj * ndc; + vec4 eyeCoord = invMvmProj * ndc; return eyeCoord.xyz / eyeCoord.w; } @@ -44,21 +47,27 @@ void main() dhColor = combinedMcDhColor; } + float mcFragmentDepth = texture(uMcDepthTexture, TexCoord).r; + float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; + vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj); - + // this is a work around to prevent MC clouds rendering behind DH clouds + if (dhVertexWorldPos.y > uMaxLevelHeight) + { + fragColor = vec4(combinedMcDhColor.rgb, 0.0); + } // a fragment depth of "1" means the fragment wasn't drawn to, // we only want to fade vanilla rendered objects, not to the sky or LODs - float mcFragmentDepth = texture(uMcDepthTexture, TexCoord).r; - if (mcFragmentDepth < 1.0) + else if (mcFragmentDepth < 1.0) { // fade based on distance from the camera - vec3 vertexWorldPos = calcViewPosition(mcFragmentDepth); - float fragmentDistance = length(vertexWorldPos.xzy); + vec3 mcVertexWorldPos = calcViewPosition(mcFragmentDepth, uMcInvMvmProj); + float mcFragmentDistance = length(mcVertexWorldPos.xzy); // Smoothly transition between combinedMcDhColor and uDhColorTexture // as the depth increases from the camera - float fadeStep = smoothstep(uStartFadeBlockDistance, uEndFadeBlockDistance, fragmentDistance); + float fadeStep = smoothstep(uStartFadeBlockDistance, uEndFadeBlockDistance, mcFragmentDistance); fragColor = mix(combinedMcDhColor, dhColor, fadeStep); fragColor.a = 1.0; // TODO is setting the alpha needed? } diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index 0bfe32461..cd8e75166 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -16,6 +16,7 @@ uniform bool uNoiseEnabled; uniform int uNoiseSteps; uniform float uNoiseIntensity; uniform int uNoiseDropoff; +uniform bool uDitherDhRendering; // The random functions for diffrent dimentions @@ -60,16 +61,40 @@ void applyNoise(inout vec4 fragColor, const in float viewDist) fragColor.rgb = newCol; } - +float random(vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + void main() { fragColor = vertexColor; float viewDist = length(vertexWorldPos); - if (viewDist < uClipDistance && uClipDistance > 0.0) + + if (uDitherDhRendering) { - discard; + // only for opaque pass // + + // Dither out the fragment based on distance and noise. + float noiseValue = random(vertexWorldPos.xy); + float fadeStep = smoothstep(uClipDistance, uClipDistance * 1.5, viewDist); + if (fadeStep < noiseValue) + { + discard; // Discard if the fadeStep is less than the noise. + } + + + // only for transparent pass // + //float fadeStep = smoothstep(uClipDistance, uClipDistance * 2, viewDist); + //fragColor.a = min(fadeStep, fragColor.a); + } + else + { + if (viewDist < uClipDistance && uClipDistance > 0.0) + { + discard; + } } if (uNoiseEnabled)