From e862bcd6c8cb218c2213ac4a05a11dd13dbdecbf Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 16 May 2018 16:42:30 +0200 Subject: Workbench: World based studio lighting Disabled shadows for now as the calculation of the light direction is still to bogus. --- release/datafiles/studiolights/camera/camera01.hdr | Bin 0 -> 55703 bytes release/datafiles/studiolights/camera/camera02.jpg | Bin 0 -> 22559 bytes release/datafiles/studiolights/sl01.jpg | Bin 7314 -> 0 bytes release/datafiles/studiolights/sl02.jpg | Bin 49661 -> 0 bytes release/datafiles/studiolights/world/sl02.jpg | Bin 0 -> 49661 bytes release/scripts/startup/bl_ui/space_view3d.py | 13 ++- source/blender/blenkernel/BKE_studiolight.h | 13 ++- source/blender/blenkernel/intern/studiolight.c | 122 +++++++++++++++++---- .../shaders/workbench_composite_frag.glsl | 9 +- .../shaders/workbench_world_light_lib.glsl | 17 ++- .../draw/engines/workbench/workbench_materials.c | 50 +++++++-- source/blender/makesdna/DNA_view3d_types.h | 3 + source/blender/makesrna/intern/rna_space.c | 91 +++++++++++---- 13 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 delete mode 100644 release/datafiles/studiolights/sl02.jpg create mode 100644 release/datafiles/studiolights/world/sl02.jpg diff --git a/release/datafiles/studiolights/camera/camera01.hdr b/release/datafiles/studiolights/camera/camera01.hdr new file mode 100644 index 00000000000..341b15524c5 Binary files /dev/null and b/release/datafiles/studiolights/camera/camera01.hdr differ diff --git a/release/datafiles/studiolights/camera/camera02.jpg b/release/datafiles/studiolights/camera/camera02.jpg new file mode 100644 index 00000000000..37be86325df Binary files /dev/null and b/release/datafiles/studiolights/camera/camera02.jpg differ diff --git a/release/datafiles/studiolights/sl01.jpg b/release/datafiles/studiolights/sl01.jpg deleted file mode 100644 index cd007bade68..00000000000 Binary files a/release/datafiles/studiolights/sl01.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/sl02.jpg b/release/datafiles/studiolights/sl02.jpg deleted file mode 100644 index 1c9ce99a0d8..00000000000 Binary files a/release/datafiles/studiolights/sl02.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/world/sl02.jpg b/release/datafiles/studiolights/world/sl02.jpg new file mode 100644 index 00000000000..1c9ce99a0d8 Binary files /dev/null and b/release/datafiles/studiolights/world/sl02.jpg differ 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); -- cgit v1.2.3