Add dithered DH fading, double pass fading, and fix LOD clouds
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Boolean> twoPassVanillaFade = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "TODO \n"
|
||||
+ "")
|
||||
.setPerformance(EConfigEntryPerformance.LOW)
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> ditherDhFade = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "TODO \n"
|
||||
+ "")
|
||||
.setPerformance(EConfigEntryPerformance.LOW)
|
||||
.build();
|
||||
|
||||
// TODO fixme
|
||||
|
||||
+16
-12
@@ -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());
|
||||
|
||||
|
||||
+5
-2
@@ -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
|
||||
|
||||
+1
-3
@@ -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,
|
||||
|
||||
+39
-15
@@ -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
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user