Position Pass Splitter (MEC)
Slice a 3D scene by world position, straight from the render pass
- position
- x_mask
- y_mask
- z_mask
Rendering a position pass (world position stored as RGB) is one of those moves that unlocks a whole category of comp tricks: depth-aware grading, matte painting, isolating a region of a 3D scene by actual coordinates instead of hand-drawn shapes. The catch is that a position pass is three channels of numbers, and pulling a usable mask out of it used to mean math nodes or a trip to another app. Position Pass Splitter (MEC) collapses that into one node: feed it the pass, get X, Y, and Z masks.
What the pass encodes
The mechanism is honest and simple. The pass encodes position as RGB - X in the red channel, Y in green, Z in blue. The node takes each channel and normalizes it to [0,1]: either by auto_normalize (per-frame min/max, so you always get full range regardless of your scene scale) or by the manual x_min/x_max/y_min/y_max/z_min/z_max bounds you set. That normalized channel becomes a mask: where the channel value falls in range you get white, where it's out of range you get black, and in between you get a soft gradient you can threshold or blur downstream.
Auto or manual ranges
The one decision that matters is auto_normalize. Leave it on (the default) and the node scales each channel to the pass's own min/max - perfect for a quick "show me this scene by depth" and immune to scene scale. Turn it off and you take manual control of each axis's range, which is what you want when you're doing deliberate region selects: "everything between world-X 5.0 and 12.0" as a precise mask, not a relative one. Manual mode needs meaningful bounds, though - defaults are 0 to 1, which on a real scene range of hundreds of units will clip everything to a single value, so set your ranges from the actual pass.
The outputs and the uses
Three outputs: x_mask, y_mask, z_mask - all MASK type, all directly wireable. The uses write themselves: z_mask is your depth matte for selective grading or atmospheric effects; x_mask/y_mask let you isolate a horizontal band or vertical slice of a scene for targeted color work; stack two of them through a Mask Composite to get a "this box in 3D space" selection for inpainting or relighting. It's one of those small nodes that turns a data pass into a matte kitchen, and it runs in pure tensor math - instant, no models.
Install and input caveats
Install is the pack: clone Code2Collapse/ComfyUI-CustomNodePacks into ComfyUI/custom_nodes (or "CustomNodePacks" in ComfyUI Manager), restart, find it under MaskEditControl/Geometry next to Normal → Curvature, its sibling render-pass utility. Needs only the pack's opencv-python/scipy requirements.
Two caveats, both about input, not the node: it wants a genuine world-position pass (typically linear, often from a render engine's P/RP channel) - if you feed it a color pass it will happily normalize whatever it gets and hand you meaningless masks; and if your renderer stores position differently (e.g. camera-space or half-float with odd scaling), set auto_normalize on first and check the outputs before trusting manual ranges.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| position | IMAGE | — | |
| auto_normalizeopt | BOOLEAN | true | — |
| x_minopt | FLOAT | 0.00-1000000–1000000 | — |
| x_maxopt | FLOAT | 1.00-1000000–1000000 | — |
| y_minopt | FLOAT | 0.00-1000000–1000000 | — |
| y_maxopt | FLOAT | 1.00-1000000–1000000 | — |
| z_minopt | FLOAT | 0.00-1000000–1000000 | — |
| z_maxopt | FLOAT | 1.00-1000000–1000000 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| x_mask | MASK | — |
| y_mask | MASK | — |
| z_mask | MASK | — |