Workbench: Cleaner Shadow edges own shadow
authorJeroen Bakker <j.bakker@atmind.nl>
Tue, 15 May 2018 13:19:57 +0000 (15:19 +0200)
committerJeroen Bakker <j.bakker@atmind.nl>
Tue, 15 May 2018 13:40:12 +0000 (15:40 +0200)
13 files changed:
release/scripts/startup/bl_ui/properties_scene.py
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/versioning_280.c
source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
source/blender/draw/engines/workbench/workbench_materials.c
source/blender/draw/engines/workbench/workbench_private.h
source/blender/draw/engines/workbench/workbench_studiolight.c
source/blender/gpu/intern/gpu_texture.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index cf17adfe5c1519e2e1613b6de84caedd728e0a75..545d0d696dc287d456a684888160d045962f6ed1 100644 (file)
@@ -441,6 +441,7 @@ class SCENE_PT_viewport_display(SceneButtonsPanel, Panel):
         layout = self.layout
         scene = context.scene
         layout.prop(scene.display, "light_direction", text="")
+        layout.prop(scene.display, "shadow_shift")
 
 
 class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
index f95da4f723f8cd6aec3593fa9e0684ce83c19277..5fde2db0d15c8f810740618ff57728bae7345a1a 100644 (file)
@@ -824,6 +824,7 @@ void BKE_scene_init(Scene *sce)
 
        /* 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;
 }
 
 Scene *BKE_scene_add(Main *bmain, const char *name)
index 08cb81bb35708c8d904e461306556b5f196e750f..2af10d3faf6b122f5fdaf9d7b1bed87a7a43cded 100644 (file)
@@ -1085,6 +1085,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
                                copy_v3_v3(scene->display.light_direction, (float[3]){-M_SQRT1_3, -M_SQRT1_3, M_SQRT1_3});
                        }
                }
+               if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "float", "shadow_shift")) {
+                       for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+                               scene->display.shadow_shift = 0.1;
+                       }
+               }
 
                if (!DNA_struct_elem_find(fd->filesdna, "Object", "ObjectDisplay", "display")) {
                        /* Initialize new object.ObjectDisplay */
index 7f7e8f9c69ccbdb85fdf069b14d4f949a750051e..09bdffe3299f19e78f455dca6bbae1a0af7fa64a 100644 (file)
@@ -7,6 +7,10 @@ uniform sampler2D normalBuffer;
 uniform vec2 invertedViewportSize;
 uniform vec3 objectOverlapColor = vec3(0.0);
 uniform float shadowMultiplier;
+uniform float lightMultiplier;
+uniform float shadowShift = 0.1;
+
+uniform vec3 lightDirection; /* light direction in view space */
 
 layout(std140) uniform world_block {
        WorldData world_data;
@@ -38,29 +42,42 @@ void main()
        }
 #endif /* !V3D_SHADING_OBJECT_OVERLAP */
 
-
-#ifdef V3D_LIGHTING_STUDIO
        vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
+/* Do we need normals */
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
 #ifdef WORKBENCH_ENCODE_NORMALS
        vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
        if (diffuse_color.a == 1.0) {
-               normal_viewport = - normal_viewport;
+               normal_viewport = -normal_viewport;
        }
 #else /* WORKBENCH_ENCODE_NORMALS */
        vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
 #endif /* WORKBENCH_ENCODE_NORMALS */
+#endif
+
+
+#ifdef V3D_LIGHTING_STUDIO
        vec3 diffuse_light = get_world_diffuse_light(world_data, normal_viewport);
-       vec3 shaded_color = diffuse_light * diffuse_color.rgb * (1.0 - shadowMultiplier);
+       vec3 shaded_color = diffuse_light * diffuse_color.rgb;
 
 #else /* V3D_LIGHTING_STUDIO */
-       vec3 diffuse_color = texelFetch(colorBuffer, texel, 0).rgb;
-       vec3 shaded_color = diffuse_color * (1.0 - shadowMultiplier);
+       vec3 shaded_color = diffuse_color.rgb;
+
 #endif /* V3D_LIGHTING_STUDIO */
 
