From 9057e9a937ff2f9bc6b4ac292367dea375e5e417 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 16 Nov 2016 09:39:52 -0500 Subject: [PATCH] Updated atmosphere module from NYU data. --- .../scene/atmosphereearth/atmosphereearth.mod | 2 +- modules/atmosphere/CMakeLists.txt | 6 +- modules/atmosphere/atmospheremodule.cpp | 4 +- .../base/shaders/atmosphere_deferred_fs.glsl | 629 ------------------ .../base/shaders/atmosphere_deferred_vs.glsl | 48 -- modules/base/shaders/atmosphere_fs.glsl | 505 -------------- modules/base/shaders/atmosphere_vs.glsl | 86 --- modules/base/shaders/deltaE_calc_fs.glsl | 41 -- modules/base/shaders/deltaJ_calc_fs.glsl | 186 ------ modules/base/shaders/deltaS_calc_fs.glsl | 45 -- .../base/shaders/inScattering_calc_fs.glsl | 208 ------ .../shaders/inScattering_sup_calc_fs.glsl | 149 ----- modules/base/shaders/irradiance_calc_fs.glsl | 57 -- .../base/shaders/irradiance_sup_calc_fs.glsl | 96 --- .../base/shaders/transmittance_calc_fs.glsl | 113 ---- 15 files changed, 7 insertions(+), 2168 deletions(-) delete mode 100644 modules/base/shaders/atmosphere_deferred_fs.glsl delete mode 100644 modules/base/shaders/atmosphere_deferred_vs.glsl delete mode 100644 modules/base/shaders/atmosphere_fs.glsl delete mode 100644 modules/base/shaders/atmosphere_vs.glsl delete mode 100644 modules/base/shaders/deltaE_calc_fs.glsl delete mode 100644 modules/base/shaders/deltaJ_calc_fs.glsl delete mode 100644 modules/base/shaders/deltaS_calc_fs.glsl delete mode 100644 modules/base/shaders/inScattering_calc_fs.glsl delete mode 100644 modules/base/shaders/inScattering_sup_calc_fs.glsl delete mode 100644 modules/base/shaders/irradiance_calc_fs.glsl delete mode 100644 modules/base/shaders/irradiance_sup_calc_fs.glsl delete mode 100644 modules/base/shaders/transmittance_calc_fs.glsl diff --git a/data/scene/atmosphereearth/atmosphereearth.mod b/data/scene/atmosphereearth/atmosphereearth.mod index 6a7de0f845..53ad2d73c4 100644 --- a/data/scene/atmosphereearth/atmosphereearth.mod +++ b/data/scene/atmosphereearth/atmosphereearth.mod @@ -18,7 +18,7 @@ return { Name = "Earth", Parent = "EarthBarycenter", Renderable = { - Type = "RenderablePlanet", + Type = "RenderablePlanetAtmosphere", Frame = "IAU_EARTH", Body = "EARTH", Geometry = { diff --git a/modules/atmosphere/CMakeLists.txt b/modules/atmosphere/CMakeLists.txt index 3e1b3ab94a..509ab4b89f 100644 --- a/modules/atmosphere/CMakeLists.txt +++ b/modules/atmosphere/CMakeLists.txt @@ -25,14 +25,16 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmosphereraycaster.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplanetatmosphere.h ) source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmosphereraycaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplanetatmosphere.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/atmosphere/atmospheremodule.cpp b/modules/atmosphere/atmospheremodule.cpp index 211ac38683..88df0e1673 100644 --- a/modules/atmosphere/atmospheremodule.cpp +++ b/modules/atmosphere/atmospheremodule.cpp @@ -28,7 +28,7 @@ #include -#include +#include namespace openspace { @@ -37,7 +37,7 @@ AtmosphereModule::AtmosphereModule() : OpenSpaceModule("Atmosphere") {} void AtmosphereModule::internalInitialize() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); - fRenderable->registerClass("RenderableAtmosphere"); + fRenderable->registerClass("RenderablePlanetAtmosphere"); } } // namespace openspace diff --git a/modules/base/shaders/atmosphere_deferred_fs.glsl b/modules/base/shaders/atmosphere_deferred_fs.glsl deleted file mode 100644 index 33baac895e..0000000000 --- a/modules/base/shaders/atmosphere_deferred_fs.glsl +++ /dev/null @@ -1,629 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#define EPSILON 0.0001f - -// Sun Irradiance -const float ISun = 40.0; - -uniform dmat4 object2WorldKMMatrix; -uniform dmat4 object2WorldMatrix; -uniform dmat4 scaleTransformKMMatrix; -uniform dmat4 scaleTransformMatrix; -uniform dmat4 completeTransfKMInverse; -uniform dmat4 completeTransfInverse; -uniform dmat4 sgctProjectionMatrix; -uniform dmat4 inverseSgctProjectionMatrix; -uniform dmat4 sgctViewMatrix; -uniform dmat4 inverseSgctViewMatrix; -uniform dmat4 cameraRotationMatrix; -uniform dmat4 inverseCameraRotationMatrix; -uniform dmat4 world2ObjectKMMatrix; -uniform dmat4 world2ObjectMatrix; -uniform dvec4 cameraPositionKMObject; -uniform dvec4 cameraPositionKMWorld; -uniform dvec4 cameraPositionObject; -uniform dvec4 cameraPositionWorld; -uniform dvec4 planetPositionObjKM; -uniform dvec4 planetPositionWorldKM; -uniform dvec4 planetPositionObj; -uniform dvec4 planetPositionWorld; -uniform dvec4 sunPositionObjKM; -uniform dvec4 sunPositionObj; - -//uniform vec4 campos; -//uniform vec4 objpos; -//uniform vec3 sun_pos; - -uniform bool _performShading = true; -uniform float transparency; -uniform int shadows; - -uniform float screenX; -uniform float screenY; -uniform float screenWIDTH; -uniform float screenHEIGHT; - -uniform float time; - -uniform sampler2D reflectanceTexture; -uniform sampler2D transmittanceTexture; -uniform sampler2D irradianceTexture; -uniform sampler3D inscatterTexture; - -#include "hdr.glsl" -#include "PowerScaling/powerScaling_fs.hglsl" -#include "fragment.glsl" -#include "atmosphere_common.glsl" - - -layout(location = 1) out vec4 renderTarget; - -in vec3 viewDirectionVS; -in vec4 vertexPosObjVS; - -/******************************************************************************* - ****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ****** - *******************************************************************************/ - -/* Calculates the intersection of the view ray direction with the atmosphere and - * returns the first intersection (0.0 when inside atmosphere): offset - * and the second intersection: maxLength - */ - -struct Ray { - dvec4 origin; - dvec4 direction; -}; - -struct Ellipsoid { - dvec4 center; - dvec4 size; -}; - -bool algebraicIntersecSphere(const Ray ray, const float SphereRadius, const dvec4 SphereCenter, - out double offset, out double maxLength) -{ - dvec3 L = ray.origin.xyz - SphereCenter.xyz; - double B = 2 * dot(ray.direction.xyz, L); - double C = dot(L, L) - (SphereRadius*SphereRadius); - double delta = B*B - 4*C; - - if ( delta < 0.0 ) { // no intersection - return false; - } - else if ( delta == 0.0 ) { // one intersection; - offset = maxLength = -B/2.0; - return true; - } else { - double inv2 = 1.0/2.0; - double tmpB = -B*inv2; - double root = sqrt(delta); - double t0 = tmpB - root*inv2; - double t1 = tmpB + root*inv2; - - if ( t0 < t1 ) { - offset = t0; - maxLength = t1; - } else { - offset = t1; - maxLength = t0; - } - } - - return true; -} - -bool geometricIntersecSphere(const Ray ray, const float SphereRadius, const dvec4 SphereCenter, - out double offset, out double maxLength) { - // Ray's direction must be normalized. - dvec4 OC = SphereCenter - ray.origin; - double L2 = dot(OC.xyz, OC.xyz); - double Sr2 = SphereRadius * SphereRadius; - - if ( L2 < Sr2 ) // Ray origin inside sphere. - return false; // TODO: Bust be handled later - - double t_ca = dot(OC.xyz, ray.direction.xyz); - - if ( t_ca < 0.0 ) // Sphere's center lies behind the rays origin. - return false; // TODO: Handle inside sphere. - - double t_2hc = Sr2 - L2 + (t_ca * t_ca); - - if ( t_2hc < 0.0 ) // Ray misses the sphere - return false; - - double t_hc = sqrt(t_2hc); - - offset = t_ca - t_hc; - maxLength = t_ca + t_hc; - - return true; -} - -bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out double offset, out double maxLength) { - dvec4 O_C = ray.origin-ellipsoid.center; - dvec4 dir = normalize(ray.direction); - - offset = 0.0f; - maxLength = 0.0f; - - double a = - ((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - double b = - ((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - double c = - ((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z)) - - 1.f; - - double d = ((b*b)-(4.f*a*c)); - if ( d<0.f || a==0.f || b==0.f || c==0.f ) - return false; - - d = sqrt(d); - - double t1 = (-b+d)/(2.f*a); - double t2 = (-b-d)/(2.f*a); - - if( t1<=EPSILON && t2<=EPSILON ) - return false; // both intersections are behind the ray origin - - bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid - double t=0.f; - if( t1<=EPSILON ) - t = t2; - else - if( t2<=EPSILON ) - t = t1; - else - t=(t1= 0.0) { - // ray outside sphere - double m2 = l2 - (s*s); - if (m2 <= r2) { - // ray hits atmosphere - double q = sqrt(r2 - m2); - offset = s-q; - maxLength = (s+q)-offset; - - return true; - } - } - - return false; -} - -// Rayleigh phase function -float phaseFunctionR(float mu) { - return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); -} - -// Mie phase function -float phaseFunctionM(float mu) { - return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG); -} - -float opticalDepth(float H, float r, float mu, float d) { - float a = sqrt((0.5/H)*r); - vec2 a01 = a*vec2(mu, mu + d / r); - vec2 a01s = sign(a01); - vec2 a01sq = a01*a01; - float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; - vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); - return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); -} - -vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) -{ - float H = sqrt(Rt * Rt - Rg * Rg); - float rho = sqrt(r * r - Rg * Rg); - float rmu = r * mu; - float delta = rmu * rmu - r * r + Rg * Rg; - vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); - float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); - float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); - float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); - float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); - float uNu = floor(lerp); - lerp = lerp - uNu; - return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + - texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; -} - -vec3 analyticTransmittance(float r, float mu, float d) { - return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - betaMieExtinction * opticalDepth(HM, r, mu, d)); -} - -vec3 getMie(vec4 rayMie) { - return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaRayleigh.r / betaRayleigh); -} - -vec2 getTransmittanceUV(float r, float mu) { - float uR, uMu; - uR = sqrt((r - Rg) / (Rt - Rg)); - uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - return vec2(uMu, uR); -} - -vec3 transmittanceFromTexture(float r, float mu) { - vec2 uv = getTransmittanceUV(r, mu); - return texture(transmittanceTexture, uv).rgb; -} - -vec3 transmittanceWithShadow(float r, float mu) { - return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu); -} - -vec3 transmittance(float r, float mu, vec3 v, vec3 x0) { - vec3 result; - float r1 = length(x0); - float mu1 = dot(x0, v) / r; - if (mu > 0.0) { - result = min(transmittanceFromTexture(r, mu) / - transmittanceFromTexture(r1, mu1), 1.0); - } else { - result = min(transmittanceFromTexture(r1, -mu1) / - transmittanceFromTexture(r, -mu), 1.0); - } - return result; -} - -vec2 getIrradianceUV(float r, float muS) { - float uR = (r - Rg) / (Rt - Rg); - float uMuS = (muS + 0.2) / (1.0 + 0.2); - return vec2(uMuS, uR); -} - -vec3 irradiance(sampler2D sampler, float r, float muS) { - vec2 uv = getIrradianceUV(r, muS); - return texture(sampler, uv).rgb; -} - -/* - * Calculates the light scattering in the view direction comming from other - * light rays scattered in the atmosphere. - * The view direction here is the ray: x + tv, s is the sun direction, - * r and mu the position and zenith cossine angle as in the paper. - */ -vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s, - out float r, out float mu, out vec3 attenuation) { - vec3 result; - r = length(x); - mu = dot(x, v) / r; - float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt); - if (d > 0.0) { - x += d * v; - t -= d; - mu = (r * mu + d) / Rt; - r = Rt; - } - // Intersects atmosphere? - if (r <= Rt) { - float nu = dot(v, s); - float muS = dot(x, s) / r; - float phaseR = phaseFunctionR(nu); - float phaseM = phaseFunctionM(nu); - vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0); - if (t > 0.0) { - vec3 x0 = x + t * v; - float r0 = length(x0); - float rMu0 = dot(x0, v); - float mu0 = rMu0 / r0; - float muS0 = dot(x0, s) / r0; - - attenuation = analyticTransmittance(r, mu, t); - //attenuation = transmittance(r, mu, v, x+t*v); - - //The following Code is generating surface acne on atmosphere. JCC - // We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x - if (r0 > Rg + 0.1*r) { - inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0); - const float EPS = 0.004; - float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r)); - if (abs(mu - muHoriz) < EPS) { - float a = ((mu - muHoriz) + EPS) / (2.0 * EPS); - - mu = muHoriz - EPS; - r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); - mu0 = (r * mu + t) / r0; - vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); - vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); - vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); - - mu = muHoriz + EPS; - r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); - mu0 = (r * mu + t) / r0; - inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); - inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); - vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); - - inscatter = mix(inScatterA, inScatterB, a); - } - } - } - inscatter.w *= smoothstep(0.00, 0.02, muS); - result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0); - - } else { - // No intersection with earth - result = vec3(0.0); - } - return result * ISun; -} - -vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation) -{ - vec3 result; - // Ray hits ground - if (t > 0.0) { - vec3 x0 = x + t * v; - float r0 = length(x0); - vec3 n = x0 / r0; - - // Old deferred: - vec2 coords = vec2(atan(n.y, n.x), acos(n.z)) * vec2(0.5, 1.0) / M_PI + vec2(0.5, 0.0); - vec4 reflectance = texture2D(reflectanceTexture, coords) * vec4(0.2, 0.2, 0.2, 1.0); - if (r0 > Rg + 0.01) { - reflectance = vec4(0.4, 0.4, 0.4, 0.0); - } - - // New non-deferred - // // Fixing texture coordinates: - // vec4 reflectance = vec4(0.2, 0.2, 0.2, 1.0); - - // // The following code is generating surface acne in ground. - // // It is only necessary inside atmosphere rendering. JCC - // if (r0 > Rg + 0.01) { - // reflectance = vec4(0.4, 0.4, 0.4, 0.0); - // } - - float muS = dot(n, s); - vec3 sunLight = transmittanceWithShadow(r0, muS); - - vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS); - - //vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st); - vec3 groundColor = (reflectance.rgb) * - (max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI; - - // Yellowish reflection from sun on oceans and rivers - if (reflectance.w > 0.0) { - vec3 h = normalize(s - v); - float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); - float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0); - groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun; - } - - result = attenuation * groundColor; - } else { - // No hit - result = vec3(0.0); - } - return result; -} - -vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) { - if (t > 0.0) { - return vec3(0.0); - } else { - vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0); - float isun = step(cos(M_PI / 180.0), dot(v, s)) * ISun; - return transmittance * isun; - } -} - -Fragment getFragment() { - //vec4 position = vs_position; - float depth = 0.0; - // vec4 diffuse = texture(texture1, vs_st); - // vec4 diffuse2 = texture(nightTex, vs_st); - // vec4 clouds = texture(cloudsTexture, vs_st); - vec4 diffuse = vec4(0.0); - - Fragment frag; - if (_performShading) { - // // Fragment to window coordinates - // dvec4 windowCoords = vec4(0.0); - // windowCoords.xy = gl_FragCoord.xy + 0.5; - // windowCoords.z = gl_FragCoord.z; // z can be 0.0 or 1.0. We chose 1.0 to avoid math problems. - // windowCoords.w = 1.0 / gl_FragCoord.w; - - // // Window to NDC coordinates - // dvec4 viewPort = vec4(screenX, screenY, screenWIDTH, screenHEIGHT); - // dvec4 ndcCoords = vec4(0.0); - // ndcCoords.x = (2.0/screenWIDTH) * (windowCoords.x - (screenX + screenWIDTH/2.0)); - // ndcCoords.y = (2.0/screenHEIGHT) * (windowCoords.y - (screenY + screenHEIGHT/2.0)); - // double f_plus_n = gl_DepthRange.far + gl_DepthRange.near; - // double f_minus_n = gl_DepthRange.far - gl_DepthRange.near; - // ndcCoords.z = (2.0/f_minus_n) * windowCoords.z - (f_plus_n/f_minus_n); - // ndcCoords.w = windowCoords.w; - - // // NDC to clip coordinates - // dvec4 clipCoords = vec4(0.0); - // clipCoords.xyz = ndcCoords.xyz * ndcCoords.w; - // clipCoords.w = 1.0 / ndcCoords.w; - - // //now we transform back from clip space to world space using the complete inverse transformation. - // dvec4 projCoords = projInverse * clipCoords; - - // Because this is a vector and not a point, we do not need to reverse the perspective division here, - // a vetor doesn't have intrinsic depth: - dvec4 vVSTmp = vertexPosObjVS; - //vVSTmp.z = -1.0; - //vVSTmp.w = 0.0; - dvec4 projCoords = inverseSgctProjectionMatrix * vVSTmp; - //projCoords.z = -1.0; - //projCoords.w = 0.0; - - -/* - uniform dmat4 object2WorldKMMatrix; - uniform dmat4 object2WorldMatrix; - uniform dmat4 scaleTransformKMMatrix; - uniform dmat4 scaleTransformMatrix; - uniform dmat4 completeTransfKMInverse; - uniform dmat4 completeTransfInverse; - uniform dmat4 sgctProjectionMatrix; - uniform dmat4 inverseSgctProjectionMatrix; - uniform dmat4 sgctViewMatrix; - uniform dmat4 inverseSgctViewMatrix; - uniform dmat4 cameraRotationMatrix; - uniform dmat4 inverseCameraRotationMatrix; - uniform dmat4 world2ObjecKMMatrix; - uniform dmat4 world2ObjecMatrix; - uniform dvec4 cameraPositionKMObject; - uniform dvec4 cameraPositionKMWorld; - uniform dvec4 cameraPositionObject; - uniform dvec4 cameraPositionWorld; - uniform dvec4 planetPositionObjKM; - uniform dvec4 planetPositionWorldKM; - uniform dvec4 planetPositionObj; - uniform dvec4 planetPositionWorld; - uniform dvec4 sunPositionObjKM; - uniform dvec4 sunPositionObj; -*/ - - - double offset = 0.0, maxLength = 0.0; - vec4 ppos = vec4(0.0); - - //View direction is in object space. - dvec4 viewDirection = completeTransfInverse * vVSTmp; - - Ray ray; - ray.origin = cameraPositionObject; - ray.direction = vec4(normalize((viewDirection - cameraPositionObject).xyz), 0.0); - - //diffuse = vec4(normalize(ray.direction.xyz), 1.0); - diffuse = vec4(normalize(planetPositionObj.xyz), 1.0); - // dvec4 zeroTest = vec4(0.0); - //if ( algebraicIntersecSphere(ray, Rt, zeroTest, offset, maxLength) ) { - //if ( algebraicIntersecSphere(ray, Rt, planetPositonTransfObject, offset, maxLength) ) { - //if ( algebraicIntersecSphere(ray, Rt, planetPositionObj, offset, maxLength) ) { - //if ( geometricIntersecSphere(ray, Rg, ppos, offset, maxLength) ) { - //if ( geometricIntersecSphere(ray, Rt, planetPositionObj, offset, maxLength) ) { - //if (intersectAtmosphere(planetPositionObj, v, Rg, offset, maxLength)) { - //if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) { - // // if ( offset < 0) // inside atmosphere - // // t = maxLength; - // // Following paper nomenclature - // // float t = offset; - // // vec3 x = cameraPosObj.xyz + (t * v) - planetPositionObj.xyz; - // // // When using geometry - // // //vec3 x = ray.origin.xyz + t * ray.direction.xyz - planetPositionObj.xyz; - // // float r = length(x); - // // float mu = (dot(x, v))/ r; - // // //float mu = (dot(x, -v))/ r; - // // vec3 s = normalize(sunPositionObj); - - // // vec3 attenuation; - // // vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation); - // // vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); - // // vec3 sunColor = sunColor(x, t, v, s, r, mu); - - // // diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); - // //diffuse = HDR(vec4(sunColor, 1.0)); - // //diffuse = HDR(vec4(groundColor, 1.0)); - // //diffuse = HDR(vec4(inscatterColor, 1.0)); - - // //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2); - // // diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) * - // // calcShadow(shadowDataArray, vs_posWorld.xyz) ); - - - - // float t = maxLength; - // vec3 x = cameraPosObj.xyz + offset * v; - // float r = length(x); - // float mu = dot(x, v) / r; - // vec3 s = normalize(sunPositionObj - x); - - // vec3 attenuation; - // vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation); //S[L]-T(x,xs)S[l]|xs - // vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); //R[L0]+R[L*] - // vec3 sunColor = sunColor(x, t, v, s, r, mu); //L0 - // diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); // Eq (16) - - // diffuse = vec4(1.0, 0.0, 0.0, 1.0); - - - // } - // else - // diffuse = HDR(diffuse); - } - - renderTarget = diffuse; - - - diffuse[3] = transparency; - frag.color = diffuse; - frag.depth = 0.0; - - return frag; -} diff --git a/modules/base/shaders/atmosphere_deferred_vs.glsl b/modules/base/shaders/atmosphere_deferred_vs.glsl deleted file mode 100644 index bf64a142c8..0000000000 --- a/modules/base/shaders/atmosphere_deferred_vs.glsl +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -layout(location = 0) in vec4 in_position; - -#include "PowerScaling/powerScaling_vs.hglsl" - -uniform dmat4 completeInverse; -uniform dmat4 projInverse; -uniform dvec4 cameraPosObj; - -out vec3 viewDirectionVS; -out vec4 vertexPosObjVS; - -void main() -{ - //viewDirectionVS = normalize( (completeInverse * vec4((projInverse * in_position).xyz, 0.0)).xyz - cameraPosObj.xyz); - - //viewDirectionVS = normalize( (completeInverse * vec4(projInverse * in_position) ).xyz ); - - //viewDirectionVS = (completeInverse * projInverse * in_position).xyz; - - vertexPosObjVS = in_position; - gl_Position = in_position; -} \ No newline at end of file diff --git a/modules/base/shaders/atmosphere_fs.glsl b/modules/base/shaders/atmosphere_fs.glsl deleted file mode 100644 index 5e0ee08d02..0000000000 --- a/modules/base/shaders/atmosphere_fs.glsl +++ /dev/null @@ -1,505 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#define EPSILON 0.0001f - -const uint numberOfShadows = 1; - -struct ShadowRenderingStruct { - float xu, xp; - float rs, rc; - vec3 sourceCasterVec; - vec3 casterPositionVec; - bool isShadowing; -}; - -uniform ShadowRenderingStruct shadowDataArray[numberOfShadows]; - -uniform mat4 completeInverse; -uniform mat4 projInverse; - -uniform vec4 campos; -uniform vec4 objpos; -uniform vec3 sun_pos; - -uniform vec4 cameraPosObj; -uniform vec4 planetPositionObj; -uniform vec3 sunPositionObj; - -uniform bool _performShading = true; -uniform float transparency; -uniform int shadows; - -uniform float screenX; -uniform float screenY; -uniform float screenWIDTH; -uniform float screenHEIGHT; - -uniform float time; -uniform sampler2D texture1; -uniform sampler2D nightTex; -uniform sampler2D cloudsTexture; - -uniform sampler2D reflectanceTexture; -uniform sampler2D transmittanceTexture; -uniform sampler2D irradianceTexture; -uniform sampler3D inscatterTexture; - -in vec2 vs_st; -in vec2 vs_nightTex; -in vec4 vs_normal; -in vec4 vs_position; -in vec4 vs_posWorld; - -#include "hdr.glsl" -#include "PowerScaling/powerScaling_fs.hglsl" -#include "fragment.glsl" -#include "atmosphere_common.glsl" - -vec4 butterworthFunc(const float d, const float r, const float n) { - return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); -} - -/******************************************************************************* - ****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ****** - *******************************************************************************/ - -/* Calculates the intersection of the view ray direction with the atmosphere and - * returns the first intersection (0.0 when inside atmosphere): offset - * and the second intersection: maxLength - */ - -struct Ray { - vec4 origin; - vec4 direction; -}; - -struct Ellipsoid { - vec4 center; - vec4 size; -}; - -bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out float offset, out float maxLength) { - vec4 O_C = ray.origin-ellipsoid.center; - vec4 dir = normalize(ray.direction); - - offset = 0.0f; - maxLength = 0.0f; - - float a = - ((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - float b = - ((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - float c = - ((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z)) - - 1.f; - - float d = ((b*b)-(4.f*a*c)); - if ( d<0.f || a==0.f || b==0.f || c==0.f ) - return false; - - d = sqrt(d); - - float t1 = (-b+d)/(2.f*a); - float t2 = (-b-d)/(2.f*a); - - if( t1<=EPSILON && t2<=EPSILON ) - return false; // both intersections are behind the ray origin - - bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid - float t=0.f; - if( t1<=EPSILON ) - t = t2; - else - if( t2<=EPSILON ) - t = t1; - else - t=(t1= 0.0) { - // ray outside sphere - float m2 = l2 - (s*s); - if (m2 <= r2) { - // ray hits atmosphere - float q = sqrt(r2 - m2); - offset = s-q; - maxLength = (s+q)-offset; - - return true; - } - } - - return false; -} - -// Rayleigh phase function -float phaseFunctionR(float mu) { - return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); -} - -// Mie phase function -float phaseFunctionM(float mu) { - return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG); -} - -float opticalDepth(float H, float r, float mu, float d) { - float a = sqrt((0.5/H)*r); - vec2 a01 = a*vec2(mu, mu + d / r); - vec2 a01s = sign(a01); - vec2 a01sq = a01*a01; - float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; - vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); - return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); -} - -vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) -{ - float H = sqrt(Rt * Rt - Rg * Rg); - float rho = sqrt(r * r - Rg * Rg); - float rmu = r * mu; - float delta = rmu * rmu - r * r + Rg * Rg; - vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); - float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); - float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); - float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); - float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); - float uNu = floor(lerp); - lerp = lerp - uNu; - return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + - texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; -} - -vec3 analyticTransmittance(float r, float mu, float d) { - return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - - betaMieExtinction * opticalDepth(HM, r, mu, d)); -} - -vec3 getMie(vec4 rayMie) { - return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaRayleigh.r / betaRayleigh); -} - -vec2 getTransmittanceUV(float r, float mu) { - float uR, uMu; - uR = sqrt((r - Rg) / (Rt - Rg)); - uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - return vec2(uMu, uR); -} - -vec3 transmittanceFromTexture(float r, float mu) { - vec2 uv = getTransmittanceUV(r, mu); - return texture(transmittanceTexture, uv).rgb; -} - -vec3 transmittanceWithShadow(float r, float mu) { - return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu); -} - -vec3 transmittance(float r, float mu, vec3 v, vec3 x0) { - vec3 result; - float r1 = length(x0); - float mu1 = dot(x0, v) / r; - if (mu > 0.0) { - result = min(transmittanceFromTexture(r, mu) / - transmittanceFromTexture(r1, mu1), 1.0); - } else { - result = min(transmittanceFromTexture(r1, -mu1) / - transmittanceFromTexture(r, -mu), 1.0); - } - return result; -} - -vec2 getIrradianceUV(float r, float muS) { - float uR = (r - Rg) / (Rt - Rg); - float uMuS = (muS + 0.2) / (1.0 + 0.2); - return vec2(uMuS, uR); -} - -vec3 irradiance(sampler2D sampler, float r, float muS) { - vec2 uv = getIrradianceUV(r, muS); - return texture(sampler, uv).rgb; -} - -/* - * Calculates the light scattering in the view direction comming from other - * light rays scattered in the atmosphere. - * The view direction here is the ray: x + tv, s is the sun direction, - * r and mu the position and zenith cossine angle as in the paper. - */ -vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s, - out float r, out float mu, out vec3 attenuation) { - vec3 result; - r = length(x); - mu = dot(x, v) / r; - float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt); - if (d > 0.0) { - x += d * v; - t -= d; - mu = (r * mu + d) / Rt; - r = Rt; - } - // Intersects atmosphere? - if (r <= Rt) { - float nu = dot(v, s); - float muS = dot(x, s) / r; - float phaseR = phaseFunctionR(nu); - float phaseM = phaseFunctionM(nu); - vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0); - if (t > 0.0) { - vec3 x0 = x + t * v; - float r0 = length(x0); - float rMu0 = dot(x0, v); - float mu0 = rMu0 / r0; - float muS0 = dot(x0, s) / r0; - - attenuation = analyticTransmittance(r, mu, t); - //attenuation = transmittance(r, mu, v, x+t*v); - - //The following Code is generating surface acne on atmosphere. JCC - // We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x - if (r0 > Rg + 0.1*r) { - inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0); - const float EPS = 0.004; - float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r)); - if (abs(mu - muHoriz) < EPS) { - float a = ((mu - muHoriz) + EPS) / (2.0 * EPS); - - mu = muHoriz - EPS; - r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); - mu0 = (r * mu + t) / r0; - vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); - vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); - vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); - - mu = muHoriz + EPS; - r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); - mu0 = (r * mu + t) / r0; - inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); - inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); - vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); - - inscatter = mix(inScatterA, inScatterB, a); - } - } - } - inscatter.w *= smoothstep(0.00, 0.02, muS); - result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0); - - } else { - // No intersection with earth - result = vec3(0.0); - } - return result * sunRadiance; -} - -vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation) -{ - vec3 result; - // Ray hits ground - if (t > 0.0) { - vec3 x0 = x + t * v; - float r0 = length(x0); - vec3 n = x0 / r0; - - // Fixing texture coordinates: - vec4 reflectance = texture(reflectanceTexture, vs_st) * vec4(0.2, 0.2, 0.2, 1.0); - - // The following code is generating surface acne in ground. - // It is only necessary inside atmosphere rendering. JCC - // if (r0 > Rg + 0.01) { - // reflectance = vec4(0.4, 0.4, 0.4, 0.0); - // } - - float muS = dot(n, s); - vec3 sunLight = transmittanceWithShadow(r0, muS); - - vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS); - - vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st); - vec3 groundColor = (reflectance.rgb + clouds.rgb) * - (max(muS, 0.0) * sunLight + groundSkyLight) * sunRadiance / M_PI; - - // Yellowish reflection from sun on oceans and rivers - if (reflectance.w > 0.0) { - vec3 h = normalize(s - v); - float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); - float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0); - groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * sunRadiance; - } - - result = attenuation * groundColor; - } else { - // No hit - result = vec3(0.0); - } - return result; -} - -vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) { - if (t > 0.0) { - return vec3(0.0); - } else { - vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0); - float isun = step(cos(M_PI / 180.0), dot(v, s)) * sunRadiance; - return transmittance * isun; - } -} - -/*********************************************************************** - ******* CALCULATIONS FOR SHADOWS ARE IN WORLD SPACE IN METERS ********* - ***********************************************************************/ - // TODO: Change calculations for view space in KM. -vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) { - if (shadowInfoArray[0].isShadowing) { - vec3 pc = shadowInfoArray[0].casterPositionVec - position; - vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader - vec3 pc_proj = dot(pc, sc_norm) * sc_norm; - vec3 d = pc - pc_proj; - - float length_d = length(d); - float length_pc_proj = length(pc_proj); - - float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp; - - //float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu; - float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; - - if ( length_d < r_u_pi ) { // umbra - //return vec4(0.0, 0.0, 0.0, 1.0); - //return vec4(1.0, 0.0, 0.0, 1.0); - return butterworthFunc(length_d, r_u_pi, 4.0); - } - else if ( length_d < r_p_pi ) {// penumbra - //return vec4(0.5, 0.5, 0.5, 1.0); - //return vec4(0.0, 1.0, 0.0, 1.0); - return vec4(vec3(length_d/r_p_pi), 1.0); - } - } - - return vec4(1.0); -} - -Fragment getFragment() { - vec4 position = vs_position; - float depth = pscDepth(position); - vec4 diffuse = texture(texture1, vs_st); - vec4 diffuse2 = texture(nightTex, vs_st); - vec4 clouds = texture(cloudsTexture, vs_st); - - Fragment frag; - if (_performShading) { - // atmosphere - vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT); - vec4 ndcPos; - ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1; - //ndcPos.x = ((2.0f * gl_FragCoord.x) - (2.0f * viewport.x)) / viewport.z - 1.0f; - //ndcPos.y = 1.0f - (2.0f * gl_FragCoord.y) / viewport.w; - ndcPos.z = (2.0f * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / - (gl_DepthRange.far - gl_DepthRange.near); - ndcPos.w = 1.0f; - vec4 clipPos = ndcPos / gl_FragCoord.w; - //vec4 clipPos = ndcPos; - //clipPos.z = -1.0; - //clipPos.w = 1.0; - vec4 projCoords = projInverse * clipPos; - vec4 viewDirection = normalize(completeInverse * vec4(projCoords.xyz, 0.0)); - vec3 v = normalize(viewDirection.xyz); - - float offset, maxLength; - vec4 ppos = vec4(0.0); - //if (intersectAtmosphere(planetPositionObj, v, Rt, offset, maxLength)) { - if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) { - // Following paper nomenclature - float t = offset; - vec3 x = cameraPosObj.xyz;// + offset * v; - float r = length(x); - float mu = dot(x, v) / r; - vec3 s = normalize(sunPositionObj); - - vec3 attenuation; - vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation); - vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); - vec3 sunColor = sunColor(x, t, v, s, r, mu); - - //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); - //diffuse = HDR(vec4(sunColor, 1.0)); - //diffuse = HDR(vec4(groundColor, 1.0)); - //diffuse = HDR(vec4(inscatterColor, 1.0)); - - //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2); - diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) * - calcShadow(shadowDataArray, vs_posWorld.xyz) ); - } - // else - // diffuse = HDR(diffuse); - } - - diffuse[3] = transparency; - frag.color = diffuse; - frag.depth = depth; - - return frag; -} diff --git a/modules/base/shaders/atmosphere_vs.glsl b/modules/base/shaders/atmosphere_vs.glsl deleted file mode 100644 index aff724f1ef..0000000000 --- a/modules/base/shaders/atmosphere_vs.glsl +++ /dev/null @@ -1,86 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -uniform mat4 ViewProjection; -uniform mat4 ModelTransform; -uniform mat4 NormalTransform; -uniform sampler2D heightTex; -uniform bool _hasHeightMap; -uniform float _heightExaggeration; - -layout(location = 0) in vec4 in_position; -layout(location = 1) in vec2 in_st; -layout(location = 2) in vec3 in_normal; -//layout(location = 3) in vec2 in_nightTex; - - -out vec2 vs_st; -out vec4 vs_normal; -out vec4 vs_position; -out vec4 vs_posWorld; -out float s; -out vec4 ray; - -#include "PowerScaling/powerScaling_vs.hglsl" - -void main() -{ - // set variables - vs_st = in_st; - vs_position = in_position; - vec4 tmp = in_position; - - // this is wrong for the normal. The normal transform is the transposed inverse of the model transform - //vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - - // This is the wright transformation for the normals - vs_normal = normalize(NormalTransform * vec4(in_normal,0)); - - // The position is not in world coordinates, it is in - // regular view/eye coordinates. - vec4 position = pscTransform(tmp, ModelTransform); - - // Vertex position in world coordinates in meters and - // with no powerscalling coordiantes - vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; - vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0); - vs_posWorld = conv; - - vs_position = tmp; - - if (_hasHeightMap) { - float height = texture(heightTex, in_st).r; - vec3 displacementDirection = abs(normalize(in_normal.xyz)); - float displacementFactor = height * _heightExaggeration; - position.xyz = position.xyz + displacementDirection * displacementFactor; - } - - // Now the position is transformed from view coordinates to SGCT projection - // coordinates. - position = ViewProjection * position; - gl_Position = z_normalization(position); -} diff --git a/modules/base/shaders/deltaE_calc_fs.glsl b/modules/base/shaders/deltaE_calc_fs.glsl deleted file mode 100644 index a0b6ba8355..0000000000 --- a/modules/base/shaders/deltaE_calc_fs.glsl +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTableColor; - -// See paper algorithm -uniform int line; -uniform sampler2D deltaETexture; - -void main(void) { - if (line == 4) - renderTableColor = vec4(0.0); - else if (line == 10) { - vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H); - renderTableColor = texture(deltaETexture, uv); - } -} \ No newline at end of file diff --git a/modules/base/shaders/deltaJ_calc_fs.glsl b/modules/base/shaders/deltaJ_calc_fs.glsl deleted file mode 100644 index 9bd31c1363..0000000000 --- a/modules/base/shaders/deltaJ_calc_fs.glsl +++ /dev/null @@ -1,186 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTarget1; - -uniform float r; -uniform vec4 dhdH; - -uniform sampler2D transmittanceTexture; -uniform sampler2D deltaETexture; -uniform sampler3D deltaSRTexture; -uniform sampler3D deltaSMTexture; -uniform float first; - -const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); -const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); - -void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) { - float x = gl_FragCoord.x - 0.5; - float y = gl_FragCoord.y - 0.5; - if (y < float(RES_MU) / 2.0) { - float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); - d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); - mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); - mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); - } else { - float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); - d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); - mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); - } - mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); - mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); - nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; -} - -vec3 transmittanceFromTexture(const float r, const float mu) { - float u_r = sqrt((r - Rg) / (Rt - Rg)); - // See Colliene to understand the different mapping. - float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - - return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; -} - -vec3 transmittance(const float r, const float mu, float d) { - vec3 result; - float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); - float mu1 = (r * mu + d) / r1; - if (mu > 0.0) { - result = min(transmittanceFromTexture(r, mu) / - transmittanceFromTexture(r1, mu1), 1.0); - } else { - result = min(transmittanceFromTexture(r1, -mu1) / - transmittanceFromTexture(r, -mu), 1.0); - } - return result; -} - -// Rayleigh phase -float phaseFunctionR(const float mu) { - return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); -} - -// Mie phase -float phaseFunctionM(const float mu) { - return (3.0 / (8.0 * M_PI)) * - ( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) / - ( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) ); -} - -vec3 irradiance(sampler2D calcTexture, const float r, const float mu_s) { - float u_r = (r - Rg) / (Rt - Rg); - float u_mu_s = (mu_s + 0.2) / (1.0 + 0.2); - return texture(calcTexture, vec2(u_mu_s, u_r)).rgb; -} - -vec4 texture4D(sampler3D table, const float r, const float mu, - const float mu_s, const float nu) -{ - float H = sqrt(Rt * Rt - Rg * Rg); - float rho = sqrt(r * r - Rg * Rg); - float rmu = r * mu; - float delta = rmu * rmu - r * r + Rg * Rg; - vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); - float u_r = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); - float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); - float u_mu_s = 0.5 / float(RES_MU_S) + (atan(max(mu_s, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); - float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); - float uNu = floor(lerp); - lerp = lerp - uNu; - return texture(table, vec3((uNu + u_mu_s) / float(RES_NU), u_mu, u_r)) * (1.0 - lerp) + - texture(table, vec3((uNu + u_mu_s + 1.0) / float(RES_NU), u_mu, u_r)) * lerp; -} - -void inscatter(float r, float mu, float mu_s, float nu, out vec3 raymie) { - r = clamp(r, Rg, Rt); - mu = clamp(mu, -1.0, 1.0); - mu_s = clamp(mu_s, -1.0, 1.0); - float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - mu_s * mu_s); - nu = clamp(nu, mu_s * mu - var, mu_s * mu + var); - - float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r)); - - vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu); - float sx = v.x == 0.0 ? 0.0 : (nu - mu_s * mu) / v.x; - vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - mu_s * mu_s)), mu_s); - - raymie = vec3(0.0); - - for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) { - float theta = (float(itheta) + 0.5) * dtheta; - float ctheta = cos(theta); - - float greflectance = 0.0; - float dground = 0.0; - vec3 gtransp = vec3(0.0); - if (ctheta < cthetamin) { - greflectance = AverageGroundReflectance / M_PI; - dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg); - gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground); - } - - for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) { - float phi = (float(iphi) + 0.5) * dphi; - float dw = dtheta * dphi * sin(theta); - vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta); - - float nu1 = dot(s, w); - float nu2 = dot(v, w); - float pr2 = phaseFunctionR(nu2); - float pm2 = phaseFunctionM(nu2); - - vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg; - vec3 girradiance = irradiance(deltaETexture, Rg, dot(gnormal, s)); - - vec3 raymie1; - - raymie1 = greflectance * girradiance * gtransp; - - if (first == 1.0) { - float pr1 = phaseFunctionR(nu1); - float pm1 = phaseFunctionM(nu1); - vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb; - vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu1).rgb; - raymie1 += ray1 * pr1 + mie1 * pm1; - } else { - raymie1 += texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb; - } - - raymie += raymie1 * (betaRayleigh * exp(-(r - Rg) / HR) * pr2 + betaMieScattering * exp(-(r - Rg) / HM) * pm2) * dw; - } - } -} - -void main(void) { - vec3 raymie; - float mu, mu_s, nu; - getMuMuSNu(r, dhdH, mu, mu_s, nu); - inscatter(r, mu, mu_s, nu, raymie); - - renderTarget1 = vec4(raymie, 1.0); -} diff --git a/modules/base/shaders/deltaS_calc_fs.glsl b/modules/base/shaders/deltaS_calc_fs.glsl deleted file mode 100644 index 042e1a212e..0000000000 --- a/modules/base/shaders/deltaS_calc_fs.glsl +++ /dev/null @@ -1,45 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTarget1; - -uniform int layer; - -uniform sampler3D deltaSRTexture; -uniform sampler3D deltaSMTexture; - -void main(void) { - vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R)); - vec4 ray = texture(deltaSRTexture, uvw); - vec4 mie = texture(deltaSMTexture, uvw); - - // We are using only the red component of the Mie scattering - // See the Precomputed Atmosphere Scattering paper for details about - // the angular precision. - renderTarget1 = vec4(ray.rgb, mie.r); -} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_calc_fs.glsl b/modules/base/shaders/inScattering_calc_fs.glsl deleted file mode 100644 index b1151e4fe7..0000000000 --- a/modules/base/shaders/inScattering_calc_fs.glsl +++ /dev/null @@ -1,208 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ -#version 330 - -#include "atmosphere_common.glsl" - -layout(location = 0) out vec4 renderTarget1; -layout(location = 1) out vec4 renderTarget2; - -uniform float r; -uniform vec4 dhdH; - -uniform sampler2D transmittanceTexture; - -// In the following shaders r (altitude) is the length of vector/position x in the -// atmosphere (or on the top of it when considering an observer in space), -// where the light is comming from the opposity direction of the view direction, -// here the vector v or viewDirection. -// Rg is the planet radius - -void unmappingMuMuSunNu(const float r, vec4 dhdH, out float mu, out float muSun, out float nu) { - float x = gl_FragCoord.x - 0.5f; - float y = gl_FragCoord.y - 0.5f; - if (y < (float(RES_MU) / 2.0f)) { - float d = 1.0f - y / (float(RES_MU) / 2.0f - 1.0f); - d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); - mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); - mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); - } else { - float d = (y - float(RES_MU) / 2.0f) / (float(RES_MU) / 2.0f - 1.0f); - d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); - mu = (Rt * Rt - r * r - d * d) / (2.0f * r * d); - } - muSun = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0f); - muSun = tan((2.0f * muSun - 1.0f + 0.26f) * 1.1f) / tan(1.26f * 1.1f); - nu = -1.0f + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0f) * 2.0f; -} - -vec3 transmittanceFromTexture(const float r, const float mu) { - // Given the position x (here the altitude r) and the view - // angle v (here the cosine(v)= mu), we map this - float u_r = sqrt((r - Rg) / (Rt - Rg)); - // See Colliene to understand the different mapping. - float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - - return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; -} - -vec3 transmittance(const float r, const float mu, const float d) { - // Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) - // to, given a distance d, calculates that transmittance along - // that distance starting in x (hight r): T(x,d) = T(x,v)/T(d,v). - // - // From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab) - float ri = sqrt(d * d + r * r + 2.0 * r * d * mu); - float mui = (d + r * mu) / ri; - - // It's important to remember that we calculate the Transmittance - // table only for zenith angles between 0 and pi/2+episilon. - // Then, if mu < 0.0, we just need to invert the view direction - // and the start and end points between them, i.e., if - // x --> x0, then x0-->x. - // Also, let's use the property: T(a,c) = T(a,b)*T(b,c) - // Because T(a,c) and T(b,c) are already in the table T, - // T(a,b) = T(a,c)/T(b,c). - if (mu > 0.0f) { - return min(transmittanceFromTexture(r, mu) / - transmittanceFromTexture(ri, mui), 1.0f); - } else { - return min(transmittanceFromTexture(ri, -mui) / - transmittanceFromTexture(r, -mu), 1.0f); - } -} - -void integrand(const float r, const float mu, const float muSun, const float nu, - const float y, out vec3 S_R, out vec3 S_M) { - // The integral's integrand is the single inscattering radiance: - // S[L0] = P_M*S_M[L0] + P_R*S_R[L0] - // where S_M[L0] = T*(betaMScattering * exp(-h/H_M))*L0 and - // S_R[L0] = T*(betaRScattering * exp(-h/H_R))*L0. - // T = transmittance. - // One must remember that because the occlusion on L0, the integrand - // here will be equal to 0 in that cases. - // Also it is important to remember that the phase function for the - // Rayleigh and Mie scattering are addded during the rendering time - // to increase the angular precision - S_R = vec3(0.0); - S_M = vec3(0.0); - - // cosine law - float ri = sqrt(r * r + y * y + 2.0 * r * mu * y); - // Approximate and interpolate muSun_i - float muSun_i = (nu * y + muSun * r) / ri; - - // ri >= Rg - ri = max(Rg, ri); - - // If the muSun_i is smaller than the angle to horizon (no sun radiance - // hitting the point y), we return S_R = S_M = 0.0f. - if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) { - // It's the transmittance from the point y (ri) to the top of atmosphere - // in direction of the sun (muSun_i) and the transmittance from the observer - // at x (r) to y (ri). - vec3 transmittanceY = transmittance(r, mu, y) * transmittanceFromTexture(ri, muSun_i); - // exp(-h/H)*T(x,v) - S_R = exp( -(ri - Rg) / HR ) * transmittanceY; - S_M = exp( -(ri - Rg) / HM ) * transmittanceY; - // The L0 (sun radiance) is added in real-time. - } -} - -float rayDistance(const float r, const float mu) { - // The light ray starting at the observer in/on the atmosphere can - // have to possible end points: the top of the atmosphere or the - // planet ground. So the shortest path is the one we are looking for, - // otherwise we may be passing through the ground. - - // cosine law - float atmRadiusEps = Rt + ATM_EPSILON; - float rayDistanceAtmosphere = -r * mu + - sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps); - float delta = r * r * (mu * mu - 1.0f) + Rg * Rg; - // No imaginary numbers... :-) - if (delta >= 0.0f) { - float rayDistanceGround = -r * mu - sqrt(delta); - if (rayDistanceGround >= 0.0f) { - return min(rayDistanceAtmosphere, rayDistanceGround); - } - } - return rayDistanceAtmosphere; -} - -void inscatter(const float r, const float mu, const float muSun, const float nu, - out vec3 S_R, out vec3 S_M) { - // Let's calculate S_M and S_R by integration along the eye ray path inside - // the atmosphere, given a position r, a view angle (cosine) mu, a sun - // position angle (cosine) muSun, and the angle (cosine) between the sun position - // and the view direction, nu. - // Integrating using the Trapezoidal rule: - // Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i))) - S_R = vec3(0.0f); - S_M = vec3(0.0f); - float rayDist = rayDistance(r, mu); - float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES); - float yi = 0.0f; - vec3 S_Ri; - vec3 S_Mi; - integrand(r, mu, muSun, nu, 0.0, S_Ri, S_Mi); - for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { - float yj = float(i) * dy; - vec3 S_Rj; - vec3 S_Mj; - integrand(r, mu, muSun, nu, yj, S_Rj, S_Mj); - S_R += (S_Ri + S_Rj); - S_M += (S_Mi + S_Mj); - yi = yj; - S_Ri = S_Rj; - S_Mi = S_Mj; - } - S_R *= betaRayleigh * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES))); - S_M *= betaMieScattering * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES))); -} - -void main(void) { - vec3 S_R; - vec3 S_M; - float mu, muSun, nu; - unmappingMuMuSunNu(r, dhdH, mu, muSun, nu); - // Here we calculate the single inScattered light. - // Because this is a single inscattering, the light - // that arrives at a point y in the path from the - // eye to the infinity (top of atmosphere or planet's - // ground), comes only from the light source, i.e., the - // sun. So, the there is no need to integrate over the - // whole solid angle (4pi), we need only to consider - // the Sun position (cosine of sun pos = muSun). - // Then, following the paper notation: - // S[L] = P_R*S_R[L0] + P_M*S_M[L0] + S[L*] - // For single inscattering only: - // S[L0] = P_R*S_R[L0] + P_M*S_M[L0] - // In order to save memory, we just store the red component - // of S_M[L0], and later we use the proportionality rule - // to calcule the other components. - inscatter(r, mu, muSun, nu, S_R, S_M); - renderTarget1 = vec4(S_R, 1.0); - renderTarget2 = vec4(S_M, 1.0); -} diff --git a/modules/base/shaders/inScattering_sup_calc_fs.glsl b/modules/base/shaders/inScattering_sup_calc_fs.glsl deleted file mode 100644 index 6b2bbdcd78..0000000000 --- a/modules/base/shaders/inScattering_sup_calc_fs.glsl +++ /dev/null @@ -1,149 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTarget1; - -uniform float r; -uniform vec4 dhdH; - -uniform sampler2D transmittanceTexture; -uniform sampler3D deltaJTexture; - -void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) { - float x = gl_FragCoord.x - 0.5; - float y = gl_FragCoord.y - 0.5; - if (y < float(RES_MU) / 2.0) { - float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); - d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); - mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); - mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); - } else { - float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); - d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); - mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); - } - mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); - mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); - nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; -} - -vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) -{ - float H = sqrt(Rt * Rt - Rg * Rg); - float rho = sqrt(r * r - Rg * Rg); - float rmu = r * mu; - float delta = rmu * rmu - r * r + Rg * Rg; - vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); - float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); - float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); - float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); - float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); - float uNu = floor(lerp); - lerp = lerp - uNu; - return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + - texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; -} - -float limit(float r, float mu) { - float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + ((Rt+ATM_EPSILON) * (Rt+ATM_EPSILON))); - float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg; - if (delta2 >= 0.0) { - float din = -r * mu - sqrt(delta2); - if (din >= 0.0) { - dout = min(dout, din); - } - } - return dout; -} - -vec3 transmittanceFromTexture(const float r, const float mu) { - float u_r = sqrt((r - Rg) / (Rt - Rg)); - // See Colliene to understand the different mapping. - float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - - return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; -} - -vec3 transmittance(const float r, const float mu, const float d) { - vec3 result; - float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); - float mu1 = (r * mu + d) / r1; - if (mu > 0.0) { - result = min(transmittanceFromTexture(r, mu) / - transmittanceFromTexture(r1, mu1), 1.0); - } else { - result = min(transmittanceFromTexture(r1, -mu1) / - transmittanceFromTexture(r, -mu), 1.0); - } - return result; -} - -vec3 integrand(float r, float mu, float muS, float nu, float t) { - float ri = sqrt(r * r + t * t + 2.0 * r * mu * t); - float mui = (r * mu + t) / ri; - float muSi = (nu * t + muS * r) / ri; - return texture4D(deltaJTexture, ri, mui, muSi, nu).rgb * transmittance(r, mu, t); -} - -float rayDistance(const float r, const float mu) { - // cosine law - float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) + - (Rt + ATM_EPSILON)*(Rt + ATM_EPSILON)); - float distance = distanceAtmosphereIntersect; - float delta = r * r * (mu * mu - 1.0) + Rg * Rg; - // No imaginary numbers... :-) - if (delta >= 0.0) { - float distanceEarthIntersect = -r * mu - sqrt(delta); - if (distanceEarthIntersect >= 0.0) { - distance = min(distanceAtmosphereIntersect, distanceEarthIntersect); - } - } - return distance; -} - -vec3 inscatter(float r, float mu, float muS, float nu) { - vec3 raymie = vec3(0.0); - float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); - float xi = 0.0; - vec3 raymiei = integrand(r, mu, muS, nu, 0.0); - for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { - float xj = float(i) * dx; - vec3 raymiej = integrand(r, mu, muS, nu, xj); - raymie += (raymiei + raymiej) / 2.0 * dx; - xi = xj; - raymiei = raymiej; - } - return raymie; -} - -void main(void) { - float mu, muS, nu; - getMuMuSNu(r, dhdH, mu, muS, nu); - - renderTarget1 = vec4(inscatter(r, mu, muS, nu), 1.0); -} \ No newline at end of file diff --git a/modules/base/shaders/irradiance_calc_fs.glsl b/modules/base/shaders/irradiance_calc_fs.glsl deleted file mode 100644 index 107e422f82..0000000000 --- a/modules/base/shaders/irradiance_calc_fs.glsl +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTableColor; - -uniform sampler2D transmittanceTexture; - -void unmappingRAndMuSun(out float r, out float muSun) { - // See Bruneton and Colliene to understand the mapping. - muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(OTHER_TEXTURES_W) - 1.0f) * (1.0f + 0.2f); - r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) - 1.0f) * (Rt - Rg); -} - -vec3 transmittance(const float r, const float mu) { - float u_r = sqrt((r - Rg) / (Rt - Rg)); - // See Colliene to understand the different mapping. - float u_mu = atan((mu + 0.15f) / (1.0f + 0.15f) * tan(1.5f)) / 1.5f; - - return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; -} - -void main(void) { - float muSun, r; - unmappingRAndMuSun(r, muSun); - // We are calculating the Irradiance for L0, i.e., - // only the radiance comming from sun direction is accounted: - // E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded). - // Because we consider the Planet as a perfect sphere and we are - // considering only single scattering here, the - // dot product dot(w,n) is equal to dot(s,n) that is equal to - // dot(s, r/||r||) = muSun. - renderTableColor = vec4(transmittance(r, muSun) * clamp(muSun, 0.0, 1.0), 0.0); -} diff --git a/modules/base/shaders/irradiance_sup_calc_fs.glsl b/modules/base/shaders/irradiance_sup_calc_fs.glsl deleted file mode 100644 index 5b6c4c36b4..0000000000 --- a/modules/base/shaders/irradiance_sup_calc_fs.glsl +++ /dev/null @@ -1,96 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version 330 - -#include "atmosphere_common.glsl" - -out vec4 renderTableColor; - -uniform float first; - -const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); -const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); - -uniform sampler2D transmittanceTexture; -uniform sampler3D deltaSRTexture; -uniform sampler3D deltaSMTexture; - -// Rayleigh phase -float phaseFunctionR(const float mu) { - return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); -} - -// Mie phase -float phaseFunctionM(const float mu) { - return (3.0 / (8.0 * M_PI)) * - ( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) / - ( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) ); -} - -vec4 texture4D(sampler3D table, const float r, const float mu, - const float muS, const float nu) -{ - float H = sqrt(Rt * Rt - Rg * Rg); - float rho = sqrt(r * r - Rg * Rg); - float rmu = r * mu; - float delta = rmu * rmu - r * r + Rg * Rg; - vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); - float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); - float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); - float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); - float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); - float uNu = floor(lerp); - lerp = lerp - uNu; - return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + - texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; -} - -void main(void) { - float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY_H) - 1.0) * (Rt - Rg); - float mu_s = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY_W) - 1.0) * (1.0 + 0.2); - vec3 s = vec3(max(sqrt(1.0 - mu_s * mu_s), 0.0), 0.0, mu_s); - - vec3 result = vec3(0.0); - for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) { - float phi = (float(iphi) + 0.5) * dphi; - for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) { - float theta = (float(itheta) + 0.5) * dtheta; - float dw = dtheta * dphi * sin(theta); - vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta)); - float nu = dot(s, w); - if (first == 1.0) { - float pr1 = phaseFunctionR(nu); - float pm1 = phaseFunctionM(nu); - vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb; - vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu).rgb; - result += (ray1 * pr1 + mie1 * pm1) * w.z * dw; - } else { - result += texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb * w.z * dw; - } - } - } - - renderTableColor = vec4(result, 0.0); -} \ No newline at end of file diff --git a/modules/base/shaders/transmittance_calc_fs.glsl b/modules/base/shaders/transmittance_calc_fs.glsl deleted file mode 100644 index 5e0dc55c48..0000000000 --- a/modules/base/shaders/transmittance_calc_fs.glsl +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ -#version __CONTEXT__ - -#include "atmosphere_common.glsl" - -//layout(location = 1) out vec4 renderTableColor; -out vec4 renderTableColor; - -// In the following shaders r (altitude) is the length of vector/position x in the -// atmosphere (or on the top of it when considering an observer in space), -// where the light is comming from the opposity direction of the view direction, -// here the vector v or viewDirection. -// Rg is the planet radius - -float rayDistance(const float r, const float mu) { - // The light ray starting at the observer in/on the atmosphere can - // have to possible end points: the top of the atmosphere or the - // planet ground. So the shortest path is the one we are looking for, - // otherwise we may be passing through the ground. - - // cosine law - float atmRadiusEps = Rt + ATM_EPSILON; - float rayDistanceAtmosphere = -r * mu + - sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps); - float delta = r * r * (mu * mu - 1.0f) + Rg * Rg; - // No imaginary numbers... :-) - if (delta >= 0.0f) { - float rayDistanceGround = -r * mu - sqrt(delta); - if (rayDistanceGround >= 0.0f) { - return min(rayDistanceAtmosphere, rayDistanceGround); - } - } - return rayDistanceAtmosphere; -} - -float opticalDepth(const float r, const float mu, const float H) { - float r2 = r*r; - // Is ray below horizon? The transmittance table will have only - // the values for transmittance starting at r (x) until the - // light ray touches the atmosphere or the ground and only for - // view angles v between 0 and pi/2 + eps. That's because we - // can calculate the transmittance for angles bigger than pi/2 - // just inverting the ray direction and starting and ending points. - - // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) - float cosZenithHorizon = -sqrt( 1.0f - ( ( Rg * Rg ) / r2 ) ); - if (mu < cosZenithHorizon) - return 1e9; - - // Integrating using the Trapezoidal rule: - // Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i))) - float b_a = rayDistance(r, mu); - float deltaStep = b_a / float(TRANSMITTANCE_STEPS); - // cosine law - float y_i = exp(-(r - Rg) / H); - - float x_step = 0.0f; - float accumulation = 0.0f; - for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) { - float x_i = float(i) * deltaStep; - // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) - // In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu - float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H); - accumulation += (y_ii + y_i); - //x_step = x_i; - y_i = y_ii; - } - return accumulation * ( b_a / ( 2 * TRANSMITTANCE_STEPS ) ); -} - -void unmappingRAndMu(out float r, out float mu) { - float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W); - float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H); - - // In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2) - r = sqrt( Rg * Rg + (u_r * u_r) * (Rt * Rt - Rg * Rg) ); - - // In the paper the author suggest mu = dot(v,x)/||x|| with ||v|| = 1.0 - // Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6)) - // But the below one is better. See Colliene. - mu = -0.15f + tan(1.5f * u_mu) / tan(1.5f) * (1.0f + 0.15f); -} - -void main(void) { - float r, muSun; - unmappingRAndMu(r, muSun); - vec3 opDepth = betaMieExtinction * opticalDepth(r, muSun, HM) + - betaRayleigh * opticalDepth(r, muSun, HR); - - renderTableColor = vec4( exp( -opDepth ), 0.0f ); -}