diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-18 16:17:46 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-18 16:32:53 +0300 |
commit | 7747d4cecf078589f614813d0e5e0a753d4e10b5 (patch) | |
tree | 099fe569b48e44f1406d8420ea618ad27f00ee84 /source/blender/draw | |
parent | fec97ec94939ab32b43e3221e4c611e1e873a563 (diff) |
Workbench: increased Quality of the diffuse lighting model
- implemented Spherical Harmonics L2 for diffuse shading.
TODO: caching the precalculated harmonics so it won't take soo long to
open the popover
Diffstat (limited to 'source/blender/draw')
5 files changed, 29 insertions, 48 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl index 069cb0f52d8..2ba6e0e8e55 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -4,12 +4,7 @@ struct LightData { }; struct WorldData { - vec4 diffuse_light_x_pos; - vec4 diffuse_light_x_neg; - vec4 diffuse_light_y_pos; - vec4 diffuse_light_y_neg; - vec4 diffuse_light_z_pos; - vec4 diffuse_light_z_neg; + vec3 spherical_harmonics_coefs[9]; vec4 background_color_low; vec4 background_color_high; vec4 object_outline_color; 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 9d256e5350a..71adc751f0a 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,24 +1,32 @@ #define BLINN +vec3 spherical_harmonics_L2(vec3 N, vec3 spherical_harmonics_coefs[9]) +{ + vec3 sh = vec3(0.0); + + sh += 0.282095 * spherical_harmonics_coefs[0]; + + sh += -0.488603 * N.z * spherical_harmonics_coefs[1]; + sh += 0.488603 * N.y * spherical_harmonics_coefs[2]; + sh += -0.488603 * N.x * spherical_harmonics_coefs[3]; + + sh += 1.092548 * N.x * N.z * spherical_harmonics_coefs[4]; + sh += -1.092548 * N.z * N.y * spherical_harmonics_coefs[5]; + sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * spherical_harmonics_coefs[6]; + sh += -1.092548 * N.x * N.y * spherical_harmonics_coefs[7]; + sh += 0.546274 * (N.x * N.x - N.z * N.z) * spherical_harmonics_coefs[8]; + + return sh; +} + vec3 get_world_diffuse_light(WorldData world_data, vec3 N) { - vec4 result = world_data.diffuse_light_x_pos * clamp(N.x, 0.0, 1.0); - result = mix(result, world_data.diffuse_light_x_neg, clamp(-N.x, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_pos, clamp(-N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_neg, clamp(N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_z_pos, clamp(N.z, 0.0, 1.0)); - return mix(result, world_data.diffuse_light_z_neg, clamp(-N.z, 0.0, 1.0)).xyz; + return (spherical_harmonics_L2(vec3(N.x, N.y, -N.z), world_data.spherical_harmonics_coefs)); } vec3 get_camera_diffuse_light(WorldData world_data, vec3 N) { - vec4 result = world_data.diffuse_light_x_pos * clamp(N.x, 0.0, 1.0); - result = mix(result, world_data.diffuse_light_x_neg, clamp(-N.x, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_z_pos, clamp( N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_z_neg, clamp(-N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_pos, clamp( N.z, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_neg, clamp(-N.z, 0.0, 1.0)); - return result.rgb; + return (spherical_harmonics_L2(vec3(N.x, -N.z, -N.y), world_data.spherical_harmonics_coefs)); } /* N And I are in View Space. */ diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 45af9366a43..b4a2330f173 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -118,7 +118,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2]; } } - } void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3]) @@ -154,20 +153,8 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa wd->num_lights = light_index; } -#if 0 - if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { - BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED); - float rot_matrix[3][3]; - axis_angle_to_mat3_single(rot_matrix, 'Z', wpd->shading.studiolight_rot_z); - mul_v3_m3v3(e_data.display.light_direction, rot_matrix, wpd->studio_light->light_direction); - } - else { -#else - { -#endif - copy_v3_v3(light_direction, scene->display.light_direction); - negate_v3(light_direction); - } + copy_v3_v3(light_direction, scene->display.light_direction); + negate_v3(light_direction); DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data); } diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 90d8cfc3dd2..9e43a5c4a48 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -112,12 +112,7 @@ typedef struct WORKBENCH_UBO_Light { } WORKBENCH_UBO_Light; typedef struct WORKBENCH_UBO_World { - float diffuse_light_x_pos[4]; - float diffuse_light_x_neg[4]; - float diffuse_light_y_pos[4]; - float diffuse_light_y_neg[4]; - float diffuse_light_z_pos[4]; - float diffuse_light_z_neg[4]; + float spherical_harmonics_coefs[9][4]; float background_color_low[4]; float background_color_high[4]; float object_outline_color[4]; diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c index 6451d1f57c8..e5e24cbb88a 100644 --- a/source/blender/draw/engines/workbench/workbench_studiolight.c +++ b/source/blender/draw/engines/workbench/workbench_studiolight.c @@ -34,14 +34,10 @@ void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd) { - BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED); - - copy_v3_v3(wd->diffuse_light_x_pos, sl->diffuse_light[STUDIOLIGHT_X_POS]); - copy_v3_v3(wd->diffuse_light_x_neg, sl->diffuse_light[STUDIOLIGHT_X_NEG]); - copy_v3_v3(wd->diffuse_light_y_pos, sl->diffuse_light[STUDIOLIGHT_Y_POS]); - copy_v3_v3(wd->diffuse_light_y_neg, sl->diffuse_light[STUDIOLIGHT_Y_NEG]); - copy_v3_v3(wd->diffuse_light_z_pos, sl->diffuse_light[STUDIOLIGHT_Z_POS]); - copy_v3_v3(wd->diffuse_light_z_neg, sl->diffuse_light[STUDIOLIGHT_Z_NEG]); + BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED); + for (int i = 0; i < 9; i++) { + copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]); + } } static void compute_parallel_lines_nor_and_dist(const float v1[2], const float v2[2], const float v3[2], float r_line[2]) |