+#ifdef V3D_SHADING_SHADOW
+       float shadow_mix = step(-shadowShift, dot(normal_viewport, lightDirection));
+       float light_multiplier;
+       light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix);
+
+#else /* V3D_SHADING_SHADOW */
+       float light_multiplier = 1.0;
+#endif /* V3D_SHADING_SHADOW */
+
+       shaded_color *= light_multiplier;
 
 #ifdef V3D_SHADING_OBJECT_OVERLAP
        shaded_color = mix(objectOverlapColor, shaded_color, object_overlap);
 #endif /* V3D_SHADING_OBJECT_OVERLAP */
-
        fragColor = vec4(shaded_color, 1.0);
 }
index 54c5bce42718d088c52b37b96f02faa413f6f02c..2cc0ff3723d36ac75c4a4ccce99edca5ed842238 100644 (file)
@@ -4,22 +4,22 @@ uniform vec3 object_color = vec3(1.0, 0.0, 1.0);
 uniform sampler2D image;
 #endif
 
-#ifdef V3D_LIGHTING_STUDIO
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
 in vec3 normal_viewport;
-#endif /* V3D_LIGHTING_STUDIO */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 #ifdef OB_TEXTURE
 in vec2 uv_interp;
 #endif /* OB_TEXTURE */
 
 layout(location=0) out uint objectId;
 layout(location=1) out vec4 diffuseColor;
-#ifdef V3D_LIGHTING_STUDIO
-#ifdef WORKBENCH_ENCODE_NORMALS
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
+       #ifdef WORKBENCH_ENCODE_NORMALS
 layout(location=2) out vec2 normalViewport;
-#else /* WORKBENCH_ENCODE_NORMALS */
+       #else /* WORKBENCH_ENCODE_NORMALS */
 layout(location=2) out vec3 normalViewport;
-#endif /* WORKBENCH_ENCODE_NORMALS */
-#endif /* V3D_LIGHTING_STUDIO */
+       #endif /* WORKBENCH_ENCODE_NORMALS */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 
 void main()
 {
@@ -31,18 +31,18 @@ void main()
        diffuseColor = texture(image, uv_interp);
 #endif /* OB_TEXTURE */
 
-#ifdef V3D_LIGHTING_STUDIO
-#ifdef WORKBENCH_ENCODE_NORMALS
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
+       #ifdef WORKBENCH_ENCODE_NORMALS
        if (!gl_FrontFacing) {
-               normalViewport = normal_encode(-normal_viewport);
+               normalViewport = normal_encode(normalize(-normal_viewport));
                diffuseColor.a = 1.0;
        }
        else {
-               normalViewport = normal_encode(normal_viewport);
+               normalViewport = normal_encode(normalize(normal_viewport));
                diffuseColor.a = 0.0;
        }
-#else /* WORKBENCH_ENCODE_NORMALS */
+       #else /* WORKBENCH_ENCODE_NORMALS */
        normalViewport = normal_viewport;
-#endif /* WORKBENCH_ENCODE_NORMALS */
-#endif /* V3D_LIGHTING_STUDIO */
+       #endif /* WORKBENCH_ENCODE_NORMALS */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 }
index 22b16bf1d6a6d2dbd927849063ecfeed7025cf46..f2df117d897a8a63e7c6dd88bb56f0d4d774504c 100644 (file)
@@ -1,19 +1,19 @@
 uniform mat4 ModelViewProjectionMatrix;
-#ifdef V3D_LIGHTING_STUDIO
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
 uniform mat3 NormalMatrix;
-#endif /* V3D_LIGHTING_STUDIO */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 
 in vec3 pos;
-#ifdef V3D_LIGHTING_STUDIO
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
 in vec3 nor;
-#endif /* V3D_LIGHTING_STUDIO */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 #ifdef OB_TEXTURE
 in vec2 uv;
 #endif
 
-#ifdef V3D_LIGHTING_STUDIO
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
 out vec3 normal_viewport;
-#endif /* V3D_LIGHTING_STUDIO */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 #ifdef OB_TEXTURE
 out vec2 uv_interp;
 #endif
@@ -23,8 +23,8 @@ void main()
 #ifdef OB_TEXTURE
        uv_interp = uv;
 #endif
-#ifdef V3D_LIGHTING_STUDIO
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
        normal_viewport = normalize(NormalMatrix * nor);
-#endif /* V3D_LIGHTING_STUDIO */
+#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
        gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
 }
