diff --git a/include/merian-shaders/common.glsl b/include/merian-shaders/common.glsl index df83939..9278024 100644 --- a/include/merian-shaders/common.glsl +++ b/include/merian-shaders/common.glsl @@ -3,7 +3,10 @@ #define M_PI 3.14159265358979323846 #define TWO_PI 6.283185307179586 +#define FOUR_PI 12.566370614359172 #define INV_PI 0.3183098861837907 +#define INV_TWO_PI 0.15915494309189535 +#define INV_FOUR_PI 0.07957747154594767 #define INV_SQRT_TWO_PI 0.3989422804014327 // returns 1/x if x > 0 else 1. diff --git a/include/merian-shaders/von_mises_fisher.glsl b/include/merian-shaders/von_mises_fisher.glsl index 33299b0..53308d1 100644 --- a/include/merian-shaders/von_mises_fisher.glsl +++ b/include/merian-shaders/von_mises_fisher.glsl @@ -8,14 +8,14 @@ // numerically robust von Mises Fisher lobe float vmf_pdf(const float kappa, const float dotmu) { - if (kappa < 1e-4) return 1.0 / (4.0 * M_PI); - return kappa / (2.0 * M_PI * (1.0 - exp(-2.0 * kappa))) * exp(kappa * (dotmu - 1.0)); + if (kappa < 1e-4) return INV_FOUR_PI; + return kappa / (TWO_PI * (1.0 - exp(-2.0 * kappa))) * exp(kappa * (dotmu - 1.0)); } // see wenzel's doc on numerically stable expression for vmm vec3 vmf_sample(const float kappa, const vec2 random) { - const float w = 1.0 + log(random.x + (1.0-random.x) * exp(-2.0 * kappa)) / kappa; - const vec2 v = vec2(sin(2.0 * M_PI * random.y), cos(2.0 * M_PI * random.y)); + const float w = 1.0 + log(random.x + (1.0 - random.x) * exp(-2.0 * kappa)) / kappa; + const vec2 v = vec2(sin(TWO_PI * random.y), cos(TWO_PI * random.y)); return vec3(sqrt(1.0 - w * w) * v, w); } @@ -26,7 +26,7 @@ vec3 vmf_sample(const vec3 z, const float kappa, const vec2 random) { // compute concentration parameter for given maximum density x float vmf_get_kappa(const float pdf) { - if (pdf > 0.795) return 2.0 * M_PI * pdf; + if (pdf > 0.795) return TWO_PI * pdf; return max(1e-5, (168.479 * pdf * pdf + 16.4585 * pdf - 2.39942) / (-1.12718 * pdf * pdf + 29.1433 * pdf + 1.0)); }