[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