MiniMax H3 Skin Finish Specular-Aware Split / 高光感知纹理解耦 (Advanced EXP)
The frequency split that cares about highlights (specular-aware, not a replacement)
- source_frames
- candidate_frames
- used_skin_mask
- audio
- specular_frequency_candidate
- source
- selected
- audio
- effective_mask
- rejected_mask
- difference
- report_json
Plain frequency splitting has a blind spot: when you strip a skin-finish candidate down to its low-frequency tone and re-add source detail, you also throw away the candidate's highlight work. Oily shine on a forehead or nose bridge is high-frequency-ish energy, and a naive split discards the whole point of an oil-control pass. The Specular-Aware Split is the append-only alternative that runs the ordinary Frequency Split first, then selectively restores the darker highlight treatment that the split lost.
How it works
The pipeline is: run the unchanged Frequency Split, then walk back only the bright, positive detail the split erased - but only where three things agree: bright semantic skin, positive local source detail, and the input candidate's own treatment. That agreement requirement is what stops it from inventing shine that was never there.
The knobs that matter:
highlight_detail_suppression(default 0.65) - how much of the lost bright detail comes back from the input candidate. 0 returns the exact ordinary split; the correction can never overshoot the candidate.highlight_start/highlight_end(0.6 → 0.92) - the luma band that counts as "highlight."positive_detail_threshold(default 0.004) andtreatment_intent_scale- what counts as positive detail worth restoring and how hard to apply it.maximum_specular_delta(default 0.04) - a hard per-pixel luma cap before the Texture Guard runs, so no single pixel gets slammed.
Everything else - the separation radius, mask-area limits, clipping epsilon, chunk size - mirrors the Frequency Split node, because it is that node underneath. The correction is a convex interpolation between the frequency result and the input candidate, so mathematically it cannot produce a stronger subtraction than the candidate itself.
The input/output shape
Same skeleton as Frequency Split: source_frames, candidate_frames, used_skin_mask required; optional audio. Outputs specular_frequency_candidate, source, selected, audio, effective_mask, rejected_mask, difference, report_json. And the same fail-closed personality: source stays selected until you review and flip accept_candidate.
Why you'd reach for it
If you're doing oil control on footage with real shine - forehead, nose bridge, cheeks - the plain split is the wrong tool because it eats the highlight correction along with the pores. This node is the middle ground: it keeps the candidate's darker-highlight intent on exactly the pixels that had bright detail, while the mask exterior, alpha, auxiliary channels, and audio all stay bit-exact.
Honest expectations
T8's own verification is refreshingly unimpressed with itself here. On a six-frame calibration, the ordinary/0.35/0.65 routes all passed the guards but the labelled contact sheet "still looked subtle," and the harder oil-control parameter run retained only ~25–32% of the raw average treatment while protecting texture. So: this is a conservative highlight-restoring tool, not a "make this face matte" button. If you're after dramatic de-shining you'll be fighting the texture guards the whole way, and that's by design - the author would rather you under-treat than wipe the pores.
Installing it
Ships in the comfyui-minimax-h3-audio-T8 pack (ComfyUI Manager search "MiniMax H3 Audio T8", or clone https://github.com/T8mars/comfyui-minimax-h3-audio-T8.git into custom_nodes, update ComfyUI first, restart). No extra models; pure CPU post-processing.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| source_frames | IMAGE | — | |
| candidate_frames | IMAGE | — | |
| used_skin_mask | MASK | — | |
| low_frequency_strength | FLOAT | 1.000–1 | — |
| source_detail_gain | FLOAT | 1.000–1.25 | — |
| separation_radius_percent | FLOAT | 3.000.1–5 | — |
| maximum_radius_px | INT | 321–128 | — |
| highlight_detail_suppression | FLOAT | 0.650–1 | Restores the input candidate only where bright positive detail was lost. The correction cannot pass beyond that candidate; 0 is exact ordinary split. |
| highlight_start | FLOAT | 0.600–0.95 | — |
| highlight_end | FLOAT | 0.920.05–1 | — |
| positive_detail_threshold | FLOAT | 0.0040–0.05 | — |
| treatment_intent_scale | FLOAT | 0.00400.0001–0.1 | — |
| maximum_specular_delta | FLOAT | 0.0400–0.1 | Hard per-pixel luma correction cap before Texture Guard. |
| minimum_mask_area | FLOAT | 0.00010–0.25 | — |
| maximum_mask_area | FLOAT | 0.500.05–1 | — |
| maximum_new_clipped_fraction | FLOAT | 0.00050–0.25 | — |
| clipping_epsilon | FLOAT | 0.00390.0001–0.05 | — |
| chunk_frames | INT | 41–32 | — |
| accept_candidate | BOOLEAN | false | The source stays selected until the labelled candidate is reviewed. |
| audioopt | AUDIO | — |
Outputs (8)
| Name | Type | Description |
|---|---|---|
| specular_frequency_candidate | IMAGE | — |
| source | IMAGE | — |
| selected | IMAGE | — |
| audio | AUDIO | — |
| effective_mask | MASK | — |
| rejected_mask | MASK | — |
| difference | IMAGE | — |
| report_json | STRING | — |