index 7322266a9560cbd5a3759aa2c03fb9c9241c4de6..8ef1a8b589b0581e8596b851ed9885cf67f35b0b 100644 (file)
@@ -1,4 +1,4 @@
-#define EPSILON 0.000001
+#define EPSILON 0.0001
 #define INFINITE 100.0
 
 uniform mat4 ModelMatrixInverse;
index f4b9a0a3e536dd2088e6f75ed30f649e6254d798..0f21b76b4d264ec582544df29fcef006cc76831d 100644 (file)
@@ -61,7 +61,8 @@ static struct {
        struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
        struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
 
-       float light_direction[3]; /* world light direction for shadows */
+       SceneDisplay display; /* world light direction for shadows */
+       float light_direction_vs[3];
        int next_object_id;
 } e_data = {{NULL}};
 
@@ -82,8 +83,12 @@ extern char datatoc_workbench_world_light_lib_glsl[];
 extern DrawEngineType draw_engine_workbench_solid;
 
 #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OVERLAP)
-#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO)
+#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))
+
+
 static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
 {
        char *str = NULL;
@@ -93,9 +98,15 @@ static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
        if (wpd->shading.flag & V3D_SHADING_OBJECT_OVERLAP) {
                BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OVERLAP\n");
        }
+       if (wpd->shading.flag & V3D_SHADING_SHADOW) {
+               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 (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
+       }
        switch (drawtype) {
                case OB_SOLID:
                        BLI_dynstr_appendf(ds, "#define OB_SOLID\n");
@@ -105,9 +116,9 @@ static char *workbench_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
                        break;
        }
 
-#ifdef WORKBENCH_ENCODE_NORMALS
-       BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
-#endif
+       if (NORMAL_ENCODING_ENABLED()) {
+               BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
+       }
 
        str = BLI_dynstr_get_cstring(ds);
        BLI_dynstr_free(ds);
@@ -154,7 +165,7 @@ static char *workbench_build_prepass_frag(void)
 
 static int get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype)
 {
-       const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OVERLAP;
+       const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OVERLAP | V3D_SHADING_SHADOW;
        int index = (wpd->shading.flag & DRAWOPTIONS_MASK);
        index = (index << 2) + wpd->shading.light;
        /* set the drawtype flag
@@ -251,7 +262,41 @@ static void get_material_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, Mat
                }
        }
 }
+static void workbench_private_data_init(WORKBENCH_Data *vedata)
+{
+       WORKBENCH_StorageList *stl = vedata->stl;
+       WORKBENCH_PrivateData *wpd = stl->g_data;
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+
+       View3D *v3d = draw_ctx->v3d;
+       if (v3d) {
+               wpd->shading = v3d->shading;
+               wpd->drawtype = v3d->drawtype;
+               wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light);
+       }
+       else {
+               /* XXX: We should get the default shading from the view layer, after we implemented the render callback */
+               memset(&wpd->shading, 0, sizeof(wpd->shading));
+               wpd->shading.light = V3D_LIGHTING_STUDIO;
+               wpd->shading.shadow_intensity = 0.5;
+               copy_v3_fl(wpd->shading.single_color, 0.8f);
+               wpd->drawtype = OB_SOLID;
+               wpd->studio_light = BKE_studiolight_findindex(0);
+       }
+       wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
 
+       WORKBENCH_UBO_World *wd = &wpd->world_data;
+       UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low);
+       UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
+
+       /* XXX: Really quick conversion to avoid washed out background.
+        * Needs to be adressed properly (color managed using ocio). */
+       srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
+       srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
+
+       studiolight_update_world(wpd->studio_light, wd);
+
+}
 void workbench_materials_engine_init(WORKBENCH_Data *vedata)
 {
        WORKBENCH_FramebufferList *fbl = vedata->fbl;
@@ -271,17 +316,20 @@ void workbench_materials_engine_init(WORKBENCH_Data *vedata)
                stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
        }
 
