From e862bcd6c8cb218c2213ac4a05a11dd13dbdecbf Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 16 May 2018 16:42:30 +0200 Subject: [PATCH] Workbench: World based studio lighting Disabled shadows for now as the calculation of the light direction is still to bogus. --- .../studiolights/camera/camera01.hdr | Bin 0 -> 55703 bytes .../studiolights/camera/camera02.jpg | Bin 0 -> 22559 bytes release/datafiles/studiolights/sl01.jpg | Bin 7314 -> 0 bytes .../studiolights/{ => world}/sl02.jpg | Bin release/scripts/startup/bl_ui/space_view3d.py | 13 +- source/blender/blenkernel/BKE_studiolight.h | 13 +- .../blender/blenkernel/intern/studiolight.c | 122 +++++++++++++++--- .../shaders/workbench_composite_frag.glsl | 9 +- .../shaders/workbench_world_light_lib.glsl | 17 ++- .../engines/workbench/workbench_materials.c | 50 +++++-- source/blender/makesdna/DNA_view3d_types.h | 3 + source/blender/makesrna/intern/rna_space.c | 91 +++++++++---- 12 files changed, 254 insertions(+), 64 deletions(-) create mode 100644 release/datafiles/studiolights/camera/camera01.hdr create mode 100644 release/datafiles/studiolights/camera/camera02.jpg delete mode 100644 release/datafiles/studiolights/sl01.jpg rename release/datafiles/studiolights/{ => world}/sl02.jpg (100%) diff --git a/release/datafiles/studiolights/camera/camera01.hdr b/release/datafiles/studiolights/camera/camera01.hdr new file mode 100644 index 0000000000000000000000000000000000000000..341b15524c5fa56b0cf4efce0681ce2a592fa2ae GIT binary patch literal 55703 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

