[Bf-blender-cvs] [a3be79303f4] viewport-compositor: Viewport Compositor: Complete Alpha Over node
Omar Emara
noreply at git.blender.org
Tue Dec 28 20:02:44 CET 2021
Commit: a3be79303f475ee83a196413b6d5c0abafc0877e
Author: Omar Emara
Date: Sat Nov 6 22:21:47 2021 +0200
Branches: viewport-compositor
https://developer.blender.org/rBa3be79303f475ee83a196413b6d5c0abafc0877e
Viewport Compositor: Complete Alpha Over node
This patch adds the missing premultiplication handling for the Alpha
Over node. The shader is a straightforward port of the compositor code.
===================================================================
M source/blender/gpu/shaders/composite/gpu_shader_composite_alpha_over.glsl
M source/blender/nodes/composite/nodes/node_composite_alphaOver.cc
===================================================================
diff --git a/source/blender/gpu/shaders/composite/gpu_shader_composite_alpha_over.glsl b/source/blender/gpu/shaders/composite/gpu_shader_composite_alpha_over.glsl
index 29c9d13a6b2..99483c89039 100644
--- a/source/blender/gpu/shaders/composite/gpu_shader_composite_alpha_over.glsl
+++ b/source/blender/gpu/shaders/composite/gpu_shader_composite_alpha_over.glsl
@@ -1,8 +1,51 @@
+void node_composite_alpha_over_mixed(
+ float factor, vec4 color, vec4 over_color, float premultiply_factor, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float add_factor = 1.0 - premultiply_factor + over_color.a * premultiply_factor;
+ float premultiplier = factor * add_factor;
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + vec2(premultiplier, factor).xxxy * over_color;
+ }
+}
+
+void node_composite_alpha_over_key(float factor, vec4 color, vec4 over_color, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float premultiplier = factor * over_color.a;
+
+ result.rgb = mix(color.rgb, over_color.rgb, premultiplier);
+ result.a = (1.0 - premultiplier) * color.a + factor * over_color.a;
+ }
+}
-void node_composite_alpha_over(
- float fac, vec4 color1, vec4 color2, float premult_convert, float premult_fac, out vec4 result)
+void node_composite_alpha_over_premultiply(float factor,
+ vec4 color,
+ vec4 over_color,
+ out vec4 result)
{
- /* TODO(fclem) Finalize with all premult variant. */
- result = color1 * (1.0 - color2.a) + color2;
- result = mix(color1, result, fac);
+ if (over_color.a < 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + factor * over_color;
+ }
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_alphaOver.cc b/source/blender/nodes/composite/nodes/node_composite_alphaOver.cc
index 3d50eb4df9c..f9ef2ba8f26 100644
--- a/source/blender/nodes/composite/nodes/node_composite_alphaOver.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.cc
@@ -42,18 +42,24 @@ static void node_alphaover_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
}
-static int node_composit_gpu_rlayers(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
+static int node_composite_gpu_alpha_over(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
{
- GPUNodeLink *premult_convert = GPU_constant(&((NodeTwoFloats *)node->storage)->x);
- GPUNodeLink *premult_fac = GPU_uniform(&((NodeTwoFloats *)node->storage)->y);
+ const float premultiply_factor = ((NodeTwoFloats *)node->storage)->x;
- GPU_stack_link(mat, node, "node_composite_alpha_over", in, out, premult_convert, premult_fac);
+ if (premultiply_factor != 0.0f) {
+ return GPU_stack_link(
+ mat, node, "node_composite_alpha_over_mixed", in, out, GPU_uniform(&premultiply_factor));
+ }
- return true;
+ if (node->custom1) {
+ return GPU_stack_link(mat, node, "node_composite_alpha_over_key", in, out);
+ }
+
+ return GPU_stack_link(mat, node, "node_composite_alpha_over_premultiply", in, out);
}
void register_node_type_cmp_alphaover(void)
@@ -65,7 +71,7 @@ void register_node_type_cmp_alphaover(void)
node_type_init(&ntype, node_alphaover_init);
node_type_storage(
&ntype, "NodeTwoFloats", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_composit_gpu_rlayers);
+ node_type_gpu(&ntype, node_composite_gpu_alpha_over);
nodeRegisterType(&ntype);
}
More information about the Bf-blender-cvs
mailing list