From cdaf6892638f8db6187a164a6fb868d03b0a45fd Mon Sep 17 00:00:00 2001 From: AnotherCommander <another_commander@oolite.org> Date: Thu, 7 Mar 2019 20:51:10 +0100 Subject: [PATCH] Fixed black stripe at dark part of atmosphere circumference. Also, gamma corrected atmopshere. --- .../oolite-default-atmosphere.fragment | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/Resources/Shaders/oolite-default-atmosphere.fragment b/Resources/Shaders/oolite-default-atmosphere.fragment index 9c668c45..28ee6bf4 100644 --- a/Resources/Shaders/oolite-default-atmosphere.fragment +++ b/Resources/Shaders/oolite-default-atmosphere.fragment @@ -37,7 +37,7 @@ varying vec3 vLight1Vector; const vec3 biasColor = vec3(0.0, 0.0, 1.0); const vec3 kTerminatorThreshold = vec3(0.105, 0.18, 0.28); // old: vec3(0.1, 0.105, 0.12); const float kFresnelExponent = 4.0; -const float biasColorMixRatio = 0.1; +const float biasColorMixRatio = 0.35; void main() @@ -51,11 +51,12 @@ void main() vec3 diffuseColor = DIFFUSE_LIGHT; float NdotV = clamp(dot(normal, eyeVector), 0.0, 1.0); - + float NdotL = max(0.0, dot(light1Vector, normal)); + float atmDistance = length(atmPosition.xyz); float minDistance = atmRadius + 3500.0; float magicDistance = atmDistance - minDistance; - float cosThreshold = 0.14; // 81.95 deg + float cosThreshold = 0.15; // 81.37 deg float newOpacityExponent = 3.0; // the outer atmosphere rim does not follow exactly the curvature of the planet for small radii @@ -70,13 +71,12 @@ void main() // mix in some light blue color totalColor += diffuseColor * vec3(0.85, 0.85, 1.0); - // create a fresnel torus around the planet vec3 fresnel = vec3(pow(1.0 - (NdotV * 0.3), kFresnelExponent)); - // get the fresnel lit up from the correct direction - vec3 invLight = vec3(dot(light1Vector, normal)); - totalColor *= dot(normalize(fresnel), invLight) * - mix(totalColor, biasColor, biasColorMixRatio) * + // mix the bias color now + totalColor *= mix(totalColor, biasColor, biasColorMixRatio) * + // uncomment below for fresnel to affect atmosphere color + //dot(normalize(fresnel), vec3(NdotL)) * clamp(totalColor, vec3(0.0), diffuseColor); // magic herebelow - painting the orange-reddish tinted terminator @@ -92,11 +92,23 @@ void main() float quant = atmDistance < (minDistance + 2000.0) ? magicDistance / 2000.0 : 1.0; + // create a fresnel torus around the planet - opacity is proportional to it + // multiply NdotV by a constant less than 1.0 to create haze + //vec3 fresnel = vec3(pow(1.0 - (NdotV * 0.3), kFresnelExponent)); + // calculate the final opacity, special handling for // angles > arccos(cosThreshold) to fade atmosphere out at its edge - float newOpacity = quant * (NdotV > cosThreshold ? + float newOpacity = quant * max(0.01, NdotL) * (NdotV > cosThreshold ? fresnel.r * cosThreshold / NdotV : pow(NdotV / cosThreshold, newOpacityExponent)); + // all above calculations were done in linear space - tonemap & go to sRGB for display + // using Jim Hejl's filmic tonemapping and gamma correction approximation. + // Normally this would require HDR, but I think it works extremely well in Oolite. + // Formula taken from https://www.gdcvault.com/play/1012351/Uncharted-2-HDR + // jump to 27:40 in the video. Note the pow 1.0/2.2 is baked into these numbers + vec3 x = max(vec3(0.0), totalColor - 0.004); + totalColor = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); + gl_FragColor = vec4(totalColor, newOpacity); }