Fix nishita sky artifacts on some GPUs
It could happen that values returned by dot() were slightly larger than 1 or less than -1 due to precision errors, but acos() is undefined outside of [-1, 1]. This would lead to NaN values on some GPUs, causing visible artifacts.
This commit is contained in:
parent
d610cc6a2f
commit
ca96174b6b
|
@ -40,4 +40,9 @@ float attenuate(const float dist) {
|
|||
// 1.0 / (quadratic * dist * dist);
|
||||
}
|
||||
|
||||
float safe_acos(const float x) {
|
||||
// acos is undefined if |x| > 1
|
||||
return acos(clamp(x, -1.0, 1.0));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef _SKY_GLSL_
|
||||
#define _SKY_GLSL_
|
||||
|
||||
#include "std/math.glsl"
|
||||
|
||||
uniform sampler2D nishitaLUT;
|
||||
uniform vec2 nishitaDensity;
|
||||
|
||||
|
@ -119,7 +121,7 @@ vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const floa
|
|||
|
||||
// Idea behind this: "Rotate" everything by iPos (-> iPos is the new zenith) and then all calculations for the
|
||||
// inner integral only depend on the sample height (iHeight) and sunTheta (angle between sun and new zenith).
|
||||
float sunTheta = acos(dot(normalize(iPos), normalize(pSun)));
|
||||
float sunTheta = safe_acos(dot(normalize(iPos), normalize(pSun)));
|
||||
vec3 jAttn = nishita_lookupLUT(iHeight, sunTheta);
|
||||
|
||||
// Calculate attenuation
|
||||
|
|
Loading…
Reference in a new issue