+       workbench_private_data_init(vedata);
+
        {
                const float *viewport_size = DRW_viewport_size_get();
                const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
                e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid);
                e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
                e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
-#ifdef WORKBENCH_ENCODE_NORMALS
-               e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG8, &draw_engine_workbench_solid);
-#else
-               e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, &draw_engine_workbench_solid);
-#endif
+
+               if (NORMAL_ENCODING_ENABLED()) {
+                       e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
+               } else {
+                       e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, &draw_engine_workbench_solid);
+               }
 
                GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
                        GPU_ATTACHMENT_TEXTURE(dtxl->depth),
@@ -329,66 +377,49 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
        WORKBENCH_PrivateData *wpd = stl->g_data;
        DRWShadingGroup *grp;
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       static float shadow_multiplier = 0.0f;
+       static float light_multiplier = 1.0f;
 
        wpd->material_hash = BLI_ghash_ptr_new(__func__);
 
-       View3D *v3d = draw_ctx->v3d;
        Scene *scene = draw_ctx->scene;
-       if (v3d) {
-               wpd->shading = v3d->shading;
-               wpd->drawtype = v3d->drawtype;
-               wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light);
-       }
-       else {
-               /* XXX: We should get the default shading from the view layer, after we implemented the render callback */
-               memset(&wpd->shading, 0, sizeof(wpd->shading));
-               wpd->shading.light = V3D_LIGHTING_STUDIO;
-               wpd->shading.shadow_intensity = 0.5;
-               copy_v3_fl(wpd->shading.single_color, 0.8f);
-               wpd->drawtype = OB_SOLID;
-               wpd->studio_light = BKE_studiolight_findindex(0);
-       }
-       BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
 
        select_deferred_shaders(wpd);
        /* Deferred Mix Pass */
        {
-               WORKBENCH_UBO_World *wd = &wpd->world_data;
-               UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low);
-               UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
-
-               /* XXX: Really quick conversion to avoid washed out background.
-                * Needs to be adressed properly (color managed using ocio). */
-               srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
-               srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
-
-               studiolight_update_world(wpd->studio_light, wd);
 
                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.light_direction, scene->display.light_direction);
-               negate_v3(e_data.light_direction);
+               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;
+               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)) {
                        psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
                        grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
                        workbench_composite_uniforms(wpd, grp);
                        DRW_shgroup_stencil_mask(grp, 0x00);
-                       DRW_shgroup_uniform_float(grp, "shadowMultiplier", &shadow_multiplier, 1);
+                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction_vs, 1);
+                       DRW_shgroup_uniform_float(grp, "lightMultiplier", &light_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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 
 #ifdef DEBUG_SHADOW_VOLUME
                        psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK | DRW_STATE_WRITE_COLOR);
                        grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
-                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
+                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.display.light_direction, 1);
                        DRW_shgroup_stencil_mask(grp, 0xFF);
                        wpd->shadow_shgrp = grp;
 #else
                        psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL_SHADOW);
                        grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
-                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
+                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.display.light_direction, 1);
                        DRW_shgroup_stencil_mask(grp, 0xFF);
                        wpd->shadow_shgrp = grp;
 
@@ -396,7 +427,10 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
                        grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
                        DRW_shgroup_stencil_mask(grp, 0x00);
                        workbench_composite_uniforms(wpd, grp);
