Mesh Bake Maps
Normal and AO maps from high-poly to low-poly
- model
- high_poly
- model
- maps
Mesh Bake Maps is where the geometry workflow in ComfyTV gets its professional finish. Decimating a model makes it light and game-ready, but it throws away all the surface detail - the dents, scratches and creases that only exist in the high-poly version. The classic 3D answer is baking: render that detail into texture maps on the low-poly model's UVs so the light still catches every bump. That's this node's entire job, and it's the step that turns an ugly-but-fast mesh into one that renders like the original.
ComfyTV is the canvas-style app layer on ComfyUI where every operation is its own node. This stage sits in the 3D category, in the geometry workshop alongside Mesh Ops, Mesh Boolean and Mesh Primitive.
How it works. You give it a UV-unwrapped low-poly model and a high_poly source of detail, and it bakes two kinds of maps. The normal map captures the high-poly surface direction per texel (tangent-space, glTF/OpenGL +Y convention) - this is what fakes all the geometry you decimated away. The ambient occlusion map captures which crevices are shadowed (white = open, dark = in the cracks) and gets packed into the glTF ORM occlusion texture so your renderer reads it natively. cage_distance controls the surface-search band for the normal bake as a fraction of the bounding-box diagonal, ao_samples is how many occlusion rays per texel, and ao_strength scales how dark the AO goes.
The inputs that matter. The force_run_token, project_id and parent_output_id inputs are internal plumbing. The real set:
model- the UV-unwrapped low-poly to bake onto (required).high_poly- the mesh the detail comes from (the one your low-poly was decimated from).bake_normal/bake_ao- which maps to produce. Both on by default.resolution- baked map size, 256–4096 (step 256), default 1024.cage_distance- 0.001–0.5, default 0.05. Raise it if you see missing patches (the baker didn't reach the detail); lower it if it's grabbing across gaps.ao_samples- 4–512, default 64. More = smoother AO, slower.ao_strength- 0–2, default 1. >1 darkens, <1 lightens.
Outputs are model (the low-poly with its baked maps attached, ready for a render stage) and maps (a COMFYTV_IMAGE contact sheet of the baked maps, so you can eyeball them before rendering).
Install. Install the pack once:
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Restart ComfyUI (full restart, not a browser refresh) and the stage appears under ComfyTV → 3D. ComfyUI Manager - search "ComfyTV" - works too. Zero Python dependencies (the pack's pyproject.toml dependency list is empty) and no model files - baking is geometry math on your GPU. Desktop/multi-install users: clone into the running instance's path from the startup log or the node won't register.
Where people get burned. Baking onto a model with no or overlapping UVs is the classic failure - the baker needs a proper unwrap, so run the unwrap op in Mesh Ops first if you're not sure. Second: cage_distance is the knob people don't expect to matter. Black patches on the normal map = the cage didn't reach the high-poly surface (raise it); smeared lighting = it grabbed across a gap (lower it). And if the high-poly and low-poly are wildly different in shape, no bake will save you - the two meshes have to roughly match, since the normal map only encodes surface direction, not geometry. For AI-generated meshes specifically, remember the 3D-generation reality: these bakes work best when the low-poly is a clean retopo of the original, not a decimated wreck of it.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| bake_normal | BOOLEAN | true | Bake a tangent-space normal map (glTF/OpenGL +Y) capturing high-poly detail lost to decimation. |
| bake_ao | BOOLEAN | true | Bake an ambient-occlusion map (white = open, dark = crevices), packed into the glTF ORM/occlusionTexture. |
| resolution | INT | 1024256–4096 | Baked map resolution. |
| cage_distance | FLOAT | 0.0500.001–0.5 | Normal bake — surface search band as a fraction of the bbox diagonal. Raise for missing patches; lower if it grabs across gaps. |
| ao_samples | INT | 644–512 | AO rays per texel. More = smoother, slower. |
| ao_strength | FLOAT | 1.000–2 | Scales the occlusion. >1 darkens, <1 lightens. |
| modelopt | COMFYTV_MODEL | UV-unwrapped low-poly to bake onto. | |
| high_polyopt | COMFYTV_MODEL | High-poly source of the detail (the mesh the low-poly was decimated from). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| model | COMFYTV_MODEL | — |
| maps | COMFYTV_IMAGE | — |