# RotoMerge node¶

*This documentation is for version 2.0 of RotoMerge (net.sf.openfx.MergeRoto).*

## Description¶

Pixel-by-pixel merge operation between two inputs using and external alpha channel for input A. All channels from input A are merged with those from B, using RotoMask as the alpha channel for input A: the alpha channel from A is thus merged onto the alpha channel from B using the RotoMask as the alpha value (“a” in the formulas). This may be useful, for example, to “paint” alpha values from A onto the alpha channel of B using a given operation with an external alpha mask (which may be opaque even where the alpha channel of A is zero).

A description of most operators is available in the W3C Compositing and Blending Level 1 Recommendation https://www.w3.org/TR/compositing-1/ and a complete explanation of the Porter-Duff compositing operators can be found in “Compositing Digital Images”, by T. Porter and T. Duff (Proc. SIGGRAPH 1984) http://keithp.com/~keithp/porterduff/p253-porter.pdf

Note that if an input with only RGB components is connected to A or B, its alpha channel is considered to be opaque (one) by default, thus the output will be completely opaque if the checkbox for channel A of input B is checked. One reason for this behaviour is that non-zero RGB values with a zero A value are not valid alpha-premultiplied RGBA values. If the user wishes to keep the background fully transparent, it can only be black, which is equivalent to not using the merge operator. Non-black fully transparent pixels should never appear anywhere in a proper compositing graph.

### Operators¶

The following operators are available.

#### Porter-Duff compositing operators¶

- copy: A (a.k.a. src)
- over: A+B(1-a) (a.k.a. src-over)
- under: A(1-b)+B (a.k.a. dst-over)
- in: Ab (a.k.a. src-in)
- mask: Ba (a.k.a dst-in)
- out: A(1-b) (a.k.a. src-out)
- stencil: B(1-a) (a.k.a. dst-out)
- atop: Ab + B(1 - a) (a.k.a. src-atop)
- xor: A(1-b)+B(1-a)

#### Blend modes, see https://en.wikipedia.org/wiki/Blend_modes¶

##### Multiply and Screen¶

- multiply: AB, A if A < 0 and B < 0
- screen: A+B-AB if A or B <= 1, otherwise max(A, B)
- overlay: multiply(A, 2*B) if B < 0.5, screen(A, 2*B - 1) if B > 0.5
- hard-light: multiply(2*A, B) if A < 0.5, screen(2*A - 1, B) if A > 0.5
- soft-light: burn-in if A < 0.5, lighten if A > 0.5

##### Dodge and burn¶

- color-dodge: brighten B towards A
- color-burn: darken B towards A
- pinlight: if B >= 0.5 then max(A, 2*B - 1), min(A, B * 2) else
- difference: abs(A-B) (a.k.a. absminus)
- exclusion: A+B-2AB
- divide: A/B, 0 if A < 0 and B < 0

##### Simple arithmetic blend modes¶

- divide: A/B, 0 if A < 0 and B < 0
- plus: A+B (a.k.a. add)
- from: B-A (a.k.a. subtract)
- minus: A-B
- difference: abs(A-B) (a.k.a. absminus)
- min: min(A, B) (a.k.a. darken only)
- max: max(A, B) (a.k.a. lighten only)

##### Hue, saturation and luminosity¶

- hue: SetLum(SetSat(A, Sat(B)), Lum(B))
- saturation: SetLum(SetSat(B, Sat(A)), Lum(B))
- color: SetLum(A, Lum(B))
- luminosity: SetLum(B, Lum(A))

#### Other¶

- average: (A + B) / 2
- conjoint-over: A + B(1-a)/b, A if a > b
- disjoint-over: A+B(1-a)/b, A+B if a+b < 1
- freeze: 1-sqrt(1-A)/B
- geometric: 2AB/(A+B)
- grain-extract: B - A + 0.5
- grain-merge: B + A - 0.5
- hypot: sqrt(A*A+B*B)
- matte: Aa + B(1-a) (unpremultiplied over)
- reflect: A*A / (1 - B)

See also:

- “Digital Image Compositing” by Marc Levoy https://graphics.stanford.edu/courses/cs248-06/comp/comp.html
- “Compositing and Blending Level 1” https://www.w3.org/TR/compositing-1/
- “SVG Compositing Specification” https://www.w3.org/TR/SVGCompositing/
- “ISO 32000-1:2008: Portable Document Format (July 2008)”, Sec. 11.3 “Basic Compositing Operations” http://www.adobe.com/devnet/pdf/pdf_reference.html
- “Merge” by Martin Constable http://opticalenquiry.com/nuke/index.php?title=Merge
- “Merge Blend Modes” by Martin Constable http://opticalenquiry.com/nuke/index.php?title=Merge_Blend_Modes
- “Primacy of the B Feed” by Martin Constable http://opticalenquiry.com/nuke/index.php?title=Primacy_of_the_B_Feed
- grain-extract and grain-merge are described in http://docs.gimp.org/en/gimp-concepts-layer-modes.html

