[Bf-blender-cvs] [ba3ef44a6b5] blender2.8: Implement display of weight isoline contours in the fragment shader.

Alexander Gavrilov noreply at git.blender.org
Mon Oct 8 13:16:59 CEST 2018


Commit: ba3ef44a6b57970b278c3a99a7ee00906efa3eb7
Author: Alexander Gavrilov
Date:   Thu Sep 27 18:38:07 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBba3ef44a6b57970b278c3a99a7ee00906efa3eb7

Implement display of weight isoline contours in the fragment shader.

Add an option to display contour lines tracing through points with the
same interpolated weight value in weight paint mode. This can be useful
for working on gentle gradients over a relatively high resolution mesh,
where the difference in color between adjacent vertices is very small.

The contour grid has 3 levels of detail going down to step 0.001,
which automatically fade in or out based on the weight gradient.

Fade out works by capping both screen space and weight space line
width, and reducing alpha when the screen space width becomes too
small for moire and noise-less rendering.

Reviewers: fclem

Differential Revision: https://developer.blender.org/D3749

===================================================================

M	release/scripts/startup/bl_ui/space_view3d.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/draw/modes/paint_weight_mode.c
M	source/blender/draw/modes/shaders/paint_weight_frag.glsl
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 b84f3693274..5726e359f16 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -4501,9 +4501,10 @@ class VIEW3D_PT_overlay_edit_mesh_shading(Panel):
 
         col.prop(overlay, "show_weight", text="Vertex Group Weights")
         if overlay.show_weight:
-            row = col.split()
+            row = col.split(factor=0.33)
             row.label(text="Zero Weights")
-            row.prop(tool_settings, "vertex_group_user", text="")
+            sub = row.row()
+            sub.prop(tool_settings, "vertex_group_user", expand=True)
 
         col.prop(overlay, "show_statvis", text="Mesh Analysis")
         if overlay.show_statvis:
@@ -4774,6 +4775,14 @@ class VIEW3D_PT_overlay_paint(Panel):
             'PAINT_WEIGHT': "weight_paint_mode_opacity",
         }[context.mode], text="Opacity")
 
+        if context.mode == 'PAINT_WEIGHT':
+            row = col.split(factor=0.33)
+            row.label(text="Zero Weights")
+            sub = row.row()
+            sub.prop(context.tool_settings, "vertex_group_user", expand=True)
+
+            col.prop(overlay, "show_wpaint_contours")
+
         if context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
             col.prop(overlay, "show_paint_wire")
 
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 47e6d96822f..6f104370485 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1091,10 +1091,6 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
             row.active = mesh.use_mirror_x
             row.prop(mesh, "use_mirror_topology")
 
-        col.label(text="Show Zero Weights:")
-        sub = col.row()
-        sub.prop(tool_settings, "vertex_group_user", expand=True)
-
         self.unified_paint_settings(col, context)
 
 # ********** default tools for vertex-paint ****************
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
index f5394e4e925..9060a97f412 100644
--- a/source/blender/draw/modes/paint_weight_mode.c
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -140,6 +140,8 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
 
 		stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
 
+		DRW_shgroup_uniform_bool_copy(stl->g_data->fweights_shgrp, "drawContours", (v3d->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0);
+
 		DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1);
 		DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", globals_weight_ramp);
 		DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", globals_ubo);
diff --git a/source/blender/draw/modes/shaders/paint_weight_frag.glsl b/source/blender/draw/modes/shaders/paint_weight_frag.glsl
index bb0834e9cd4..faa36f5535e 100644
--- a/source/blender/draw/modes/shaders/paint_weight_frag.glsl
+++ b/source/blender/draw/modes/shaders/paint_weight_frag.glsl
@@ -6,13 +6,71 @@ out vec4 fragColor;
 uniform float opacity = 1.0;
 uniform sampler1D colorramp;
 
