T73434: Improve Weight Paint Overlay Drawing.

Master multiplied the weight paint on top of the rendered image. This
reduced readability.

This patch removes the multiplication for weight painting and adds a
hint of the geometry below the overlay.

Reviewed By: Mets, pablodp606, campbellbarton

Maniphest Tasks: T73434

Differential Revision: https://developer.blender.org/D12170
This commit is contained in:
Jeroen Bakker 2021-08-18 07:31:43 +02:00 committed by Jeroen Bakker
parent 400cb25fc7
commit c0f600cad1
6 changed files with 52 additions and 31 deletions

View File

@ -92,18 +92,26 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
case CTX_MODE_PAINT_WEIGHT: {
opacity = is_edit_mode ? 1.0 : pd->overlay.weight_paint_mode_opacity;
if (opacity > 0.0f) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
sh = OVERLAY_shader_paint_weight();
const bool do_shading = draw_ctx->v3d->shading.type != OB_WIRE;
sh = OVERLAY_shader_paint_weight(do_shading);
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours);
DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending);
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp);
/* Arbitrary light to give a hint of the geometry behind the weights. */
if (do_shading) {
float light_dir[3];
copy_v3_fl3(light_dir, 0.0f, 0.5f, 0.86602f);
normalize_v3(light_dir);
DRW_shgroup_uniform_vec3_copy(grp, "light_dir", light_dir);
}
if (pd->painting.alpha_blending) {
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(psl->paint_depth_ps, state | pd->clipping_state);
@ -257,17 +265,10 @@ void OVERLAY_paint_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_FramebufferList *fbl = vedata->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (DRW_state_is_fbo()) {
if (pd->painting.alpha_blending) {
GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb :
fbl->overlay_default_fb);
}
else {
/* Paint overlay needs final color because of multiply blend mode. */
GPU_framebuffer_bind(pd->painting.in_front ? dfbl->in_front_fb : dfbl->default_fb);
}
GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb :
fbl->overlay_default_fb);
}
if (psl->paint_depth_ps) {

View File

@ -736,7 +736,7 @@ GPUShader *OVERLAY_shader_paint_face(void);
GPUShader *OVERLAY_shader_paint_point(void);
GPUShader *OVERLAY_shader_paint_texture(void);
GPUShader *OVERLAY_shader_paint_vertcol(void);
GPUShader *OVERLAY_shader_paint_weight(void);
GPUShader *OVERLAY_shader_paint_weight(bool shading);
GPUShader *OVERLAY_shader_paint_wire(void);
GPUShader *OVERLAY_shader_particle_dot(void);
GPUShader *OVERLAY_shader_particle_shape(void);

View File

@ -211,7 +211,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *paint_point;
GPUShader *paint_texture;
GPUShader *paint_vertcol;
GPUShader *paint_weight;
GPUShader *paint_weight[2];
GPUShader *paint_wire;
GPUShader *particle_dot;
GPUShader *particle_shape;
@ -1334,13 +1334,14 @@ GPUShader *OVERLAY_shader_paint_vertcol(void)
return sh_data->paint_vertcol;
}
GPUShader *OVERLAY_shader_paint_weight(void)
GPUShader *OVERLAY_shader_paint_weight(const bool shading)
{
int index = shading ? 1 : 0;
const DRWContextState *draw_ctx = DRW_context_state_get();
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->paint_weight) {
sh_data->paint_weight = GPU_shader_create_from_arrays({
if (!sh_data->paint_weight[index]) {
sh_data->paint_weight[index] = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg->lib,
datatoc_common_globals_lib_glsl,
datatoc_common_view_lib_glsl,
@ -1349,10 +1350,10 @@ GPUShader *OVERLAY_shader_paint_weight(void)
.frag = (const char *[]){datatoc_common_globals_lib_glsl,
datatoc_paint_weight_frag_glsl,
NULL},
.defs = (const char *[]){sh_cfg->def, NULL},
.defs = (const char *[]){sh_cfg->def, shading ? "#define FAKE_SHADING\n" : "", NULL},
});
}
return sh_data->paint_weight;
return sh_data->paint_weight[index];
}
GPUShader *OVERLAY_shader_paint_wire(void)

View File

@ -1,12 +1,12 @@
in vec2 weight_interp; /* (weight, alert) */
in float color_fac;
out vec4 fragColor;
uniform float opacity = 1.0;
uniform sampler1D colorramp;
uniform bool useAlphaBlend = false;
uniform bool drawContours = false;
float contours(float value, float steps, float width_px, float max_rel_width, float gradient)
@ -68,6 +68,13 @@ vec4 contour_grid(float weight, float weight_gradient)
return grid * clamp((weight_gradient - flt_eps) / flt_eps, 0.0, 1.0);
}
vec4 apply_color_fac(vec4 color_in)
{
vec4 color = color_in;
color.rgb = max(vec3(0.005), color_in.rgb) * color_fac;
return color;
}
void main()
{
float alert = weight_interp.y;
@ -75,12 +82,13 @@ void main()
/* Missing vertex group alert color. Uniform in practice. */
if (alert > 1.1) {
color = colorVertexMissingData;
color = apply_color_fac(colorVertexMissingData);
}
/* Weights are available */
else {
float weight = weight_interp.x;
vec4 weight_color = texture(colorramp, weight, 0);
weight_color = apply_color_fac(weight_color);
/* Contour display */
if (drawContours) {
@ -93,14 +101,9 @@ void main()
}
/* Zero weight alert color. Nonlinear blend to reduce impact. */
color = mix(weight_color, colorVertexUnreferenced, alert * alert);
vec4 color_unreferenced = apply_color_fac(colorVertexUnreferenced);
color = mix(weight_color, color_unreferenced, alert * alert);
}
if (useAlphaBlend) {
fragColor = vec4(color.rgb, opacity);
}
else {
/* mix with 1.0 -> is like opacity when using multiply blend mode */
fragColor = vec4(mix(vec3(1.0), color.rgb, opacity), 1.0);
}
fragColor = vec4(color.rgb, opacity);
}

View File

@ -1,8 +1,13 @@
#ifdef FAKE_SHADING
uniform vec3 light_dir;
#endif
in float weight;
in vec3 pos;
in vec3 nor;
out vec2 weight_interp; /* (weight, alert) */
out float color_fac;
void main()
{
@ -14,6 +19,16 @@ void main()
/* Separate actual weight and alerts for independent interpolation */
weight_interp = max(vec2(weight, -weight), 0.0);
/* Saturate the weight to give a hint of the geometry behind the weights. */
#ifdef FAKE_SHADING
vec3 view_normal = normalize(normal_object_to_view(nor));
color_fac = abs(dot(view_normal, light_dir));
color_fac = color_fac * 0.9 + 0.1;
#else
color_fac = 1.0;
#endif
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);
#endif

View File

@ -267,7 +267,8 @@ static void test_overlay_glsl_shaders()
EXPECT_NE(OVERLAY_shader_paint_point(), nullptr);
EXPECT_NE(OVERLAY_shader_paint_texture(), nullptr);
EXPECT_NE(OVERLAY_shader_paint_vertcol(), nullptr);
EXPECT_NE(OVERLAY_shader_paint_weight(), nullptr);
EXPECT_NE(OVERLAY_shader_paint_weight(false), nullptr);
EXPECT_NE(OVERLAY_shader_paint_weight(true), nullptr);
EXPECT_NE(OVERLAY_shader_paint_wire(), nullptr);
EXPECT_NE(OVERLAY_shader_particle_dot(), nullptr);
EXPECT_NE(OVERLAY_shader_particle_shape(), nullptr);