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 86e7422a2..4d3d97cc9 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 @@ -196,10 +196,8 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade // Clip Uniform float dhNearClipDistance = RenderUtil.getNearClipPlaneDistanceInBlocks(renderParameters.partialTicks); - // TODO a different multiplier might be necessary - // this is to try and allow the fragment culling to go farther than the near clip plane. - // Currently this only works for certain FOV/screen ratio combos. - dhNearClipDistance *= 2.0f; + // this added value prevents the near clip plane and discard circle from touching, which looks bad + dhNearClipDistance += 16f; // if the player is very high up and the near clip plane has been modified, disable the distance clipping // we're high enough that nothing will render on top of the player and this can cause issues otherwise if (RenderUtil.getHeightBasedNearClipOverride() != -1) 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 69df93e4a..65170c412 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 @@ -110,10 +110,15 @@ public class FadeShader extends AbstractShaderRenderer if (this.inverseDhMvmProjMatrix != null) this.shader.setUniform(this.uDhInvMvmProj, this.inverseDhMvmProjMatrix); - int vanillaBlockRenderDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; + float dhNearClipDistance = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); + // this added value prevents the near clip plane and discard circle from touching, which looks bad + dhNearClipDistance += 16f; + // measured in blocks - float fadeStartDistance = vanillaBlockRenderDistance * 0.5f; - float fadeEndDistance = vanillaBlockRenderDistance * 0.8f; + // these multipliers in James' tests should provide a fairly smooth transition + // without having underdraw issues + float fadeStartDistance = dhNearClipDistance * 1.5f; + float fadeEndDistance = dhNearClipDistance * 1.9f; if (this.uStartFadeBlockDistance != -1) this.shader.setUniform(this.uStartFadeBlockDistance, fadeStartDistance); if (this.uEndFadeBlockDistance != -1) this.shader.setUniform(this.uEndFadeBlockDistance, fadeEndDistance); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java index 3fe5c9263..9c484fa94 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java @@ -114,7 +114,7 @@ public class RenderUtil // modify based on the player's FOV double fov = MC_RENDER.getFov(partialTicks); - double aspectRatio = (double) MC_RENDER.getScreenWidth() / MC_RENDER.getScreenHeight(); + double aspectRatio = (double) MC_RENDER.getTargetFrameBufferViewportWidth() / MC_RENDER.getTargetFrameBufferViewportHeight(); // source: https://stackoverflow.com/questions/8101119/how-do-i-methodically-choose-the-near-clip-plane-distance-for-a-perspective-proj/8101234#8101234 return (float) (nearClipPlane diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index cd8e75166..ee8415afd 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -61,9 +61,8 @@ 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); -} +float worldPosToNoise(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); } + void main() @@ -74,18 +73,20 @@ void main() if (uDitherDhRendering) { - // only for opaque pass // - // Dither out the fragment based on distance and noise. - float noiseValue = random(vertexWorldPos.xy); + // Dithering is used since it works for both opaque and transparent rendering + + // noise increases as the distance increases + float worldNoise = worldPosToNoise(vertexWorldPos.xy); float fadeStep = smoothstep(uClipDistance, uClipDistance * 1.5, viewDist); - if (fadeStep < noiseValue) + if (fadeStep < worldNoise) { - discard; // Discard if the fadeStep is less than the noise. + discard; } - // only for transparent pass // + // this logic could be used for transparent rendering, + // however we don't currently have the logic needed to differentiate opaque/transparenet rendering //float fadeStep = smoothstep(uClipDistance, uClipDistance * 2, viewDist); //fragColor.a = min(fadeStep, fragColor.a); }