Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-03-12 17:59:38 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-03-13 22:59:20 +0300
commit6a7f6f2867dc8a7aba8e91bf0fdf299ef276a65b (patch)
tree738770ecdbb2adc0ccb95be64d0db54f1637e976 /source/blender/draw/engines/eevee/shaders
parent5fee9dae5d772819f261be420b5128e0e2a561f9 (diff)
Cleanup: EEVEE: Remove hammersley texture and split hammersley code
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl92
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/random_lib.glsl38
5 files changed, 86 insertions, 65 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
index c190ca0e245..7ce95a4aff2 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -1,32 +1,14 @@
+/**
+ * Sampling distribution routines for Monte-carlo integration.
+ **/
+
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
-uniform sampler1D texHammersley;
-
-vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return T * vector.x + B * vector.y + N * vector.z;
-}
-
-vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return vec3(dot(T, vector), dot(B, vector), dot(N, vector));
-}
-
-#ifdef HAMMERSLEY_SIZE
-vec3 hammersley_3d(float i, float invsamplenbr)
-{
- vec3 Xi; /* Theta, cos(Phi), sin(Phi) */
-
- Xi.x = i * invsamplenbr;
- Xi.yz = texelFetch(texHammersley, int(i), 0).rg;
-
- return Xi;
-}
-#endif
-
-/* -------------- BSDFS -------------- */
+/* -------------------------------------------------------------------- */
+/** \name Microfacet GGX distribution
+ * \{ */
#define USE_VISIBLE_NORMAL 1
@@ -89,12 +71,18 @@ vec3 sample_ggx(vec3 rand, float alpha, vec3 V, vec3 N, vec3 T, vec3 B, out floa
return tangent_to_world(Ht, N, T, B);
}
-float pdf_hemisphere()
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniform Hemisphere
+ * \{ */
+
+float pdf_uniform_hemisphere()
{
return 0.5 * M_1_PI;
}
-vec3 sample_hemisphere(vec3 rand)
+vec3 sample_uniform_hemisphere(vec3 rand)
{
float z = rand.x; /* cos theta */
float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
@@ -103,45 +91,33 @@ vec3 sample_hemisphere(vec3 rand)
return vec3(x, y, z);
}
-vec3 sample_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf)
+vec3 sample_uniform_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf)
{
- vec3 Ht = sample_hemisphere(rand);
- pdf = pdf_hemisphere();
+ vec3 Ht = sample_uniform_hemisphere(rand);
+ pdf = pdf_uniform_hemisphere();
return tangent_to_world(Ht, N, T, B);
}
-#ifdef HAMMERSLEY_SIZE
-vec3 sample_ggx(float nsample,
- float inv_sample_count,
- float alpha,
- vec3 V,
- vec3 N,
- vec3 T,
- vec3 B,
- out float pdf)
-{
- vec3 Xi = hammersley_3d(nsample, inv_sample_count);
- return sample_ggx(Xi, alpha, V, N, T, B, pdf);
-}
+/** \} */
-vec3 sample_hemisphere(
- float nsample, float inv_sample_count, vec3 N, vec3 T, vec3 B, out float pdf)
-{
- vec3 Xi = hammersley_3d(nsample, inv_sample_count);
- return sample_hemisphere(Xi, N, T, B, pdf);
-}
+/* -------------------------------------------------------------------- */
+/** \name Uniform Cone sampling
+ * \{ */
-vec3 sample_cone(float nsample, float inv_sample_count, float angle, vec3 N, vec3 T, vec3 B)
+vec3 sample_uniform_cone(vec3 rand, float angle)
{
- vec3 Xi = hammersley_3d(nsample, inv_sample_count);
-
- float z = cos(angle * Xi.x); /* cos theta */
+ float z = cos(angle * rand.x); /* cos theta */
float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
- float x = r * Xi.y;
- float y = r * Xi.z;
-
- vec3 Ht = vec3(x, y, z);
+ float x = r * rand.y;
+ float y = r * rand.z;
+ return vec3(x, y, z);
+}
+vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Ht = sample_uniform_cone(rand, angle);
+ /* TODO pdf? */
return tangent_to_world(Ht, N, T, B);
}
-#endif
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
index 18fcfd4fd41..9ecc50d9df5 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(random_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
@@ -10,7 +11,6 @@ uniform float lodMax;
uniform float intensityFac;
uniform float sampleCount;
-uniform float invSampleCount;
in vec3 worldPosition;
@@ -147,8 +147,10 @@ void main()
float weight = 0.0;
vec3 out_radiance = vec3(0.0);
for (float i = 0; i < sampleCount; i++) {
+ vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount));
+
float pdf;
- vec3 L = sample_hemisphere(i, invSampleCount, N, T, B, pdf);
+ vec3 L = sample_uniform_hemisphere(Xi, N, T, B, pdf);
float NL = dot(N, L);
if (NL > 0.0) {
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 99cbf2839ad..11fc1fb4295 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(random_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
@@ -12,7 +13,6 @@ uniform float intensityFac;
uniform float fireflyFactor;
uniform float sampleCount;
-uniform float invSampleCount;
in vec3 worldPosition;
@@ -52,9 +52,11 @@ void main()
float weight = 0.0;
vec3 out_radiance = vec3(0.0);
for (float i = 0; i < sampleCount; i++) {
+ vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount));
+
float pdf;
/* Microfacet normal */
- vec3 H = sample_ggx(i, invSampleCount, roughness, V, N, T, B, pdf);
+ vec3 H = sample_ggx(Xi, roughness, V, N, T, B, pdf);
vec3 L = -reflect(V, H);
float NL = dot(N, L);
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
index b802b39c56e..d25ef23a706 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(random_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
@@ -14,7 +15,7 @@ uniform float visibilityRange;
uniform float visibilityBlur;
uniform float sampleCount;
-uniform float invSampleCount;
+uniform float;
out vec4 FragColor;
@@ -80,13 +81,15 @@ void main()
vec2 accum = vec2(0.0);
for (float i = 0; i < sampleCount; i++) {
- vec3 samp = sample_cone(i, invSampleCount, M_PI_2 * visibilityBlur, cos, T, B);
+ vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount));
+
+ vec3 samp = sample_uniform_cone(Xi, M_PI_2 * visibilityBlur, cos, T, B);
float depth = texture(probeDepth, samp).r;
depth = get_world_distance(depth, samp);
accum += vec2(depth, depth * depth);
}
- accum *= invSampleCount;
+ accum /= sampleCount;
accum = abs(accum);
/* Encode to normalized RGBA 8 */
diff --git a/source/blender/draw/engines/eevee/shaders/random_lib.glsl b/source/blender/draw/engines/eevee/shaders/random_lib.glsl
new file mode 100644
index 00000000000..25a3e0f56b4
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/random_lib.glsl
@@ -0,0 +1,38 @@
+
+/**
+ * Random numbers and low discrepency sequences utilities.
+ **/
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+/* From: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */
+float van_der_corput_radical_inverse(uint bits)
+{
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ /* Same as dividing by 0x100000000. */
+ return float(bits) * 2.3283064365386963e-10;
+}
+
+vec2 hammersley_2d(float i, float sample_count)
+{
+ vec2 rand;
+ rand.x = i / sample_count;
+ rand.y = van_der_corput_radical_inverse(uint(i));
+ return rand;
+}
+
+/* This transform a 2d random sample (in [0..1] range) to a sample located on a cylinder of the
+ * same range. This is because the sampling functions expect such a random sample which is
+ * normally precomputed. */
+vec3 rand2d_to_cylinder(vec2 rand)
+{
+ float theta = rand.x;
+ float phi = (rand.y - 0.5) * M_2PI;
+ float cos_phi = cos(phi);
+ float sin_phi = sqrt(1.0 - sqr(cos_phi)) * sign(phi);
+ return vec3(theta, cos_phi, sin_phi);
+}