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 919a2d5fd..2f4bad3b5 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 @@ -833,7 +833,7 @@ public class Config public static ConfigUIComment experimentalHeader = new ConfigUIComment.Builder().setParentConfigClass(Experimental.class).build(); public static ConfigEntry earthCurveRatio = new ConfigEntry.Builder() - .setMinDefaultMax(0, 0, 5000) + .setMinDefaultMax(-5000, 0, 5000) .comment("" + "This is the earth size ratio when applying the curvature shader effect. \n" + "Note: Enabling this feature may cause rendering bugs. \n" @@ -843,7 +843,7 @@ public class Config + "100 = 1 to 100 (63,710 blocks) \n" + "10000 = 1 to 10000 (637.1 blocks) \n" + "\n" - + "Note: Due to current limitations, the min value is 50 \n" + + "Note: Due to current limitations, the min value is ["+WorldCurvatureConfigEventHandler.MIN_VALID_CURVE_VALUE+"] \n" + "and the max value is 5000. Any values outside this range \n" + "will be set to 0 (disabled).") .addListener(WorldCurvatureConfigEventHandler.INSTANCE) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/WorldCurvatureConfigEventHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/WorldCurvatureConfigEventHandler.java index 2a8e0b8bc..2827e50e2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/WorldCurvatureConfigEventHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/WorldCurvatureConfigEventHandler.java @@ -35,7 +35,7 @@ public class WorldCurvatureConfigEventHandler implements IConfigListener { public static WorldCurvatureConfigEventHandler INSTANCE = new WorldCurvatureConfigEventHandler(); - private static final int MIN_VALID_CURVE_VALUE = 50; + public static final int MIN_VALID_CURVE_VALUE = 50; /** private since we only ever need one handler at a time */ @@ -52,6 +52,11 @@ public class WorldCurvatureConfigEventHandler implements IConfigListener // shouldn't update the UI, otherwise we may end up fighting the user Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.set(MIN_VALID_CURVE_VALUE); } + else if (curveRatio < 0 && curveRatio > -MIN_VALID_CURVE_VALUE) + { + // same as above, but in the negative direction + Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.set(-MIN_VALID_CURVE_VALUE); + } } 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 198430ad0..439534a1c 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 @@ -46,16 +46,14 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade public int uCombinedMatrix = -1; public int uModelOffset = -1; public int uWorldYOffset = -1; - public int uDitherDhRendering = -1; public int uMircoOffset = -1; - public int uEarthRadius = -1; - public int uLightMap = -1; - // Fog/Clip Uniforms + // fragment shader uniforms public int uClipDistance = -1; + public int uDitherDhRendering = -1; // Noise Uniforms public int uNoiseEnabled = -1; @@ -76,19 +74,16 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade public DhTerrainShaderProgram() { super( - () -> Shader.loadFile(Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get() != 0 - ? "shaders/curve.vert" - : "shaders/standard.vert", - false, new StringBuilder()).toString(), - () -> Shader.loadFile("shaders/flat_shaded.frag", false, new StringBuilder()).toString(), - "fragColor", new String[]{"vPosition", "color"}); + () -> Shader.loadFile("shaders/standard.vert", false, new StringBuilder()).toString(), + () -> Shader.loadFile("shaders/flat_shaded.frag", false, new StringBuilder()).toString(), + "fragColor", new String[]{"vPosition", "color"}); this.uCombinedMatrix = this.getUniformLocation("uCombinedMatrix"); this.uModelOffset = this.getUniformLocation("uModelOffset"); - this.uWorldYOffset = this.tryGetUniformLocation("uWorldYOffset"); - this.uDitherDhRendering = this.tryGetUniformLocation("uDitherDhRendering"); + this.uWorldYOffset = this.getUniformLocation("uWorldYOffset"); + this.uDitherDhRendering = this.getUniformLocation("uDitherDhRendering"); this.uMircoOffset = this.getUniformLocation("uMircoOffset"); - this.uEarthRadius = this.tryGetUniformLocation("uEarthRadius"); + this.uEarthRadius = this.getUniformLocation("uEarthRadius"); this.uLightMap = this.getUniformLocation("uLightMap"); @@ -178,12 +173,21 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade // setUniform(skyLightUniform, skyLight); this.setUniform(this.uLightMap, 0); // TODO this should probably be passed in - if (this.uWorldYOffset != -1) this.setUniform(this.uWorldYOffset, (float) renderParameters.worldYOffset); + this.setUniform(this.uWorldYOffset, (float) renderParameters.worldYOffset); - if (this.uDitherDhRendering != -1) this.setUniform(this.uDitherDhRendering, Config.Client.Advanced.Graphics.Quality.ditherDhFade.get()); + this.setUniform(this.uDitherDhRendering, Config.Client.Advanced.Graphics.Quality.ditherDhFade.get()); - if (this.uEarthRadius != -1) this.setUniform(this.uEarthRadius, - /*6371KM*/ 6371000.0f / Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get()); + float curveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get(); + if (curveRatio < -1.0f || curveRatio > 1.0f) + { + curveRatio = /*6371KM*/ 6371000.0f / curveRatio; + } + else + { + // disable curvature if the config value is between -1 and 1 + curveRatio = 0.0f; + } + this.setUniform(this.uEarthRadius, curveRatio); // Noise Uniforms this.setUniform(this.uNoiseEnabled, Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get()); diff --git a/core/src/main/resources/shaders/curve.vert b/core/src/main/resources/shaders/curve.vert deleted file mode 100644 index 8b8c96755..000000000 --- a/core/src/main/resources/shaders/curve.vert +++ /dev/null @@ -1,79 +0,0 @@ -#version 150 core - -in uvec4 vPosition; -out vec4 vPos; -in vec4 color; - -out vec4 vertexColor; -out vec3 vertexWorldPos; -out float vertexYPos; - -uniform bool uWhiteWorld; - -uniform mat4 uCombinedMatrix; -uniform vec3 uModelOffset; -uniform float uWorldYOffset; - -uniform int uWorldSkyLight; -uniform sampler2D uLightMap; -uniform float uMircoOffset; - -uniform float uEarthRadius; - -/** - * TODO in the future this and standard.vert should be merged together to prevent inconsistencies between the two - * - * Vertex Shader - * - * author: James Seibel - * author: TomTheFurry - * author: stduhpf - * updated: coolGi - * version: 24-1-2023 - */ -void main() -{ - vPos = vPosition; // This is so it can be passed to the fragment shader - - vertexWorldPos = vPosition.xyz + uModelOffset; - - vertexYPos = vPosition.y + uWorldYOffset; - - uint meta = vPosition.a; - - uint mirco = (meta & 0xFF00u) >> 8u; // mirco offset which is a xyz 2bit value - // 0b00 = no offset - // 0b01 = positive offset - // 0b11 = negative offset - // format is: 0b00zzyyxx - float mx = (mirco & 1u) != 0u ? uMircoOffset : 0.0; - mx = (mirco & 2u) != 0u ? -mx : mx; - float my = (mirco & 4u) != 0u ? uMircoOffset : 0.0; - my = (mirco & 8u) != 0u ? -my : my; - float mz = (mirco & 16u) != 0u ? uMircoOffset : 0.0; - mz = (mirco & 32u) != 0u ? -mz : mz; - vertexWorldPos.x += mx; - vertexWorldPos.y += my; - vertexWorldPos.z += mz; - - - // vertex transformation logic - stduhpf - float localRadius = uEarthRadius + vertexYPos; - float phi = length(vertexWorldPos.xz) / localRadius; - vertexWorldPos.y += (cos(phi) - 1.0) * localRadius; - vertexWorldPos.xz = vertexWorldPos.xz * sin(phi) / phi; - - - uint lights = meta & 0xFFu; - - float light2 = (mod(float(lights), 16.0) + 0.5) / 16.0; - float light = (float(lights / 16u) + 0.5) / 16.0; - vertexColor = vec4(texture(uLightMap, vec2(light, light2)).xyz, 1.0); - - if (!uWhiteWorld) - { - vertexColor *= color; - } - - gl_Position = uCombinedMatrix * vec4(vertexWorldPos, 1.0); -} diff --git a/core/src/main/resources/shaders/standard.vert b/core/src/main/resources/shaders/standard.vert index 0c841cf3b..f948f1708 100644 --- a/core/src/main/resources/shaders/standard.vert +++ b/core/src/main/resources/shaders/standard.vert @@ -17,27 +17,28 @@ uniform float uWorldYOffset; uniform sampler2D uLightMap; uniform float uMircoOffset; +uniform float uEarthRadius; /** - * TODO in the future this and curve.vert should be merged together to prevent inconsistencies between the two - * * Vertex Shader * * author: James Seibel - * updated: TomTheFurry + * author: TomTheFurry + * author: stduhpf * updated: coolGi - * version: 2023-6-25 + * + * version: 2025-12-22 */ void main() { vPos = vPosition; // This is so it can be passed to the fragment shader - + vertexWorldPos = vPosition.xyz + uModelOffset; - + vertexYPos = vPosition.y + uWorldYOffset; - + uint meta = vPosition.a; - + uint mirco = (meta & 0xFF00u) >> 8u; // mirco offset which is a xyz 2bit value // 0b00 = no offset // 0b01 = positive offset @@ -45,21 +46,34 @@ void main() // format is: 0b00zzyyxx float mx = (mirco & 1u)!=0u ? uMircoOffset : 0.0; mx = (mirco & 2u)!=0u ? -mx : mx; - float my = (mirco & 4u)!=0u ? uMircoOffset : 0.0; - my = (mirco & 8u)!=0u ? -my : my; + //float my = (mirco & 4u)!=0u ? uMircoOffset : 0.0; + //my = (mirco & 8u)!=0u ? -my : my; float mz = (mirco & 16u)!=0u ? uMircoOffset : 0.0; mz = (mirco & 32u)!=0u ? -mz : mz; - + + vertexWorldPos.x += mx; + //vertexWorldPos.y += my; + vertexWorldPos.z += mz; + + // apply the earth curvature if needed + if (uEarthRadius < -1.0f || uEarthRadius > 1.0f) + { + // vertex transformation logic - stduhpf + float localRadius = uEarthRadius + vertexYPos; + float phi = length(vertexWorldPos.xz) / localRadius; + vertexWorldPos.y += (cos(phi) - 1.0) * localRadius; + vertexWorldPos.xz = vertexWorldPos.xz * sin(phi) / phi; + } + uint lights = meta & 0xFFu; - - float light2 = (mod(float(lights), 16.0)+0.5) / 16.0; - float light = (float(lights/16u)+0.5) / 16.0; - vertexColor = vec4(texture(uLightMap, vec2(light, light2)).xyz, 1.0); + float skyLight = (float(lights/16u)+0.5) / 16.0; + float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0; + vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); if (!uIsWhiteWorld) { vertexColor *= color; } - - gl_Position = uCombinedMatrix * vec4(vertexWorldPos + vec3(mx, 0, mz), 1.0); + + gl_Position = uCombinedMatrix * vec4(vertexWorldPos, 1.0); }