## Inputs¶

Input | Description | Optional |
---|---|---|

B | The main input. This input is passed through when the merge node is disabled. | Yes |

A | The image sequence to merge with input B. | Yes |

Mask | Yes | |

A2 | Yes |

## Controls¶

Parameter / script name | Type | Default | Function |
---|---|---|---|

Operation / `operation` |
Choice | over | The operation used to merge the input A and B images.
The operator formula is applied to each component: A and B represent the input component (Red, Green, Blue, or Alpha) of each input, and a and b represent the alpha channel of each input.
If Alpha masking is checked, the output alpha is computed using a different formula (a+b - a*b).
Alpha masking is always enabled for HSL modes (hue, saturation, color, luminosity).
atop: Ab + B(1 - a) (a.k.a. src-atop)average: (A + B) / 2color: SetLum(A, Lum(B))color-burn: darken B towards Acolor-dodge: brighten B towards Aconjoint-over: A + B(1-a)/b, A if a > bcopy: A (a.k.a. src)difference: abs(A-B) (a.k.a. absminus)disjoint-over: A+B(1-a)/b, A+B if a+b < 1divide: A/B, 0 if A < 0 and B < 0exclusion: A+B-2ABfreeze: 1-sqrt(1-A)/Bfrom: B-A (a.k.a. subtract)geometric: 2AB/(A+B)grain-extract: B - A + 0.5grain-merge: B + A - 0.5hard-light: multiply(2*A, B) if A < 0.5, screen(2*A - 1, B) if A > 0.5hue: SetLum(SetSat(A, Sat(B)), Lum(B))hypot: sqrt(A*A+B*B)in: Ab (a.k.a. src-in)luminosity: SetLum(B, Lum(A))mask: Ba (a.k.a dst-in)matte: Aa + B(1-a) (unpremultiplied over)max: max(A, B) (a.k.a. lighten only)min: min(A, B) (a.k.a. darken only)minus: A-Bmultiply: AB, A if A < 0 and B < 0out: A(1-b) (a.k.a. src-out)over: A+B(1-a) (a.k.a. src-over)overlay: multiply(A, 2*B) if B < 0.5, screen(A, 2*B - 1) if B > 0.5pinlight: if B >= 0.5 then max(A, 2*B - 1), min(A, B * 2) elseplus: A+B (a.k.a. add)reflect: A*A / (1 - B)saturation: SetLum(SetSat(B, Sat(A)), Lum(B))screen: A+B-AB if A or B <= 1, otherwise max(A, B)soft-light: burn-in if A < 0.5, lighten if A > 0.5stencil: B(1-a) (a.k.a. dst-out)under: A(1-b)+B (a.k.a. dst-over)xor: A(1-b)+B(1-a) |

Bounding Box / `bbox` |
Choice | Union | What to use to produce the output image’s bounding box.
Union (union): Union of all connected inputs.Intersection (intersection): Intersection of all connected inputs.A (a): Bounding box of input A.B (b): Bounding box of input B. |

Alpha masking / `screenAlpha` |
Boolean | Off | When enabled, the input images are unchanged where the other image has 0 alpha, and the output alpha is set to a+b - a*b. When disabled the alpha channel is processed as any other channel. Option is disabled for operations where it does not apply or makes no difference. |

R / `AChannelsR` |
Boolean | On | Use red channel from A input(s). |

G / `AChannelsG` |
Boolean | On | Use green channel from A input(s). |

B / `AChannelsB` |
Boolean | On | Use blue channel from A input(s). |

A / `AChannelsA` |
Boolean | On | Use alpha channel from A input(s). |

R / `BChannelsR` |
Boolean | On | Use red channel from B input. |

G / `BChannelsG` |
Boolean | On | Use green channel from B input. |

B / `BChannelsB` |
Boolean | On | Use blue channel from B input. |

A / `BChannelsA` |
Boolean | On | Use alpha channel from B input. |

R / `OutputChannelsR` |
Boolean | On | Write red channel to output. |

G / `OutputChannelsG` |
Boolean | On | Write green channel to output. |

B / `OutputChannelsB` |
Boolean | On | Write blue channel to output. |

A / `OutputChannelsA` |
Boolean | On | Write alpha channel to output. |

Invert Mask / `maskInvert` |
Boolean | Off | When checked, the effect is fully applied where the mask is 0. |

Mix / `mix` |
Double | 1 | Mix factor between the original and the transformed image. |