0`>egsIs2UbuVJsf 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 diff --git a/release/datafiles/studiolights/sl02.jpg b/release/datafiles/studiolights/world/sl02.jpg similarity index 100% rename from release/datafiles/studiolights/sl02.jpg rename to release/datafiles/studiolights/world/sl02.jpg diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f053a326ef1..53dea7ad2e8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3510,14 +3510,17 @@ class VIEW3D_PT_shading(Panel): col.row().prop(shading, "light", expand=True) if shading.light == 'STUDIO': col.row().template_icon_view(shading, "studio_light") + if shading.studio_light_orientation == 'WORLD': + col.row().prop(shading, "studiolight_rot_z") col.separator() - row = col.row() - row.prop(shading, "show_shadows") - sub = row.row() - sub.active = shading.show_shadows - sub.prop(shading, "shadow_intensity", text="") + if not(shading.light == 'STUDIO' and shading.studio_light_orientation == 'WORLD'): + row = col.row() + row.prop(shading, "show_shadows") + sub = row.row() + sub.active = shading.show_shadows + sub.prop(shading, "shadow_intensity", text="") col.prop(shading, "show_object_outline") diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index c65e9050157..33c2af668b2 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -38,6 +38,11 @@ #include "DNA_space_types.h" +/* + * These defines are the indexes in the StudioLight.diffuse_light + * X_POS means the light that is traveling towards the positive X + * So Light direction. + */ #define STUDIOLIGHT_X_POS 0 #define STUDIOLIGHT_X_NEG 1 #define STUDIOLIGHT_Y_POS 2 @@ -47,8 +52,11 @@ enum StudioLightFlag { - STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0), - STUDIOLIGHT_EXTERNAL_FILE = (1 << 1), + STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0), + STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1), + STUDIOLIGHT_EXTERNAL_FILE = (1 << 2), + STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3), + STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4), } StudioLightFlag; typedef struct StudioLight @@ -60,6 +68,7 @@ typedef struct StudioLight int icon_id; int index; float diffuse_light[6][3]; + float light_direction[3]; } StudioLight; void BKE_studiolight_init(void); diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 24dc274cf20..baecbd90bc5 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -40,6 +40,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_path_util.h" +#include "BLI_rand.h" #include "BLI_string.h" #include "DNA_listBase.h" @@ -54,7 +55,8 @@ static ListBase studiolights; #define STUDIO_LIGHT_EXTENSIONS ".jpg", ".hdr" #define STUDIO_LIGHT_DIFFUSE_SAMPLE_STEP 64 -static const char *STUDIO_LIGHT_FOLDER = "studiolights/"; +static const char *STUDIO_LIGHT_CAMERA_FOLDER = "studiolights/camera/"; +static const char *STUDIO_LIGHT_WORLD_FOLDER = "studiolights/world/"; /* FUNCTIONS */ static void studiolight_free(struct StudioLight *sl) @@ -79,6 +81,16 @@ static void direction_to_equirectangular(float r[2], const float dir[3]) r[1] = (acosf(dir[2] / 1.0) - M_PI) / -M_PI; } +static void equirectangular_to_direction(float r[3], float u, float v) +{ + float phi = (-(M_PI * 2))*u + M_PI; + float theta = -M_PI*v + M_PI; + float sin_theta = sinf(theta); + r[0] = sin_theta*cosf(phi); + r[1] = sin_theta*sinf(phi); + r[2] = cosf(theta); +} + static void studiolight_calculate_directional_diffuse_light(ImBuf *ibuf, float color[4], const float start[3], const float v1[3], const float v2[3]) { const int steps = STUDIO_LIGHT_DIFFUSE_SAMPLE_STEP; @@ -125,18 +137,18 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl) copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f); copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f); - if (sl->flag &= STUDIOLIGHT_EXTERNAL_FILE) { + if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { ImBuf* ibuf = NULL; ibuf = IMB_loadiffname(sl->path, 0, NULL); if (ibuf) { IMB_float_from_rect(ibuf); - + /* XXX: should calculate the same, only rendering should be different */ copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); copy_v3_fl3(v1, 0.0f, 2.0f, 0.0f); copy_v3_fl3(v2, 0.0f, 0.0f, 2.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_NEG], start, v1, v2); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_POS], start, v1, v2); copy_v3_fl3(start, 1.0f, -1.0f, -1.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_POS], start, v1, v2); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_NEG], start, v1, v2); copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); copy_v3_fl3(v1, 2.0f, 0.0f, 0.0f); @@ -145,19 +157,53 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl) copy_v3_fl3(start, -1.0f, 1.0f, -1.0f); studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_X_NEG], start, v1, v2); - copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); + copy_v3_fl3(start, -1.0f, -1.0f, 1.0f); copy_v3_fl3(v1, 2.0f, 0.0f, 0.0f); copy_v3_fl3(v2, 0.0f, 2.0f, 0.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_NEG], start, v1, v2); - copy_v3_fl3(start, -1.0f, -1.0f, 1.0f); - studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Y_POS], start, v1, v2); - + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_POS], start, v1, v2); + copy_v3_fl3(start, -1.0f, -1.0f, -1.0f); + studiolight_calculate_directional_diffuse_light(ibuf, sl->diffuse_light[STUDIOLIGHT_Z_NEG], start, v1, v2); IMB_freeImBuf(ibuf); } } sl->flag |= STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED; } +static void studiolight_calculate_light_direction(StudioLight *sl) +{ + float best_light = 0.0; + sl->light_direction[0] = 0.0f; + sl->light_direction[1] = 0.0f; + sl->light_direction[2] = -1.0f; + + if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) && (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) { + ImBuf* ibuf = NULL; + ibuf = IMB_loadiffname(sl->path, 0, NULL); + if (ibuf) { + IMB_float_from_rect(ibuf); + /* go over every pixel, determine light, if higher calc direction off the light */ + float col[4]; + float direction[3]; + float new_light; + for (int y = 0; y < ibuf->y; y ++) { + for (int x = 0; x < ibuf->x; x ++) { + nearest_interpolation_color_wrap(ibuf, NULL, col, x, y); + new_light = col[0] + col[1] + col[2]; + if (new_light > best_light) { + equirectangular_to_direction(direction, x, y); + sl->light_direction[0] = direction[1]; + sl->light_direction[1] = direction[2]; + sl->light_direction[2] = direction[0]; + best_light = new_light; + } + } + } + IMB_freeImBuf(ibuf); + } + } + sl->flag |= STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED; +} + static void studiolight_add_files_from_datafolder(const int folder_id, const char* subfolder, int flag) { StudioLight *sl; @@ -185,6 +231,34 @@ static void studiolight_add_files_from_datafolder(const int folder_id, const cha } +static int studiolight_flag_cmp_order(const StudioLight *sl) +{ + /* Internal studiolights before external studio lights */ + if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { + return 1; + } + return 0; +} + +static int studiolight_cmp(const void *a, const void *b) +{ + const StudioLight *sl1 = a; + const StudioLight *sl2 = b; + + const int flagorder1 = studiolight_flag_cmp_order(sl1); + const int flagorder2 = studiolight_flag_cmp_order(sl2); + + if (flagorder1 < flagorder2){ + return -1; + } + else if (flagorder1 > flagorder2) + { + return 1; + } + else { + return BLI_strcasecmp(sl1->name, sl2->name); + } +} /* API */ void BKE_studiolight_init(void) { @@ -194,18 +268,23 @@ void BKE_studiolight_init(void) /* Also reserve icon space for it. */ /* Add default studio light */ sl = studiolight_create(); - BLI_strncpy(sl->name, "INTERNAL_01\0", FILE_MAXFILE); - sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED; + BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE); + sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA; copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f); copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 0.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 1.0f); copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_NEG], 0.0f); - copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 1.0f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f); copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f); BLI_addtail(&studiolights, sl); - studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIO_LIGHT_FOLDER, 0); - studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIO_LIGHT_FOLDER, 0); + studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIO_LIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); + studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIO_LIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); + studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIO_LIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); + studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIO_LIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); + + /* sort studio lights on filename. */ + BLI_listbase_sort(&studiolights, studiolight_cmp); } void BKE_studiolight_free(void) @@ -281,9 +360,9 @@ unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size) float color[3]; mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0)); interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[1], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_NEG], clamp_f(-normal[1], 0.0, 1.0)); - interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[2], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0)); + interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0)); pixelresult = rgb_to_cpack( linearrgb_to_srgb(color[0]), @@ -298,11 +377,14 @@ unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size) void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) { - if (sl->flag & flag){ + if ((sl->flag & flag) == flag){ return; } if ((flag & STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED)) { studiolight_calculate_diffuse_light(sl); } + if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) { + studiolight_calculate_light_direction(sl); + } } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index fc5c085999c..17477e56b40 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -9,6 +9,7 @@ uniform vec3 objectOverlapColor = vec3(0.0); uniform float shadowMultiplier; uniform float lightMultiplier; uniform float shadowShift = 0.1; +uniform mat3 normalWorldMatrix; uniform vec3 lightDirection; /* light direction in view space */ @@ -57,7 +58,13 @@ void main() #ifdef V3D_LIGHTING_STUDIO - vec3 diffuse_light = get_world_diffuse_light(world_data, normal_viewport); +#ifdef STUDIOLIGHT_ORIENTATION_CAMERA + vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport); +#endif +#ifdef STUDIOLIGHT_ORIENTATION_WORLD + vec3 normal_world = normalWorldMatrix * normal_viewport; + vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); +#endif vec3 shaded_color = diffuse_light * diffuse_color.rgb; #else /* V3D_LIGHTING_STUDIO */ 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 b6b13a117c5..6507f1ec707 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 @@ -2,8 +2,19 @@ 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)); + 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; } + +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.xyz; +} diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 743f21eda30..a9c2941eb22 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -64,6 +64,7 @@ static struct { SceneDisplay display; /* world light direction for shadows */ float light_direction_vs[3]; int next_object_id; + float normal_world_matrix[3][3]; } e_data = {{NULL}}; /* Shaders */ @@ -86,7 +87,7 @@ extern DrawEngineType draw_engine_workbench_solid; #define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || wpd->shading.flag & V3D_SHADING_SHADOW) #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) #define NORMAL_ENCODING_ENABLED() (true) -//(!SHADOW_ENABLED(wpd)) +#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD) static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype) @@ -99,10 +100,18 @@ static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype) BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n"); } if (wpd->shading.flag & V3D_SHADING_SHADOW) { - BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n"); + if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n"); + } } if (wpd->shading.light & V3D_LIGHTING_STUDIO) { BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n"); + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n"); + } + else { + BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n"); + } } if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) { BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n"); @@ -168,10 +177,13 @@ static int get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype) const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW; int index = (wpd->shading.flag & DRAWOPTIONS_MASK); index = (index << 2) + wpd->shading.light; + index = (index << 2); /* set the drawtype flag - 0 = OB_SOLID, - 1 = OB_TEXTURE */ - index = index << 1; + 0 = OB_SOLID, + 1 = OB_TEXTURE + 2 = STUDIOLIGHT_ORIENTATION_WORLD + */ + SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 2); SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1); return index; } @@ -368,6 +380,17 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG } DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); + + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + float view_matrix_inverse[4][4]; + float rot_matrix[4][4]; + float matrix[4][4]; + axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z); + DRW_viewport_matrix_get(view_matrix_inverse, DRW_MAT_VIEWINV); + mul_m4_m4m4(matrix, rot_matrix, view_matrix_inverse); + copy_m3_m4(e_data.normal_world_matrix, matrix); + DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", e_data.normal_world_matrix); + } } void workbench_materials_cache_init(WORKBENCH_Data *vedata) @@ -386,17 +409,24 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata) select_deferred_shaders(wpd); /* Deferred Mix Pass */ { - wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL); DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data); - copy_v3_v3(e_data.display.light_direction, scene->display.light_direction); - negate_v3(e_data.display.light_direction); - e_data.display.shadow_shift = scene->display.shadow_shift; + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED); + float rot_matrix[3][3]; + // float dir[3] = {0.57, 0.57, -0.57}; + 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 { + copy_v3_v3(e_data.display.light_direction, scene->display.light_direction); + negate_v3(e_data.display.light_direction); + } float view_matrix[4][4]; DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); mul_v3_mat3_m4v3(e_data.light_direction_vs, view_matrix, e_data.display.light_direction); - + e_data.display.shadow_shift = scene->display.shadow_shift; if (SHADOW_ENABLED(wpd)) { diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 5c54da89f53..0df741df031 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -143,6 +143,9 @@ typedef struct View3DShading { float shadow_intensity; float single_color[3]; + + float studiolight_rot_z; + float pad2; } View3DShading; /* 3D Viewport Overlay setings */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ba77c94085e..f62d6c61fff 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -37,6 +37,8 @@ #include "BKE_node.h" #include "BKE_studiolight.h" +#include "BLI_math.h" + #include "DNA_action_types.h" #include "DNA_key_types.h" #include "DNA_material_types.h" @@ -181,29 +183,39 @@ const EnumPropertyItem rna_enum_viewport_lighting_items[] = { }; static const EnumPropertyItem rna_enum_studio_light_items[] = { - {0, "STUDIOLIGHT_01", 0, "", ""}, - {1, "STUDIOLIGHT_02", 0, "", ""}, - {2, "STUDIOLIGHT_03", 0, "", ""}, - {3, "STUDIOLIGHT_04", 0, "", ""}, - {4, "STUDIOLIGHT_05", 0, "", ""}, - {5, "STUDIOLIGHT_06", 0, "", ""}, - {6, "STUDIOLIGHT_07", 0, "", ""}, - {7, "STUDIOLIGHT_08", 0, "", ""}, - {8, "STUDIOLIGHT_09", 0, "", ""}, - {9, "STUDIOLIGHT_10", 0, "", ""}, - {10, "STUDIOLIGHT_11", 0, "", ""}, - {11, "STUDIOLIGHT_12", 0, "", ""}, - {12, "STUDIOLIGHT_13", 0, "", ""}, - {13, "STUDIOLIGHT_14", 0, "", ""}, - {14, "STUDIOLIGHT_15", 0, "", ""}, - {15, "STUDIOLIGHT_16", 0, "", ""}, - {16, "STUDIOLIGHT_17", 0, "", ""}, - {17, "STUDIOLIGHT_18", 0, "", ""}, - {18, "STUDIOLIGHT_19", 0, "", ""}, - {19, "STUDIOLIGHT_20", 0, "", ""}, + {0, "STUDIOLIGHT_00", 0, "", ""}, + {1, "STUDIOLIGHT_01", 0, "", ""}, + {2, "STUDIOLIGHT_02", 0, "", ""}, + {3, "STUDIOLIGHT_03", 0, "", ""}, + {4, "STUDIOLIGHT_04", 0, "", ""}, + {5, "STUDIOLIGHT_05", 0, "", ""}, + {6, "STUDIOLIGHT_06", 0, "", ""}, + {7, "STUDIOLIGHT_07", 0, "", ""}, + {8, "STUDIOLIGHT_08", 0, "", ""}, + {9, "STUDIOLIGHT_09", 0, "", ""}, + {10, "STUDIOLIGHT_10", 0, "", ""}, + {11, "STUDIOLIGHT_11", 0, "", ""}, + {12, "STUDIOLIGHT_12", 0, "", ""}, + {13, "STUDIOLIGHT_13", 0, "", ""}, + {14, "STUDIOLIGHT_14", 0, "", ""}, + {15, "STUDIOLIGHT_15", 0, "", ""}, + {16, "STUDIOLIGHT_16", 0, "", ""}, + {17, "STUDIOLIGHT_17", 0, "", ""}, + {18, "STUDIOLIGHT_18", 0, "", ""}, + {19, "STUDIOLIGHT_19", 0, "", ""}, + {20, "STUDIOLIGHT_20", 0, "", ""}, + {21, "STUDIOLIGHT_21", 0, "", ""}, + {22, "STUDIOLIGHT_22", 0, "", ""}, + {23, "STUDIOLIGHT_23", 0, "", ""}, + {24, "STUDIOLIGHT_24", 0, "", ""}, + {25, "STUDIOLIGHT_25", 0, "", ""}, + {26, "STUDIOLIGHT_26", 0, "", ""}, + {27, "STUDIOLIGHT_27", 0, "", ""}, + {28, "STUDIOLIGHT_28", 0, "", ""}, + {29, "STUDIOLIGHT_29", 0, "", ""}, {0, NULL, 0, NULL, NULL} }; -#define NUM_STUDIO_LIGHT_ITEMS 20 +#define NUM_STUDIO_LIGHT_ITEMS 30 const EnumPropertyItem rna_enum_clip_editor_mode_items[] = { {SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"}, @@ -693,9 +705,18 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf( return item; } +static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)ptr->data; + StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light); + return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD|STUDIOLIGHT_ORIENTATION_CAMERA); +} +static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value)) +{ +} + static int rna_View3DShading_studio_light_get(PointerRNA *ptr) { - /* XXX: should be stored as string */ View3D *v3d = (View3D *)ptr->data; StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light); return sl->index; @@ -703,7 +724,6 @@ static int rna_View3DShading_studio_light_get(PointerRNA *ptr) static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value) { - /* XXX: should be stored as string */ View3D *v3d = (View3D *)ptr->data; StudioLight *sl = BKE_studiolight_findindex(value); BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE); @@ -721,6 +741,7 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( if (totitem < NUM_STUDIO_LIGHT_ITEMS) { RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, totitem); lastitem = &item[totitem-1]; + lastitem->value = sl->index; lastitem->icon = sl->icon_id; lastitem->name = sl->name; } @@ -2183,6 +2204,13 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static const EnumPropertyItem studio_light_orientation_items[] = { + {0, "UNKNOWN", 0, "Unknown", "Studio light has no orientation"}, + {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", "Studio light is camera based"}, + {STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", "Studio light is world based"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "View3DShading", NULL); RNA_def_struct_sdna(srna, "View3D"); RNA_def_struct_nested(brna, srna, "SpaceView3D"); @@ -2216,6 +2244,23 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Studiolight", "Studio lighting setup"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "studio_light_orientation", PROP_ENUM, PROP_NONE); + RNA_define_verify_sdna(0); + RNA_def_property_enum_sdna(prop, NULL, "shading.flag"); + RNA_def_property_ui_text(prop, "Studio Light Orientation", "Orientation of the studio light"); + RNA_def_property_enum_items(prop, studio_light_orientation_items); + RNA_def_property_enum_funcs(prop, "rna_View3DShading_studio_light_orientation_get", "rna_View3DShading_studio_light_orientation_set", NULL); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_define_verify_sdna(1); + + prop = RNA_def_property(srna, "studiolight_rot_z", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "shading.studiolight_rot_z"); + RNA_def_property_float_default(prop, 0.0); + RNA_def_property_ui_text(prop, "Studiolight Rotation", "Rotation of the studiolight around the Z-Axis"); + RNA_def_property_range(prop, -M_PI, M_PI); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "color_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "shading.color_type"); RNA_def_property_enum_items(prop, color_type_items);