Workbench: Add Shadow Focus and change Shadow Orientation
authorClément Foucault <foucault.clem@gmail.com>
Fri, 30 Nov 2018 12:26:30 +0000 (13:26 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Fri, 30 Nov 2018 14:40:57 +0000 (15:40 +0100)
Shadow focus let the user choose how hard are is the shadows transition.
Harder shadow transition can be used for stylistic effects or more uniform
shading.

Make shadow orientation respect the same orientation as the studio light
(view from +Y direction aka. front view). Make the default shadow direction
more similar to the default light position (the default light object, not
the default studio lighting).

release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/versioning_280.c
source/blender/blenloader/intern/versioning_defaults.c
source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
source/blender/draw/engines/workbench/workbench_data.c
source/blender/draw/engines/workbench/workbench_deferred.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index 4f8d2ae34aacec4f618dfa7a12e9cbf192aa7838..4900ed6e63109f34fd4adceefc1ff9c94115d69e 100644 (file)
@@ -4402,6 +4402,7 @@ class VIEW3D_PT_shading_options_shadow(Panel):
         col = layout.column()
         col.prop(scene.display, "light_direction")
         col.prop(scene.display, "shadow_shift")
+        col.prop(scene.display, "shadow_focus")
 
 
 class VIEW3D_PT_shading_options_ssao(Panel):
index 090c016ed00e693535cd0c4a0b9767548718d4a9..7a6f1ec85b4b8ec78dcd74fff44a8f0a90a1c3c5 100644 (file)
@@ -858,8 +858,9 @@ void BKE_scene_init(Scene *sce)
        BKE_view_layer_add(sce, "View Layer");
 
        /* SceneDisplay */
-       copy_v3_v3(sce->display.light_direction, (float[3]){-M_SQRT1_3, -M_SQRT1_3, M_SQRT1_3});
-       sce->display.shadow_shift = 0.1;
+       copy_v3_v3(sce->display.light_direction, (float[3]){M_SQRT1_3, M_SQRT1_3, M_SQRT1_3});
+       sce->display.shadow_shift = 0.1f;
+       sce->display.shadow_focus = 0.0f;
 
        sce->display.matcap_ssao_distance = 0.2f;
        sce->display.matcap_ssao_attenuation = 1.0f;
index 434153fc7b9af485117bebe20e479f3697b8cc8b..17859d257d0f3d76a8fe35ea2a75b871b32ad350 100644 (file)
@@ -2480,5 +2480,15 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
                                }
                        }
                }
+
+               /* Change Solid mode shadow orientation. */
+               if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "float", "shadow_focus")) {
+                       for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+                               float *dir = scene->display.light_direction;
+                               SWAP(float, dir[2], dir[1]);
+                               dir[2] = -dir[2];
+                               dir[0] = -dir[0];
+                       }
+               }
        }
 }
index b88618bf7db1926f20fa0486782cea8b490216af..25946a9fb31d5a9cc2893445c4bcf8c044d5443f 100644 (file)
@@ -301,4 +301,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
                        }
                }
        }
+
+       for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+               copy_v3_v3(scene->display.light_direction, (float[3]){M_SQRT1_3, M_SQRT1_3, M_SQRT1_3});
+       }
 }
index 310169bdf5dcf4d2d59bd15e41e7761ab74d90f3..e383d1b19390c1a2b6bad28550702a7a3a559d39 100644 (file)
@@ -16,6 +16,7 @@ uniform vec4 viewvecs[3];
 uniform float shadowMultiplier;
 uniform float lightMultiplier;
 uniform float shadowShift = 0.1;
+uniform float shadowFocus = 1.0;
 
 layout(std140) uniform world_block {
        WorldData world_data;
@@ -99,7 +100,7 @@ void main()
        float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz);
        /* The step function might be ok for meshes but it's
         * clearly not the case for hairs. Do smoothstep in this case. */
-       float shadow_mix = smoothstep(1.0, shadowShift, light_factor);
+       float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor);
        shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix);
 #endif
 
