UltraTex Sampler
Six 2K views, and the settings that decide how long you wait
- model
- vae
- positive
- prep
- negative
- init_views
- keep_mask
- views
- masks
- atlas
This is the node the whole pack exists for: put an untextured mesh on one side, get six 2048² views of a textured one out the other, which UltraTex Bake Texture then back-projects into a UV map. It's also, by a wide margin, the slowest thing in your graph.
Two things make it unusual. It doesn't generate an image - it generates a 2×3 atlas of six views in one shot, and its conditioning isn't a prompt but two references: the world-normal G-buffer atlas and your aligned reference photo. And it's running a task LoRA on FLUX, so the sampler is doing geometry-aware multi-view prediction with the canonical TexVerse camera layout hard-coded into what the weights expect.
How it works
The target latent is the atlas; the two reference atlases are packed into the same sequence with their own position ids. Then UltraTex's training-time trick - background token dropping - throws away every token outside the object's silhouette (masks at latent resolution, dilated a pixel, original positions kept). Since a 2048 view of a character on a blank background is mostly empty, that's where the huge speedup comes from, and it's on by default because it's what the model was trained with. Turning it off isn't a quality option, it's a slower way to do the same maths.
Sampling is Euler over a UNO time-shifted schedule, and wall time is linear in steps. Background latents are the encoding of a black image, and the decoded views come back composited on white, with the foreground masks returned alongside.
The inputs worth setting
model must be FLUX.1 or FLUX.2 with an UltraTex LoRA applied - anything else raises a clear TypeError naming the class it got. vae is the matching VAE, and you want it going through UltraTex Foreground VAE Decoder first. positive is an UltraTex Text Encode with an empty box; leave negative disconnected so the sampler can skip CFG.
resolution is per view, and must be a multiple of 16 - the node checks and raises rather than silently rounding. 2048 is what UltraTex is trained at. steps defaults to 25 and that's the trained-ish regime; guidance is distilled guidance on FLUX.1 (2 = balanced; 1 hugs the reference colours and goes soft; 4 is the model's own default and gets crisper and more saturated) and only becomes text CFG on FLUX.2 when you connect a different negative.
Then the performance knobs, all of which default sensibly:
attention = ultratex_sparseruns UltraTex's own block-sparse top-k attention, vendored from SLA as a Triton kernel. It's what the model was trained with, and the reason a 32k-token step is bearable;sparse_topk = 0.2is the fraction of key blocks each query attends to, and 0.1 is faster and may cost detail. Without Triton installed (usetriton-windowson Windows) it logs a warning and falls back to ComfyUI's attention - still correct, just slower.token_chunk = 8192computes the DiT MLPs in chunks. Identical results up to bf16 rounding, and it's what keeps the whole model resident on a 16GB card at 2048.memory_factor = 0means auto - 12 with chunking, 28 without; raise it if you're hitting out-of-memory, which is literally what the tooltip says.
On an RTX 3080 laptop with fp8 Klein base 9B and 25 steps: about 118 s of sampling at 1024 (~2.3 min for the whole workflow), 472 s at 2048 (~9.6 min). Bulky meshes are worse than that, because more foreground tokens survive the drop.
Outputs
views is six images in a fixed order - front, left, back, right, top, bottom - and that order is not cosmetic: the bake maps view 0 to the front camera, view 4 to the top, and so on. masks is the six silhouette masks. atlas is the 2×3 contact sheet, which is the fastest way to eyeball whether the run is coherent - if the front view has a face and the back view also has a face, stop and fix your prep or your reference before baking.
The optional inputs
denoise, init_views and keep_mask are the second-pass controls and they only work together: init_views is six starting views (SDEdit) from UltraTex Render Views, and denoise = 1 ignores them while anything lower keeps part of the schedule. denoise below 1, or a keep_mask on its own, raises with "denoise < 1 and keep_mask need init_views". keep_mask is a per-token RePaint pull-back, so kept regions land exactly on the init content.
Note what you can't do: plug pass one's views into pass two. They were shot on the other rig, and the sampler runs an alignment check that measures content outside the new silhouettes and refuses above 5%.
Install
Manager → ComfyUI-UltraTex, or:
cd ComfyUI/custom_nodes
git clone https://github.com/visualbruno/ComfyUI-UltraTex
Requirements: trimesh, moderngl, xatlas, scipy, plus Triton for the sparse attention. Weights: FLUX.2-Klein-base-9B (the base, not the distilled Klein - this is a fine-tune, and base is the fine-tunable one), the Qwen3-8B text encoder loaded as type flux2, flux2-vae.safetensors, and the albedo/MR LoRAs from the UltraTex release. Stock ComfyUI loaders handle the model, VAE and CLIP, so fp8 weights, GGUF and ComfyUI's offloading all apply.
Gotchas
- The usual one: if it's unreasonably slow, check the log for how many tokens went in, the attention backend and the steps actually run. A 60k-token bulky mesh at 2048 is a different league to a slim one, and laptops thermal-throttle hard over a ten-minute run. Setting
ULTRATEX_PROFILE=1before launching ComfyUI logs a per-step breakdown - turn it off afterwards, it synchronises CUDA. - Seeds aren't per-view. One seed, all six views.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | FLUX.2-Klein base 9B or FLUX.1-dev with an UltraTex LoRA applied. | |
| vae | VAE | Matching VAE, ideally with the UltraTex foreground decoder applied. | |
| positive | CONDITIONING | CLIP Text Encode with an EMPTY prompt (UltraTex is image-guided). | |
| prep | ULTRATEX_PREP | — | |
| resolution | INT | 2048256–4096 | Per-view resolution. UltraTex is trained at 2048. |
| steps | INT | 251–200 | — |
| seed | INT | 420–18446744073709550000 | — |
| guidance | FLOAT | 2.00–30 | FLUX.1: distilled guidance. 2 = balanced; 1 = colours closest to the reference but softer details; 4 = UltraTex's FLUX.1 default, crisper but more saturated. FLUX.2: text CFG scale, only used when a different negative prompt is connected (UltraTex uses 4). |
| drop_background_tokens | BOOLEAN | true | UltraTex Background Token Dropping (huge speed-up, as trained). |
| negativeopt | CONDITIONING | — | |
| memory_factoropt | FLOAT | 00–200 | VRAM kept free for activations, per token (x hidden x dtype). 0 = auto (12 with token chunking, 28 without). Raise it on out-of-memory errors. |
| attentionopt | COMBO | ultratex_sparse | ultratex_sparse: UltraTex's block-sparse top-k attention (Triton), the attention UltraTex was trained with; ~4x faster than flash attention at 2048. comfy_default: dense attention from ComfyUI's backend. |
| sparse_topkopt | FLOAT | 0.200.05–1 | Fraction of key blocks each query block attends to (UltraTex default 0.2; 1.0 = dense). |
| token_chunkopt | INT | 81920–131072 | Compute the DiT MLPs in chunks of this many tokens to cut activation memory (0 = off). Same result, keeps the whole model on the GPU at 2048. |
| denoiseopt | FLOAT | 1.000–1 | With init_views: 1 = from pure noise, lower keeps more of the init views (only the last part of the schedule runs). ~0.6 for a refining second pass. |
| init_viewsopt | IMAGE | 6 starting views (UltraTex Render Views) for a refining second pass. | |
| keep_maskopt | MASK | 6 masks (UltraTex Render Views): 1 = keep the init content exactly, 0 = regenerate. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| views | IMAGE | — |
| masks | MASK | — |
| atlas | IMAGE | — |