-                       DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shading.shadow_intensity, 1);
+                       DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction_vs, 1);
+                       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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 #endif
                }
@@ -404,7 +438,6 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
                        psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
                        grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
                        workbench_composite_uniforms(wpd, grp);
-                       DRW_shgroup_uniform_float(grp, "shadowMultiplier", &shadow_multiplier, 1);
                        DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
                }
        }
index dde62302f62b756ebe1bcc9ad342be4f03d50034..7b0aa157e07fe60106a045420eb3b5d8663a7ed7 100644 (file)
@@ -37,7 +37,6 @@
 
 #define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
 #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
-#define WORKBENCH_ENCODE_NORMALS
 
 
 typedef struct WORKBENCH_FramebufferList {
@@ -88,6 +87,7 @@ typedef struct WORKBENCH_PrivateData {
        struct GPUUniformBuffer *world_ubo;
        struct DRWShadingGroup *shadow_shgrp;
        WORKBENCH_UBO_World world_data;
+       float shadow_multiplier;
 } WORKBENCH_PrivateData; /* Transient data */
 
 typedef struct WORKBENCH_MaterialData {
index f7d107ea4032eefcfb1a120477342f36ee8aa574..2142be3eaf44300801dabbef1d15cde03ab7fc8f 100644 (file)
@@ -31,6 +31,8 @@
 
 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]);
index 3961278ad1ada59083921ddd97913d86fc507777..5c8edfb2a33d54731d82ecc755243438cfafe433 100644 (file)
@@ -149,8 +149,8 @@ static GLenum gpu_texture_get_format(
        }
        else {
                /* Integer formats */
-               if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_R16UI, GPU_R32UI)) {
-                       if (ELEM(data_type, GPU_R16UI, GPU_R32UI)) {
+               if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
+                       if (ELEM(data_type, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
                                *data_format = GL_UNSIGNED_INT;
                        }
                        else {
@@ -194,6 +194,7 @@ static GLenum gpu_texture_get_format(
                        break;
                case GPU_RG16F:
                case GPU_RG16I:
+               case GPU_RG16UI:
                case GPU_RG16:
                case GPU_DEPTH24_STENCIL8:
                case GPU_DEPTH_COMPONENT32F:
@@ -238,6 +239,7 @@ static GLenum gpu_texture_get_format(
                case GPU_R16I: return GL_R16I;
                case GPU_R16UI: return GL_R16UI;
                case GPU_RG8: return GL_RG8;
+               case GPU_RG16UI: return GL_RG16UI;
                case GPU_R8: return GL_R8;
                /* Special formats texture & renderbuffer */
                case GPU_R11F_G11F_B10F: return GL_R11F_G11F_B10F;
@@ -270,6 +272,7 @@ static int gpu_texture_get_component_count(GPUTextureFormat format)
                case GPU_RG16:
                case GPU_RG16F:
                case GPU_RG16I:
+               case GPU_RG16UI:
                case GPU_RG32F:
                        return 2;
                default:
index c14ab28ad62e982fc7482f88102b659858992780..03cab034ec1d94b5515ffe9ca40441986c6b0bcb 100644 (file)
@@ -1360,7 +1360,7 @@ 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 */
-       int pad;
+       float shadow_shift;
 } SceneDisplay;
 
 /* *************************************************************** */
index b487a08dccd05b745a7a5346f9e96412437c3f5c..4c43fb50248ff4670737800db6d4b7be04151dd2 100644 (file)
@@ -5687,6 +5687,16 @@ static void rna_def_scene_display(BlenderRNA *brna)
        RNA_def_property_float_array_default(prop, default_light_direction);
        RNA_def_property_ui_text(prop, "Light Direction", "Direction of the light for shadows and highlights");
        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);
+       RNA_def_property_ui_range(prop, 0.00f, 1.0f, 1, 2);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
 }
 
 void RNA_def_scene(BlenderRNA *brna)