+uniform bool drawContours = false;
+
+float contours(float value, float steps, float width_px, float max_rel_width, float gradient)
+{
+	/* Minimum visible and minimum full strength line width in screen space for fade out. */
+	const float min_width_px = 1.3, fade_width_px = 2.3;
+	/* Line is thinner towards the increase in the weight gradient by this factor. */
+	const float hi_bias = 2.0;
+
+	/* Don't draw lines at 0 or 1. */
+	float rel_value = value * steps;
+
+	if (rel_value < 0.5 || rel_value > steps - 0.5)
+		return 0.0;
+
+	/* Check if completely invisible due to fade out. */
+	float rel_gradient = gradient * steps;
+	float rel_min_width = min_width_px * rel_gradient;
+
+	if (max_rel_width <= rel_min_width)
+		return 0.0;
+
+	/* Main shape of the line, accounting for width bias and maximum weight space width. */
+	float rel_width = width_px * rel_gradient;
+
+	float offset = fract(rel_value + 0.5) - 0.5;
+
+	float base_alpha = 1.0 - max(offset * hi_bias, -offset) / min(max_rel_width, rel_width);
+
+	/* Line fadeout when too thin in screen space. */
+	float rel_fade_width = fade_width_px * rel_gradient;
+
+	float fade_alpha = (max_rel_width - rel_min_width) / (rel_fade_width - rel_min_width);
+
+	return clamp(base_alpha, 0.0, 1.0) * clamp(fade_alpha, 0.0, 1.0);
+}
+
+vec4 contour_grid(float weight, float weight_gradient)
+{
+	/* Fade away when the gradient is too low to avoid big fills and noise. */
+	float flt_eps = max(1e-8, 1e-6 * weight);
+
+	if (weight_gradient <= flt_eps)
+		return vec4(0.0);
+
+	/* Three levels of grid lines */
+	float grid10 = contours(weight, 10.0, 5.0, 0.3, weight_gradient);
+	float grid100 = contours(weight, 100.0, 3.5, 0.35, weight_gradient) * 0.6;
+	float grid1000 = contours(weight, 1000.0, 2.5, 0.4, weight_gradient) * 0.25;
+
+	/* White lines for 0.1 and 0.01, and black for 0.001 */
+	vec4 grid = vec4(1.0) * max(grid10, grid100);
+
+	grid.a = max(grid.a, grid1000);
+
+	return grid * clamp((weight_gradient - flt_eps) / flt_eps, 0.0, 1.0);
+}
+
 void main()
 {
 	float alert = weight_interp.y;
 	vec4 color;
 
-	/* Missing vertex group alert color */
-	if (alert > 1.0) {
+	/* Missing vertex group alert color. Uniform in practice. */
+	if (alert > 1.1) {
 		color = colorVertexMissingData;
 	}
 	/* Weights are available */
@@ -20,6 +78,16 @@ void main()
 		float weight = weight_interp.x;
 		vec4 weight_color = texture(colorramp, weight, 0);
 
+		/* Contour display */
+		if (drawContours) {
+			/* This must be executed uniformly for all fragments */
+			float weight_gradient = length(vec2(dFdx(weight), dFdy(weight)));
+
+			vec4 grid = contour_grid(weight, weight_gradient);
+
+			weight_color = grid + weight_color * (1 - grid.a);
+		}
+
 		/* Zero weight alert color. Nonlinear blend to reduce impact. */
 		color = mix(weight_color, colorVertexUnreferenced, alert * alert);
 	}
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 1b8846df4bc..fca1a79c775 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -177,6 +177,10 @@ typedef struct View3DOverlay {
 	/* Paint mode settings */
 	int paint_flag;
 
+	/* Weight paint mode settings */
+	int wpaint_flag;
+	char _pad2[4];
+
 	/* Alpha for texture, weight, vertex paint overlay */
 	float texture_paint_mode_opacity;
 	float vertex_paint_mode_opacity;
@@ -460,6 +464,11 @@ enum {
 	V3D_OVERLAY_PAINT_WIRE        = (1 << 0),
 };
 
+/* View3DOverlay->wpaint_flag */
+enum {
+	V3D_OVERLAY_WPAINT_CONTOURS   = (1 << 0),
+};
+
 /* View3D->around */
 enum {
 	/* center of the bounding box */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index c2224fe767b..92555c54eb4 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2783,6 +2783,11 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Show Wire", "Use wireframe display in painting modes");
 	RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
+	prop = RNA_def_property(srna, "show_wpaint_contours", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "overlay.wpaint_flag", V3D_OVERLAY_WPAINT_CONTOURS);
+	RNA_def_property_ui_text(prop, "Show Weight Contours", "Show contour lines formed by points with the same interpolated weight");
+	RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
 	prop = RNA_def_property(srna, "show_weight", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "overlay.edit_flag", V3D_OVERLAY_EDIT_WEIGHT);
 	RNA_def_property_ui_text(prop, "Show Weights", "Display weights in editmode");



More information about the Bf-blender-cvs mailing list