diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderProgram.java index 83bbf669a..cecf49059 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderProgram.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderProgram.java @@ -54,6 +54,14 @@ public class LodRenderProgram extends ShaderProgram public final int lightMapUniform; + // Fog Uniforms + public final int fogColorUniform; + public final int fogScaleUniform; + public final int fogVerticalScaleUniform; + public final int nearFogStartUniform; + public final int nearFogLengthUniform;; + public final int fullFogModeUniform; + // Noise Uniforms public final int noiseEnabledUniform; public final int noiseStepsUniform; @@ -64,11 +72,10 @@ public class LodRenderProgram extends ShaderProgram // This will bind VertexAttribute public LodRenderProgram(LodFogConfig fogConfig) { - super( - fogConfig.earthCurveRatio!=0 ? VERTEX_CURVE_SHADER_PATH : VERTEX_SHADER_PATH, - FRAGMENT_SHADER_PATH, - "fragColor", new String[] { "vPosition", "color" } - ); + super(() -> Shader.loadFile(fogConfig.earthCurveRatio!=0 ? VERTEX_CURVE_SHADER_PATH : VERTEX_SHADER_PATH, + false, new StringBuilder()).toString(), + () -> fogConfig.loadAndProcessFragShader(FRAGMENT_SHADER_PATH, false).toString(), + "fragColor", new String[] { "vPosition", "color" }); this.fogConfig = fogConfig; combinedMatUniform = getUniformLocation("combinedMatrix"); @@ -79,6 +86,15 @@ public class LodRenderProgram extends ShaderProgram lightMapUniform = getUniformLocation("lightMap"); + // Fog Uniforms + fullFogModeUniform = getUniformLocation("fullFogMode"); + fogColorUniform = getUniformLocation("fogColor"); + fogScaleUniform = tryGetUniformLocation("fogScale"); + fogVerticalScaleUniform = tryGetUniformLocation("fogVerticalScale"); + // near + nearFogStartUniform = tryGetUniformLocation("nearFogStart"); + nearFogLengthUniform = tryGetUniformLocation("nearFogLength"); + // Noise Uniforms noiseEnabledUniform = getUniformLocation("noiseEnabled"); noiseStepsUniform = getUniformLocation("noiseSteps"); @@ -160,6 +176,17 @@ public class LodRenderProgram extends ShaderProgram setUniform(lightMapUniform, lightmapBindPoint); if (worldYOffsetUniform != -1) setUniform(worldYOffsetUniform, (float)worldYOffset); + + // Fog + setUniform(fullFogModeUniform, fullFogMode ? 1 : 0); + setUniform(fogColorUniform, fogColor); + + float nearFogLen = vanillaDrawDistance * 0.2f / lodDrawDistance; + float nearFogStart = vanillaDrawDistance * (VERSION_CONSTANTS.isVanillaRenderedChunkSquare() ? (float)Math.sqrt(2.) : 1.f) / lodDrawDistance; + if (nearFogStartUniform != -1) setUniform(nearFogStartUniform, nearFogStart); + if (nearFogLengthUniform != -1) setUniform(nearFogLengthUniform, nearFogLen); + if (fogScaleUniform != -1) setUniform(fogScaleUniform, 1.f/lodDrawDistance); + if (fogVerticalScaleUniform != -1) setUniform(fogVerticalScaleUniform, 1.f/worldHeight); } public void setModelPos(Vec3f modelPos) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 6f5c571a0..f622276af 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -256,7 +256,7 @@ public class LodRenderer SSAORenderer.INSTANCE.render(partialTicks); } { - FogShader.INSTANCE.render(partialTicks); +// FogShader.INSTANCE.render(partialTicks); // DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker } diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index a8a092321..0252c0b4c 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -1,4 +1,3 @@ -#version 150 core in vec4 vertexColor; in vec3 vertexWorldPos; @@ -7,12 +6,45 @@ in vec4 vPos; out vec4 fragColor; +// Fog Uniforms +uniform float fogScale; +uniform float fogVerticalScale; +uniform float nearFogStart; +uniform float nearFogLength; +uniform int fullFogMode; + // Noise Uniforms uniform bool noiseEnabled; uniform int noiseSteps; uniform float noiseIntensity; uniform int noiseDropoff; +/* ========MARCO DEFINED BY RUNTIME CODE GEN========= + +float farFogStart; +float farFogLength; +float farFogMin; +float farFogRange; +float farFogDensity; + +float heightFogStart; +float heightFogLength; +float heightFogMin; +float heightFogRange; +float heightFogDensity; +*/ + +uniform vec4 fogColor; + +// method definitions +// ==== The below 5 methods will be run-time generated. ==== +float getNearFogThickness(float dist); +float getFarFogThickness(float dist); +float getHeightFogThickness(float dist); +float calculateFarFogDepth(float horizontal, float dist, float nearFogStart); +float calculateHeightFogDepth(float vertical, float realY); +float mixFogThickness(float near, float far, float height); +// ========================================================= float fade(float value, float start, float end) { return (clamp(value,start,end)-start)/(end-start); @@ -64,7 +96,7 @@ vec3 HSV2RGB(vec3 c) { */ void main() { - fragColor = vertexColor; + fragColor = vertexColor; // TODO: Move into its own function instead of in an if statement @@ -72,9 +104,9 @@ void main() vec3 vertexNormal = normalize(cross(dFdx(vPos.xyz), dFdy(vPos.xyz))); // This bit of code is required to fix the vertex position problem cus of floats in the verted world position varuable vec3 fixedVPos = vec3( - vPos.x - vertexNormal.x * 0.001, - vPos.y - vertexNormal.y * 0.001, - vPos.z - vertexNormal.z * 0.001 + vPos.x - vertexNormal.x * 0.001, + vPos.y - vertexNormal.y * 0.001, + vPos.z - vertexNormal.z * 0.001 ); @@ -84,9 +116,9 @@ void main() // Random value for each position float randomValue = rand(vec3( - quantize(fixedVPos.x, noiseSteps), - quantize(fixedVPos.y, noiseSteps), - quantize(fixedVPos.z, noiseSteps) + quantize(fixedVPos.x, noiseSteps), + quantize(fixedVPos.y, noiseSteps), + quantize(fixedVPos.z, noiseSteps) )) * 2. * noiseAmplification - noiseAmplification; @@ -97,22 +129,22 @@ void main() // Clamps it and turns it back into a vec4 if (noiseDropoff == 0) - fragColor = vec4( - clamp(newCol.r, 0., 1.), - clamp(newCol.g, 0., 1.), - clamp(newCol.b, 0., 1.), - fragColor.w - ); + fragColor = vec4( + clamp(newCol.r, 0., 1.), + clamp(newCol.g, 0., 1.), + clamp(newCol.b, 0., 1.), + fragColor.w + ); else - fragColor = mix( - vec4( - clamp(newCol.r, 0., 1.), - clamp(newCol.g, 0., 1.), - clamp(newCol.b, 0., 1.), - fragColor.w - ), fragColor, - clamp(length(vertexWorldPos) / noiseDropoff, 0., 1.) // The further away it gets, the less noise gets applied - ); + fragColor = mix( + vec4( + clamp(newCol.r, 0., 1.), + clamp(newCol.g, 0., 1.), + clamp(newCol.b, 0., 1.), + fragColor.w + ), fragColor, + clamp(length(vertexWorldPos) / noiseDropoff, 0., 1.) // The further away it gets, the less noise gets applied + ); // For testing // if (fragColor.r != 69420.) { @@ -123,4 +155,48 @@ void main() // fragColor.w); // } } + + // TODO: Move into its own function instead of in an if statement + // This is so that it can apply after the SSAO (work for this has started in the FogShader file and fog/fog.frag shader) + if (fullFogMode != 0) { + fragColor = vec4(fogColor.rgb, 1.0); + } else { + // TODO: add a white texture to support Optifine shaders + //vec4 textureColor = texture(texImage, textureCoord); + //fragColor = vertexColor * textureColor; + + float horizontalDist = length(vertexWorldPos.xz) * fogScale; + float heightDist = calculateHeightFogDepth( + vertexWorldPos.y, vertexYPos) * fogVerticalScale; + float farDist = calculateFarFogDepth(horizontalDist, + length(vertexWorldPos.xyz) * fogScale, nearFogStart); + + float nearFogThickness = getNearFogThickness(horizontalDist); + float farFogThickness = getFarFogThickness(farDist); + float heightFogThickness = getHeightFogThickness(heightDist); + float mixedFogThickness = clamp(mixFogThickness( + nearFogThickness, farFogThickness, heightFogThickness), 0.0, 1.0); + + fragColor = mix(fragColor, vec4(fogColor.rgb, 1.0), mixedFogThickness); + } +} + + + +// Are these still needed? +float linearFog(float x, float fogStart, float fogLength, float fogMin, float fogRange) { + x = clamp((x-fogStart)/fogLength, 0.0, 1.0); + return fogMin + fogRange * x; +} + +float exponentialFog(float x, float fogStart, float fogLength, +float fogMin, float fogRange, float fogDensity) { + x = max((x-fogStart)/fogLength, 0.0) * fogDensity; + return fogMin + fogRange - fogRange/exp(x); +} + +float exponentialSquaredFog(float x, float fogStart, float fogLength, +float fogMin, float fogRange, float fogDensity) { + x = max((x-fogStart)/fogLength, 0.0) * fogDensity; + return fogMin + fogRange - fogRange/exp(x*x); } \ No newline at end of file