Skip to content

[DRAFT] feat(ByteDance): LAYERS output on Seedream Layer Separation - #15387

Closed
purzbeats wants to merge 1 commit into
fix/seedream-layer-separation-wiringfrom
feat/seedream-layers-output
Closed

[DRAFT] feat(ByteDance): LAYERS output on Seedream Layer Separation#15387
purzbeats wants to merge 1 commit into
fix/seedream-layer-separation-wiringfrom
feat/seedream-layers-output

Conversation

@purzbeats

@purzbeats purzbeats commented Aug 7, 2026

Copy link
Copy Markdown
Member

Stacked. Base is #15366 (for the tooltip context). Also requires #15317, which supplies the LAYERS io type — this does not import without it.

Renames the existing layers IMAGE output to layers_batch and adds a new layers output of type LAYERS: the base plate at z_index 0 with each element above it, carrying its own placement, name and stacking order. Wires straight into Create Layered Image — no Batch Images, no Add Layer.

base_image    -> IMAGE
base_mask     -> MASK
layers_batch  -> IMAGE          (renamed)
masks         -> MASK
bboxes        -> BOUNDING_BOX
layers        -> LAYERS         (new)

Why

The outputs currently cannot drive the compositor with placement intact. expand_item_frames applies an item’s single x/y/w/h/name/z_index to every frame of a batch, so 16 layers share one placement. That is why full-canvas mode is the only workable path today — placement is baked into the pixels, so x=0, y=0 is correct for all of them. It costs ~768MB of layer tensors plus ~268MB of masks at 2K with 16 layers, and leaves minimal-size mode unusable with the compositor.

One document item per layer sidesteps this with no change to the compositor: document_items already sorts by z_index, expand_item_frames already handles single-frame items correctly.

The bboxes output is currently dead

Its tooltip promises “Placement boxes for Create Layered Image”, but the bbox input it was written against was removed in 1c4953ff. #15386 revives it generally for any bbox producer; this PR is the direct path for this node specifically. They are alternatives — pick one.

Notes

  • New output is appended, not placed next to layers_batch, since outputs are wired by index and reordering breaks saved workflows. Happy to move it; the node is unreleased.
  • Layers flagged bbox_degenerate / bbox_out_of_canvas are skipped rather than added as invisible items.
  • Crop mode keeps each item at its own size; full-canvas mode puts items at the origin since placement is already in the pixels.

Before judging round-trip fidelity

The compositor composites in linear light (srgb_to_linear in, linear_to_srgb out — symmetric and deliberate). Hard edges reconstruct to within 0.50/255; anti-aliased edges diverge by up to ~30/255 if the model decomposed assuming sRGB-space compositing. Worth confirming with ByteDance which space they assume — the claim that elements “directly restore the original image” only holds under one of them.

Draft for @bigcat88 and @jtydhr88. cc @christian-byrne

API Node PR Checklist

Scope

  • Is API Node Change

Pricing & Billing

  • Need pricing update
  • No pricing update

If Need pricing update:

  • Metronome rate cards updated
  • Auto‑billing tests updated and passing

QA

  • QA done
  • QA not required

Comms

  • Informed Kosinkadink

DRAFT - stacked on #15317, which supplies the LAYERS io type. Does not
import without it.

Renames the existing `layers` IMAGE output to `layers_batch` and adds a
new `layers` output of type LAYERS: the base plate at z_index 0 with each
separated element above it, carrying its own placement, name and stacking
order. It wires straight into Create Layered Image - no Batch Images, no
Add Layer.

Why. The node's outputs currently cannot drive the compositor with
placement intact. `expand_item_frames` applies an item's single
x/y/w/h/name/z_index to every frame of a batch, so 16 layers share one
placement. That is why full-canvas mode is the only workable path today:
placement is baked into the pixels so x=0,y=0 is correct for all of them.
It costs ~768MB of layer tensors plus ~268MB of masks at 2K with 16
layers, and it leaves minimal-size mode unusable with the compositor.

Emitting one document item per layer sidesteps this with no change to the
compositor: `document_items` already sorts by z_index and
`expand_item_frames` already handles single-frame items correctly.

The `bboxes` output is also currently dead. Its tooltip promises
"Placement boxes for Create Layered Image", but the bbox input it was
written against was removed in 1c4953f when the compositor moved to the
LAYERS document. See #15317 for a general adapter node that revives it for
any bbox producer; this PR is the direct path for this node specifically.

Notes:
- The new output is appended rather than placed next to `layers_batch`,
  since outputs are wired by index and reordering breaks saved workflows.
  Happy to move it - the node is unreleased.
- Layers flagged `bbox_degenerate` or `bbox_out_of_canvas` are skipped
  rather than added as invisible items.
- In crop mode each item keeps its own size; in full-canvas mode
  placement is already in the pixels so items sit at the origin.

Caveat worth knowing before judging round-trip fidelity: the compositor
composites in linear light (srgb_to_linear in, linear_to_srgb out). Hard
edges reconstruct to within 0.50/255, but anti-aliased edges diverge by up
to ~30/255 if the model decomposed assuming sRGB-space compositing. Worth
confirming with ByteDance which space they assume - their claim that
elements "directly restore the original image" only holds under one.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🎉 Thank you for your contribution, we really appreciate it! 🎉

Like many open source projects, we require contributors to sign our Contributor License Agreement (CLA). A CLA makes the ownership of contributions explicit, so contributors and the project share a clear understanding of how the code can be used. By signing, you:

  • Confirm that you own your contribution.
  • Keep the right to reuse your own code.
  • Grant us a copyright license to include and share it within our projects.

CLAs are standard practice across major open source projects including those under the Apache Software Foundation and the Linux Foundation. Ours is based on the Apache Software Foundation's CLA. Most importantly, it would enable us to relicense the project under a more permissive license in the future, giving the project and its community greater flexibility.

To sign, please post a new comment on this PR with exactly the following text:


I have read and agree to the Contributor License Agreement


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@bigcat88

bigcat88 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

this draft was helpful. closing it, we checked everything from our PR against this draft already.

@bigcat88 bigcat88 closed this Aug 7, 2026
@bigcat88
bigcat88 deleted the feat/seedream-layers-output branch August 7, 2026 14:01
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants