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>2018-11-19 20:03:06 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-11-19 20:05:15 +0300
commit7bb512594cd9502fea290ac6124f2eb5fd3cfce8 (patch)
tree190b9e4184e6eabf3349e74bf6d58c6da9f29288 /source/blender/draw/engines/workbench/shaders
parent2b56d2183972a0cb3b1355652a6709599ae6af0d (diff)
Workbench: Use non-negative lighting evaluation
This makes the lighting a bit more diffuse but don't produce negative values. Add a bias of 1.5f to make the lighting a bit more directionnal. The implementation is based on: https://github.com/kayru/Probulator/blob/master/Source/Probulator/SphericalHarmonics.h#L136 which is derived from: http://www.geomerics.com/wp-content/uploads/2015/08/CEDEC_Geomerics_ReconstructingDiffuseLighting1.pdf The shader implementation is optimized and has the same runtime cost as previous method: * no sh eval : 0.13ms * prev sh eval : 0.14ms * new sh eval : 0.22ms * new sh eval opti : 0.14ms
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl45
1 files changed, 39 insertions, 6 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
index 1b93fc0014c..ab48aa5fa03 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
@@ -1,18 +1,50 @@
#define BLINN
+#if STUDIOLIGHT_SH_BANDS == 2
+vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
+{
+ /* http://www.geomerics.com/wp-content/uploads/2015/08/CEDEC_Geomerics_ReconstructingDiffuseLighting1.pdf */
+ /* Highly optimized form, precompute as much as we can. */
+ /**
+ * R1 = 0.5 * vec3(L3.r, L2.r, L1.r);
+ * sh_coefs[0..2] = R1 / length(R1);
+ **/
+ vec3 q;
+ q.x = dot(sh_coefs[1], N);
+ q.y = dot(sh_coefs[2], N);
+ q.z = dot(sh_coefs[3], N);
+ q = 0.5 * q + 0.5;
+
+ /**
+ * R0 = L0.r;
+ * lr1_r0 = lenR1 / R0;
+ * p = 1.0 + 2.0 * lr1_r0;
+ * a = (1.0 - lr1_r0) / (1.0 + lr1_r0);
+ * return R0 * (a + (1.0 - a) * (p + 1.0) * pow(q, p));
+ *
+ * sh_coefs[4] = p;
+ * sh_coefs[5] = R0 * a;
+ * sh_coefs[0] = R0 * (1.0 - a) * (p + 1.0);
+ **/
+ q = pow(q, sh_coefs[4]);
+ return sh_coefs[0] * q + sh_coefs[5];
+}
+
+#else
+
vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
{
vec3 sh = 0.282095 * sh_coefs[0];
-#if STUDIOLIGHT_SH_BANDS > 1
+# if STUDIOLIGHT_SH_BANDS > 1
float nx = N.x;
float ny = N.y;
float nz = N.z;
sh += -0.488603 * nz * sh_coefs[1];
sh += 0.488603 * ny * sh_coefs[2];
sh += -0.488603 * nx * sh_coefs[3];
-#endif
-#if STUDIOLIGHT_SH_BANDS > 2
+# endif
+# if STUDIOLIGHT_SH_BANDS > 2
float nx2 = nx * nx;
float ny2 = ny * ny;
float nz2 = nz * nz;
@@ -21,8 +53,8 @@ vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
sh += 0.315392 * (3.0 * ny2 - 1.0) * sh_coefs[6];
sh += -1.092548 * nx * ny * sh_coefs[7];
sh += 0.546274 * (nx2 - nz2) * sh_coefs[8];
-#endif
-#if STUDIOLIGHT_SH_BANDS > 4
+# endif
+# if STUDIOLIGHT_SH_BANDS > 4
float nx4 = nx2 * nx2;
float ny4 = ny2 * ny2;
float nz4 = nz2 * nz2;
@@ -35,9 +67,10 @@ vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
sh += (0.9461746957575601 * (nx2 - nz2) * (-1.0 + 7.0 * ny2)) * sh_coefs[15];
sh += (-1.7701307697799304 * nx * ny * (nx2 - 3.0 * nz2)) * sh_coefs[16];
sh += (0.6258357354491761 * (nx4 - 6.0 * nz2 * nx2 + nz4)) * sh_coefs[17];
-#endif
+# endif
return sh;
}
+#endif
vec3 get_world_diffuse_light(WorldData world_data, vec3 N)
{