diff options
Diffstat (limited to 'common.glsl')
-rw-r--r-- | common.glsl | 31 |
1 files changed, 12 insertions, 19 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")
|