Commit: e9a60ce199200e25d2a6e9d722ad7e8de8cab206 Author: Lukas Stockner Date: Thu Oct 25 14:53:36 2018 +0200 Branches: experimental-build https://developer.blender.org/rBe9a60ce199200e25d2a6e9d722ad7e8de8cab206
Workbench: Add Curvature overlay for better visibility of surface detail for e.g. sculpting The approach is fairly simple, just apply an edge detection filter to the view normal and scale the brightness based on that. The overlay is disabled at object boundaries to avoid dark lines around objects. Generally, this implementation follows the proposal of @monio at https://blender.community/c/rightclickselect/J9bbbc. The changes are: - Radius of two pixels instead of one - might not be better, though, needs some feedback - Options to reduce the strength of both ridges and valleys - Tweaked function for the strength reduction (the original method actually had a local maximum, resulting in a brighter line inside valleys) - Multiplication for blending instead of overlay, which doesn't work reliably with scene-referred intensities - Renamed to point out the distinction between it and the SSAO-based cavity overlay Reviewers: jbakker Subscribers: linko, monio Differential Revision: https://developer.blender.org/D3617 =================================================================== M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenkernel/intern/screen.c M source/blender/blenloader/intern/versioning_280.c M source/blender/draw/CMakeLists.txt A source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl M source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl M source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl M source/blender/draw/engines/workbench/workbench_data.c M source/blender/draw/engines/workbench/workbench_deferred.c M source/blender/draw/engines/workbench/workbench_forward.c M source/blender/draw/engines/workbench/workbench_materials.c M source/blender/draw/engines/workbench/workbench_private.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c =================================================================== diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 750c8fcd6a9..a108a83e3dc 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -4182,6 +4182,17 @@ class VIEW3D_PT_shading_options(Panel): text="" ) + col = layout.column() + row = col.row() + row.active = not shading.show_xray + row.prop(shading, "show_curvature") + + if shading.show_curvature: + sub = col.row(align=True) + sub.active = not shading.show_xray and shading.show_curvature + sub.prop(shading, "curvature_ridge_factor") + sub.prop(shading, "curvature_valley_factor") + col = layout.column() row = col.row() row.active = not shading.show_xray diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 84962e9b03f..79f8efc6239 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -794,6 +794,8 @@ void BKE_screen_view3d_shading_init(View3DShading *shading) shading->xray_alpha_wire = 0.5f; shading->cavity_valley_factor = 1.0f; shading->cavity_ridge_factor = 1.0f; + shading->curvature_ridge_factor = 1.0f; + shading->curvature_valley_factor = 1.0f; copy_v3_fl(shading->single_color, 0.8f); copy_v3_fl(shading->background_color, 0.05f); } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index ab52a9b8b8f..3eb92d78a25 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -2164,5 +2164,18 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } + if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "curvature_ridge_factor")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->shading.curvature_ridge_factor = 1.0f; + v3d->shading.curvature_valley_factor = 1.0f; + } + } + } + } + } } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index be742868cd6..318276eccc7 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -230,6 +230,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_ghost_resolve_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC) +data_to_c_simple(engines/workbench/shaders/workbench_curvature_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_shadow_vert.glsl SRC) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl new file mode 100644 index 00000000000..6b693675f84 --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl @@ -0,0 +1,40 @@ +#ifndef CURVATURE_OFFSET +# define CURVATURE_OFFSET 1 +#endif + +float curvature_soft_clamp(float curvature, float control) +{ + if (curvature < 0.5 / control) + return curvature * (1.0 - curvature * control); + return 0.25 / control; +} + +float calculate_curvature(usampler2D objectId, sampler2D normalBuffer, ivec2 texel, float ridge, float valley) +{ + uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r; + uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r; + uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r; + uint object_right = texelFetchOffset(objectId, texel, 0, ivec2( CURVATURE_OFFSET, 0)).r; + + if((object_up != object_down) || (object_right != object_left)) { + return 0.0; + } + + vec2 normal_up = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, CURVATURE_OFFSET)).rg; + vec2 normal_down = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, -CURVATURE_OFFSET)).rg; + vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg; + vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg; + +#ifdef WORKBENCH_ENCODE_NORMALS + normal_up = normal_decode(normal_up ).rg; + normal_down = normal_decode(normal_down ).rg; + normal_left = normal_decode(normal_left ).rg; + normal_right = normal_decode(normal_right).rg; +#endif + + float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r)); + + if (normal_diff < 0) + return -2.0 * curvature_soft_clamp(-normal_diff, valley); + return 2.0 * curvature_soft_clamp(normal_diff, ridge); +} 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 eadc5e4b0d0..e2821c92710 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -13,5 +13,7 @@ struct WorldData { int num_lights; int matcap_orientation; float background_alpha; - int pad[1]; + float curvature_ridge; + float curvature_valley; + int pad[3]; }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl index 508aeb1f0c1..2d09002f71b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl @@ -109,6 +109,11 @@ void main() shaded_color *= 1.0 + cavity.y; #endif +#ifdef V3D_SHADING_CURVATURE + float curvature = calculate_curvature(objectId, normalBuffer, texel, world_data.curvature_ridge, world_data.curvature_valley); + shaded_color *= curvature + 1.0; +#endif + #ifdef V3D_SHADING_SHADOW float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz); /* The step function might be ok for meshes but it's diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 94beedc144b..025a87d9826 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -84,6 +84,9 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color); wd->object_outline_color[3] = 1.0f; + wd->curvature_ridge = 0.5f / max_ff(wpd->shading.curvature_ridge_factor*wpd->shading.curvature_ridge_factor, 1e-4f); + wd->curvature_valley = 0.7f / max_ff(wpd->shading.curvature_valley_factor*wpd->shading.curvature_valley_factor, 1e-4f); + wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data); /* Cavity settings */ diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index f7ab9bad5ec..96f0eb4d1bb 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -104,6 +104,7 @@ extern char datatoc_workbench_cavity_lib_glsl[]; extern char datatoc_workbench_common_lib_glsl[]; extern char datatoc_workbench_data_lib_glsl[]; extern char datatoc_workbench_object_outline_lib_glsl[]; +extern char datatoc_workbench_curvature_lib_glsl[]; extern char datatoc_workbench_world_light_lib_glsl[]; extern char datatoc_gpu_shader_depth_only_frag_glsl[]; @@ -124,6 +125,9 @@ static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd) if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) { BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl); } + if (wpd->shading.flag & V3D_SHADING_CURVATURE) { + BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl); + } BLI_dynstr_append(ds, datatoc_workbench_deferred_composite_frag_glsl); diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index bd9dbd5ae17..e9ed7c15d58 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -75,6 +75,7 @@ extern char datatoc_workbench_data_lib_glsl[]; extern char datatoc_workbench_background_lib_glsl[]; extern char datatoc_workbench_checkerboard_depth_frag_glsl[]; extern char datatoc_workbench_object_outline_lib_glsl[]; +extern char datatoc_workbench_curvature_lib_glsl[]; extern char datatoc_workbench_prepass_vert_glsl[]; extern char datatoc_workbench_common_lib_glsl[]; extern char datatoc_workbench_world_light_lib_glsl[]; @@ -123,6 +124,7 @@ static char *workbench_build_forward_composite_frag(void) BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl); + BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_forward_composite_frag_glsl); str = BLI_dynstr_get_cstring(ds); diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 6a11b2b8457..00d5781f069 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -57,6 +57,15 @@ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
