๐ Floor Warp V7 (JITDOT)
Tile a floor texture that actually follows the camera angle
- texture
- floor_mask
- warped_texture
The fiddly part, automated
The hard bit of "re-flooring" a room photo in ComfyUI was never generating the tile texture - it was getting it to lie flat on the floor plane. A bare texture pasted over a floor mask ignores perspective, so it reads instantly as a sticker. Floor Warp V7 exists to kill that problem: you give it a material texture and a mask of the floor, and it works out the floor's geometry, warps the texture to match the camera, and hands you back something you can drop straight into your render.
It's aimed at the interior-design niche - swap the vinyl on a kitchen floor, preview a wood plank pattern, redo a room render before you buy anything. It's a small, clearly Korean-flavored pack (the README is in Korean and it's the author's personal V7 of a project), so don't expect a support forum or a big install base. What you get is one focused node that does the geometry so you don't have to reach for an affine/perspective node and fiddle with 16 hand-placed points. That trade is usually worth it.
How it works
The node is plain OpenCV under the hood - no models, no downloads, nothing that runs on your GPU in an interesting way. The floor_mask you feed in (the author's README assumes a SAM2 floor mask) gets thresholded, and OpenCV finds the largest contour, builds its convex hull, and approximates it down to a four-corner quad. That quad is the floor you're warping onto.
Then it gets clever about the camera. From the two side edges of the quad it computes a vanishing point; depending on where that lands relative to the floor, it derives a texture rotation angle (clamped to ยฑ35ยฐ, snapped to half-degrees, with a 1ยฐ dead zone so near-flat floors don't get rotated by noise). The texture is tiled by tile_x ร tile_y, rotated to match the detected angle, then run through cv2.warpPerspective from the texture corners onto the quad corners. Finally the result is multiplied by the mask so only the floor area survives, on a black background, at the scene's full resolution. There's a 4096px cap on the tiled texture before warping - a guard against OpenCV's 32767px limit when you crank the tiles up.
The inputs that matter
- texture - your material image. Ideally an already cut-out tile/wood texture.
flip_horizontalmirrors it if the pattern's grain faces the wrong way. - floor_mask - the SAM2 mask of the floor region. The whole thing hinges on this being a clean single region; the node grabs the largest contour and takes its convex hull, so an L-shaped room or heavy furniture occlusion will stretch the quad over stuff that isn't floor.
- tile_x / tile_y - horizontal/vertical repeat count, default 3 each. The bigger the repeats, the smaller each tile appears on the floor.
- expand_px (default 15) - pushes each quad corner outward from the centroid. You'll want a small value so the warped texture bleeds past the mask edge instead of leaving a sliver of unmasked floor. This is the one beginners skip and then blame the node for.
- texture_angle - 0 means auto-detect. Set anything with magnitude โฅ 0.1 and it overrides the vanishing-point logic. If the pattern comes out sideways, dial this manually.
The single output, warped_texture, is a scene-resolution image of the texture warped and masked onto black. It is not composited over your photo - you wire it into an Image Blend / mix node, or paste it using the mask, to put it under your scene. Pair that composite with a light inpaint or ControlNet pass and you get believable lighting; skip it and the re-floor will look cleaner than the room around it, which is the tell people notice.
Installing it
ComfyUI Manager, search comfyui-floor-warp-v7, install, restart. Or, if you prefer the terminal:
cd ComfyUI/custom_nodes
git clone https://github.com/jessie-jitdot/comfyui-floor-warp-v7
then restart ComfyUI. The node shows up as ๐ Floor Warp V7 (JITDOT) under JITDOT/Floor. There's no requirements.txt - it only needs torch, numpy, and opencv-python (cv2), all of which ship with ComfyUI already. No model files to chase, which is a genuinely nice change of pace.
Where people get burned
Mostly the mask. A floor mask with holes or a second object caught in it (a rug, a shadow read as floor) confuses the largest-contour logic, and the convex hull will happily bridge across a sofa base. Keep the mask to the floor and only the floor. Also remember the output is a black-background cutout, not a finished composite - plenty of people wire it straight to a preview, see black, and assume it's broken. It's not; it's just waiting for the blend step.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| texture | IMAGE | โ | |
| floor_mask | MASK | โ | |
| tile_x | INT | 31โ30 | โ |
| tile_y | INT | 31โ30 | โ |
| flip_horizontal | BOOLEAN | false | โ |
| expand_px | INT | 150โ50 | โ |
| texture_angle | FLOAT | 0.0-45โ45 | โ |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| warped_texture | IMAGE | โ |