diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-11-19 20:03:06 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-11-19 20:05:15 +0300 |
commit | 7bb512594cd9502fea290ac6124f2eb5fd3cfce8 (patch) | |
tree | 190b9e4184e6eabf3349e74bf6d58c6da9f29288 /source/blender/draw/engines/workbench/workbench_studiolight.c | |
parent | 2b56d2183972a0cb3b1355652a6709599ae6af0d (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/workbench_studiolight.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_studiolight.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c index c852d7abb90..65732b52471 100644 --- a/source/blender/draw/engines/workbench/workbench_studiolight.c +++ b/source/blender/draw/engines/workbench/workbench_studiolight.c @@ -36,10 +36,55 @@ void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd) { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED); +#if STUDIOLIGHT_SH_BANDS == 2 + /* Use Geomerics non-linear SH. */ + mul_v3_v3fl(wd->spherical_harmonics_coefs[0], sl->spherical_harmonics_coefs[0], M_1_PI); + /* Swizzle to make shader code simpler. */ + for (int i = 0; i < 3; ++i) { + copy_v3_fl3(wd->spherical_harmonics_coefs[i+1], -sl->spherical_harmonics_coefs[3][i], + sl->spherical_harmonics_coefs[2][i], + -sl->spherical_harmonics_coefs[1][i]); + mul_v3_fl(wd->spherical_harmonics_coefs[i+1], M_1_PI * 1.5f); /* 1.5f is to improve the contrast a bit. */ + } + + /* Precompute as much as we can. See shader code for derivation. */ + float len_r1[3], lr1_r0[3], p[3], a[3]; + for (int i = 0; i < 3; ++i) { + mul_v3_fl(wd->spherical_harmonics_coefs[i+1], 0.5f); + len_r1[i] = len_v3(wd->spherical_harmonics_coefs[i+1]); + mul_v3_fl(wd->spherical_harmonics_coefs[i+1], 1.0f / len_r1[i]); + } + /* lr1_r0 = lenR1 / R0; */ + copy_v3_v3(lr1_r0, wd->spherical_harmonics_coefs[0]); + invert_v3(lr1_r0); + mul_v3_v3(lr1_r0, len_r1); + /* p = 1.0 + 2.0 * lr1_r0; */ + copy_v3_v3(p, lr1_r0); + mul_v3_fl(p, 2.0f); + add_v3_fl(p, 1.0f); + /* a = (1.0 - lr1_r0) / (1.0 + lr1_r0); */ + copy_v3_v3(a, lr1_r0); + add_v3_fl(a, 1.0f); + invert_v3(a); + negate_v3(lr1_r0); + add_v3_fl(lr1_r0, 1.0f); + mul_v3_v3(a, lr1_r0); + /* sh_coefs[4] = p; */ + copy_v3_v3(wd->spherical_harmonics_coefs[4], p); + /* sh_coefs[5] = R0 * a; */ + mul_v3_v3v3(wd->spherical_harmonics_coefs[5], wd->spherical_harmonics_coefs[0], a); + /* sh_coefs[0] = R0 * (1.0 - a) * (p + 1.0); */ + negate_v3(a); + add_v3_fl(a, 1.0f); + add_v3_fl(p, 1.0f); + mul_v3_v3(a, p); + mul_v3_v3(wd->spherical_harmonics_coefs[0], a); +#else for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) { /* Can't memcpy because of alignment */ copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]); } +#endif } static void compute_parallel_lines_nor_and_dist(const float v1[2], const float v2[2], const float v3[2], float r_line[2]) |