Badge Height Layer V1 (DAELab)
The same six heights, now with a config you can actually audit
- images
- height_mask
- height_image
- unmatched_mask
- height_profile
- applied_config
- config_digest
- config_report
What this is for
Badge Height Layer V1 does the same arithmetic as the original: colours in, six discrete heights out. What changed is the plumbing. Instead of configuration living only in the node's panel and the saved workflow, V1 writes it into an explicit height_layer_config input, digests it, and hands you back the config it actually used plus a report. Two extra outputs that sound like bureaucracy and are actually the difference between "my heights are wrong" and "my heights are wrong and here's why".
It's a separate node ID - DAELabBadgeHeightLayerV1 - and the pack is explicit that it does not replace the old node, so existing workflows keep working on the original. If you're starting fresh, use this one; the extra outputs cost nothing and answer questions the old node can't.
How it works
The colour-to-height maths is inherited unchanged: each group has a colour, a threshold (RGB Euclidean distance, 0–255) and a layer from Cut Out to Layer 5, up to 16 groups; each pixel goes to the nearest enabled colour within its tolerance; exact ties go to the higher layer; the height value is layer/5, so Layer 1 = 0.2 and Layer 5 = 1.0. Transparent pixels are forced to 0.0 and don't count as unmatched. No feathering anywhere.
What V1 adds is a configuration surface you can inspect. The panel's two-row-per-layer editor (colour + threshold on one row, semantic height on the other, with explicit "lowest / second / middle / second-highest / highest" labels and the H=0.2–1.0 values shown) writes to a hidden height_layer_config string. Before queueing and before serialising, the front end cross-checks the draft, the node properties, the hidden widget and the queue value, and blocks execution if they disagree. On the Python side, IS_CHANGED digests the resolved config, so two runs with the same art but a different layer mapping are correctly treated as different work.
Two deliberate removals and one addition in behaviour: there's no enabled flag per layer anymore - migrating an old config keeps only the layers that were enabled - and the outputs now include the resolved applied_config JSON, a config_digest, and a human-readable config_report.
The inputs and outputs
images- required, your flat colour-ID artwork.height_layer_config- optional string. Leave it empty and the node reads its configuration from the node properties in the workflow. Fill it and the value wins, which is exactly what you want when submitting programmatically.
Outputs: the original four - height_mask, height_image, unmatched_mask, height_profile - plus applied_config, config_digest, config_report.
The first four behave identically to the old node, so anything already wired to them keeps working. config_report is the one to actually read when a height map comes out flat: it tells you which layers were configured, which matched pixels, and which came back empty.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library.git
# restart ComfyUI, then hard-refresh the browser
No models, no extra dependencies. The restart-and-refresh part is not optional: the compact panel, the icon-based add/delete controls and the config serialisation are all front-end code, and a cached old bundle against new Python is the classic source of "my config didn't apply".
Where people get burned
Submitting via API with no workflow attached. height_layer_config empty plus no extra_pnginfo node properties means zero groups means an all-zero height map that looks like a broken node. Either pass height_layer_config explicitly - that's what the optional input is for - or submit the padded workflow.
Assuming the config digest is a hash of your art. It's a hash of the configuration. Change an input image with identical config and the digest stays the same; that's correct, because the height mapping didn't change. If you're using config_digest as a cache key for the whole stage, add the image yourself.
Config mismatch errors on queue. If the front end says the draft and hidden widget disagree, don't hand-patch the JSON - reopen the panel, let it normalise, and re-queue. The check exists because a mismatched config produces a height map that doesn't correspond to what the panel showed you, which is the most expensive kind of silent error in a pipeline that ends in a paid render.
The same art problems as the old node. Gradients, antialiased edges, shared colours between cut outs and solids - all still apply. V1 is more auditable, not more forgiving.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| height_layer_configopt | STRING | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| height_mask | MASK | — |
| height_image | IMAGE | — |
| unmatched_mask | MASK | — |
| height_profile | BADGE_HEIGHT_PROFILE | — |
| applied_config | STRING | — |
| config_digest | STRING | — |
| config_report | STRING | — |