From 19f46c6ac071e32482969319f43d148ada97a63f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 24 Sep 2018 17:10:29 +0200 Subject: Weight Paint: Multiply overlay on the mesh Use the multiply blending mode for the weight paint overlay. To support the opacity slider, we need a new shader. Otherwise this combination of multiplication and mixing does not seem to be supported by glBlendFunc. Reviewers: brecht Differential Revision: https://developer.blender.org/D3727 --- source/blender/draw/modes/paint_weight_mode.c | 10 +++------- source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/GPU_shader.h | 1 + source/blender/gpu/intern/gpu_shader.c | 4 ++++ ...pu_shader_multiply_and_blend_preprocessing.glsl | 22 ++++++++++++++++++++++ 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 source/blender/gpu/shaders/gpu_shader_multiply_and_blend_preprocessing.glsl diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index f0dd1994e09..c4608dfd397 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -91,7 +91,7 @@ typedef struct PAINT_WEIGHT_PrivateData { static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata)) { if (!e_data.weight_face_shader) { - e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA); + e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_MULTIPLY_AND_BLEND_PREPROCESSING); } if (!e_data.wire_overlay_shader) { @@ -129,15 +129,11 @@ static void PAINT_WEIGHT_cache_init(void *vedata) /* Create a pass */ psl->weight_faces = DRW_pass_create( "Weight Pass", - DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND); + DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY); stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces); - static float light[3] = {-0.3f, 0.5f, 1.0f}; - static float world_light = 1.0f; - DRW_shgroup_uniform_vec3(stl->g_data->fweights_shgrp, "light", light, 1); - DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "alpha", &v3d->overlay.weight_paint_mode_opacity, 1); - DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "global", &world_light, 1); + DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1); } { diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 20360cc62cb..5c010a58137 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -140,6 +140,7 @@ data_to_c_simple(shaders/gpu_shader_diag_stripes_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_simple_lighting_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_multiply_and_blend_preprocessing.glsl SRC) data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_flat_id_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 21d5b5871fa..d14164e930e 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -118,6 +118,7 @@ typedef enum GPUBuiltinShader { GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA, + GPU_SHADER_MULTIPLY_AND_BLEND_PREPROCESSING, /* for simple 2D drawing */ /** diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 0f9e0b2008e..9feaed80c2f 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -64,6 +64,7 @@ extern char datatoc_gpu_shader_simple_lighting_frag_glsl[]; extern char datatoc_gpu_shader_simple_lighting_flat_color_frag_glsl[]; extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl[]; +extern char datatoc_gpu_shader_multiply_and_blend_preprocessing_glsl[]; extern char datatoc_gpu_shader_flat_color_frag_glsl[]; extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[]; extern char datatoc_gpu_shader_flat_id_frag_glsl[]; @@ -706,6 +707,9 @@ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = { [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl }, + [GPU_SHADER_MULTIPLY_AND_BLEND_PREPROCESSING] = + { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, + datatoc_gpu_shader_multiply_and_blend_preprocessing_glsl }, [GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_image_vert_glsl, diff --git a/source/blender/gpu/shaders/gpu_shader_multiply_and_blend_preprocessing.glsl b/source/blender/gpu/shaders/gpu_shader_multiply_and_blend_preprocessing.glsl new file mode 100644 index 00000000000..88d84aeaef6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_multiply_and_blend_preprocessing.glsl @@ -0,0 +1,22 @@ +uniform float opacity; + +in vec4 finalColor; +out vec4 fragColor; + +/* Blend Mode goal: + * First multiply the foreground and background and then mix the result + * of that with the background based on a opacity value. + * + * result = background * foreground * opacity + background * (1 - opacity) + * = background * (foreground * opacity + (1 - opacity)) + * <------------------------------------> + * computed in this shader + * + * Afterwards the background and the new foreground only have to be multiplied. + */ + +void main() +{ + fragColor = finalColor * opacity + (1 - opacity); + fragColor.a = finalColor.a; +} -- cgit v1.2.3