summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.glsl31
-rw-r--r--earth.glsl50
2 files changed, 40 insertions, 41 deletions
diff --git a/common.glsl b/common.glsl
index 13dd0c2..0f48a06 100644
--- a/common.glsl
+++ b/common.glsl
@@ -83,11 +83,15 @@ const float M_PI = 3.141592657;
uniform sampler2D transmittanceSampler;
+// Boring, make both nvidia and amd work, both are not ieee compliant
+// in its own way.
+// FIXME in the long term we need to make sure that sqrt *never* gets
+// called with a negative argument
float ieeesqrt(float v)
{
float ret;
if (v < 0.0) {
- ret = 0.0/0.0;
+ ret = 0.0/0.0 + sqrt(-1.0);
} else {
ret = sqrt(v);
}
@@ -99,21 +103,10 @@ vec2 ieeesqrt(vec2 v)
return vec2(ieeesqrt(v.x), ieeesqrt(v.y));
}
-float ieeepow(float b, float e)
-{
- float ret;
- if (b < 0.0 && floor(e) != e) {
- ret = 0.0/0.0;
- } else {
- ret = pow(b, e);
- }
- return ret;
-}
-
vec2 getTransmittanceUV(float r, float mu) {
float uR, uMu;
#ifdef TRANSMITTANCE_NON_LINEAR
- uR = ieeesqrt((r - Rg) / (Rt - Rg));
+ uR = sqrt(max(0.0, (r - Rg) / (Rt - Rg)));
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
#else
uR = (r - Rg) / (Rt - Rg);
@@ -137,8 +130,8 @@ void getIrradianceRMuS(out float r, out float muS) {
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
{
- float H = ieeesqrt(Rt * Rt - Rg * Rg);
- float rho = ieeesqrt(r * r - Rg * Rg);
+ float H = sqrt(max(0.0, Rt * Rt - Rg * Rg));
+ float rho = sqrt(max(0.0, r * r - Rg * Rg));
#ifdef INSCATTER_NON_LINEAR
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
@@ -174,7 +167,7 @@ void getMuMuSNu(float r, vec4 dhdH, out float mu, out float muS, out float nu) {
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, -ieeesqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
+ mu = min(mu, -sqrt(max(0.0, 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);
@@ -222,7 +215,7 @@ vec3 transmittance(float r, float mu) {
// transmittance(=transparency) of atmosphere for infinite ray (r,mu)
// (mu=cos(view zenith angle)), or zero if ray intersects ground
vec3 transmittanceWithShadow(float r, float mu) {
- return mu < -ieeesqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittance(r, mu);
+ return mu < -sqrt(max(0.0, 1.0 - (Rg / r) * (Rg / r))) ? vec3(0.0) : transmittance(r, mu);
}
// transmittance(=transparency) of atmosphere between x and x0
@@ -244,7 +237,7 @@ vec3 transmittance(float r, float mu, vec3 v, vec3 x0) {
// (mu=cos(view zenith angle)), intersections with ground ignored
// H=height scale of exponential density function
float opticalDepth(float H, float r, float mu, float d) {
- float a = ieeesqrt((0.5/H)*r);
+ float a = sqrt((0.5/H)*r);
vec2 a01 = a*vec2(mu, mu + d / r);
vec2 a01s = sign(a01);
vec2 a01sq = a01*a01;
@@ -287,7 +280,7 @@ float phaseFunctionR(float mu) {
// Mie phase function
float phaseFunctionM(float mu) {
- return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * ieeepow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
+ return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(max(0.0, 1.0 + (mieG*mieG) - 2.0*mieG*mu), -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
}
// approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision")
diff --git a/earth.glsl b/earth.glsl
index 2b37122..908601d 100644
--- a/earth.glsl
+++ b/earth.glsl
@@ -64,13 +64,15 @@ vec3 inscatter(inout vec3 x, inout float t, vec3 v, vec3 s, out float r, out flo
vec3 result;
r = length(x);
mu = dot(x, v) / r;
- float d = -r * mu - ieeesqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
- if (d > 0.0) { // if x in space and ray intersects atmosphere
+ if ((r * r * (mu * mu - 1.0) + Rt * Rt) >= 0.0) {
+ float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
+ if (d > 0.0) { // if x in space and ray intersects atmosphere
// move x to nearest intersection of ray with top atmosphere boundary
x += d * v;
t -= d;
mu = (r * mu + d) / Rt;
r = Rt;
+ }
}
if (r <= Rt) { // if ray intersects atmosphere
float nu = dot(v, s);
@@ -96,19 +98,19 @@ vec3 inscatter(inout vec3 x, inout float t, vec3 v, vec3 s, out float r, out flo
#ifdef FIX
// avoids imprecision problems near horizon by interpolating between two points above and below horizon
const float EPS = 0.004;
- float muHoriz = -ieeesqrt(1.0 - (Rg / r) * (Rg / r));
+ float muHoriz = -sqrt(max(0.0, 1.0 - (Rg / r) * (Rg / r)));
if (abs(mu - muHoriz) < EPS) {
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
mu = muHoriz - EPS;
- r0 = ieeesqrt(r * r + t * t + 2.0 * r * t * mu);
+ r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
vec4 inScatter0 = texture4D(inscatterSampler, r, mu, muS, nu);
vec4 inScatter1 = texture4D(inscatterSampler, r0, mu0, muS0, nu);
vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
mu = muHoriz + EPS;
- r0 = ieeesqrt(r * r + t * t + 2.0 * r * t * mu);
+ r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
inScatter0 = texture4D(inscatterSampler, r, mu, muS, nu);
inScatter1 = texture4D(inscatterSampler, r0, mu0, muS0, nu);
@@ -159,8 +161,8 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenu
// water specular color due to sunLight
if (reflectance.w > 0.0) {
vec3 h = normalize(s - v);
- float fresnel = 0.02 + 0.98 * ieeepow(1.0 - dot(-v, h), 5.0);
- float waterBrdf = fresnel * ieeepow(max(dot(h, n), 0.0), 150.0);
+ 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;
}
@@ -184,9 +186,9 @@ vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) {
vec3 HDR(vec3 L) {
L = L * exposure;
- L.r = L.r < 1.413 ? ieeepow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r);
- L.g = L.g < 1.413 ? ieeepow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g);
- L.b = L.b < 1.413 ? ieeepow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b);
+ L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r);
+ L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g);
+ L.b = L.b < 1.413 ? pow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b);
return L;
}
@@ -196,21 +198,25 @@ void main() {
float r = length(x);
float mu = dot(x, v) / r;
- float t = -r * mu - ieeesqrt(r * r * (mu * mu - 1.0) + Rg * Rg);
-
- vec3 g = x - vec3(0.0, 0.0, Rg + 10.0);
- float a = v.x * v.x + v.y * v.y - v.z * v.z;
- float b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z);
- float c = g.x * g.x + g.y * g.y - g.z * g.z;
- float d = -(b + ieeesqrt(b * b - 4.0 * a * c)) / (2.0 * a);
- bool cone = d > 0.0 && abs(x.z + d * v.z - Rg) <= 10.0;
-
- if (t > 0.0) {
+ float t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);
+
+ if ((r * r * (mu * mu - 1.0) + Rg * Rg) >= 0.0) {
+ vec3 g = x - vec3(0.0, 0.0, Rg + 10.0);
+ float a = v.x * v.x + v.y * v.y - v.z * v.z;
+ float b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z);
+ float c = g.x * g.x + g.y * g.y - g.z * g.z;
+ float d = -(b + ieeesqrt(b * b - 4.0 * a * c)) / (2.0 * a);
+ bool cone = d > 0.0 && abs(x.z + d * v.z - Rg) <= 10.0;
+
+ if (t > 0.0) {
if (cone && d < t) {
- t = d;
+ t = d;
}
- } else if (cone) {
+ } else if (cone) {
t = d;
+ }
+ } else {
+ t = 0.0;
}
vec3 attenuation;