index 1cdf4c2b443fa6967853e063dca0c8c7bbd3f6e4..04e760f190919546e5caf9e2ed6e261eb96ad411 100644 (file)
@@ -161,7 +161,9 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa
        DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
 
        copy_v3_v3(r_light_direction, scene->display.light_direction);
-       negate_v3(r_light_direction);
+       SWAP(float, r_light_direction[2], r_light_direction[1]);
+       r_light_direction[2] = -r_light_direction[2];
+       r_light_direction[0] = -r_light_direction[0];
 
        /* Shadow direction. */
        mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, r_light_direction);
index 1ca76da672a18e1a3039385c853e45a0763bb2c1..a77179fa6764f781a1b1baf1ec905c8fd56239d4 100644 (file)
@@ -566,7 +566,10 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
                workbench_private_data_get_light_direction(wpd, e_data.display.light_direction);
                studiolight_update_light(wpd, e_data.display.light_direction);
 
-               e_data.display.shadow_shift = scene->display.shadow_shift;
+               float shadow_focus = scene->display.shadow_focus;
+               /* Clamp to avoid overshadowing and shading errors. */
+               CLAMP(shadow_focus, 0.0001f, 0.99999f);
+               shadow_focus = 1.0f - shadow_focus * (1.0f - scene->display.shadow_shift);
 
                if (SHADOW_ENABLED(wpd)) {
                        psl->composite_pass = DRW_pass_create(
@@ -576,7 +579,8 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
                        DRW_shgroup_stencil_mask(grp, 0x00);
                        DRW_shgroup_uniform_float_copy(grp, "lightMultiplier", 1.0f);
                        DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
-                       DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1);
+                       DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
+                       DRW_shgroup_uniform_float_copy(grp, "shadowFocus", shadow_focus);
                        DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 
                        /* Stencil Shadow passes. */
@@ -614,7 +618,8 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
                        workbench_composite_uniforms(wpd, grp);
                        DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->shadow_multiplier, 1);
                        DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
-                       DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1);
+                       DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
+                       DRW_shgroup_uniform_float_copy(grp, "shadowFocus", shadow_focus);
                        DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 #endif
 
index 6cc689378eab634f3da0809c54fc731cc1673627..1b31e45b30e54a17253d7a9fc57da05696ad9530 100644 (file)
@@ -1441,13 +1441,12 @@ typedef struct DisplaySafeAreas {
 /* Scene Display - used for store scene specific display settings for the 3d view */
 typedef struct SceneDisplay {
        float light_direction[3];      /* light direction for shadows/highlight */
-       float shadow_shift;
+       float shadow_shift, shadow_focus;
 
        /* Settings for Cavity Shader */
        float matcap_ssao_distance;
        float matcap_ssao_attenuation;
        int matcap_ssao_samples;
-       int pad;
 
        /* OpenGL render engine settings. */
        View3DShading shading;
index d6d597aac73a2a11273b13eaa1e73a7e9a73151a..3e3e08459caea4bc5be01fe6eb75df48739ec24f 100644 (file)
@@ -5591,7 +5591,6 @@ static void rna_def_scene_display(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update");
 
        prop = RNA_def_property(srna, "shadow_shift", PROP_FLOAT, PROP_ANGLE);
-       RNA_def_property_float_sdna(prop, NULL, "shadow_shift");
        RNA_def_property_float_default(prop, 0.1);
        RNA_def_property_ui_text(prop, "Shadow Shift", "Shadow termination angle");
        RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5599,6 +5598,14 @@ static void rna_def_scene_display(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update");
 
+       prop = RNA_def_property(srna, "shadow_focus", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_float_default(prop, 0.0);
+       RNA_def_property_ui_text(prop, "Shadow Focus", "Shadow factor hardness");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update");
+
        prop = RNA_def_property(srna, "matcap_ssao_distance", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_default(prop, 0.2f);
        RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the Cavity/Edge effect");