Nodes/ꘇ Genereti/ꘇ top.cornerpin
ComfyUI Node

ꘇ top.cornerpin

Stick a texture onto four points, perspective included

By languel·Created about a month ago·Updated 3 days ago· 1
ꘇ top.cornerpin
  • image
  • image
◄tl_x0.00►
◄tl_y0.00►
◄tr_x1.00►
◄tr_y0.00►
◄br_x1.00►
◄br_y1.00►
◄bl_x0.00►
◄bl_y1.00►

Four-point pinning is one of those operations that's trivial in a compositor and missing everywhere else. top.cornerpin maps your image onto a quadrilateral described by four normalized destination corners - true projective mapping, not a pair of stretched triangles - and everything outside the quad comes back transparent. Reach for it when you need to put a render into a screen in a photo, fix keystone on a projection, or paste a texture onto a surface that's at an angle.

That's the classic "I left ComfyUI for a compositor in After Effects" job. The KB's reading of this layer is that the primitives are old and cheap but the packaging is uneven, so having the pin as a node is the whole reason to care.

How it works

It's a real homography. The node solves for the 8 unknowns of the projective transform that maps the destination quad back to the source unit square, then samples the source through it, so straight lines stay straight and the interior stretches the way a perspective transform should. Sampling is premultiplied (colour × alpha, interpolate, divide back), which is why the edges of a pinned cut-out don't darken into a fringe. Corners are normalized, in clockwise order: TL, TR, BR, BL.

If your four destination points are degenerate - three corners colinear, two corners identical - the solve fails and the node reports an error rather than emitting garbage. The message is literally about the quadrilateral being non-degenerate.

The inputs that matter

Eight floats: tl_x, tl_y, tr_x, tr_y, br_x, br_y, bl_x, bl_y. The defaults (0,0 / 1,0 / 1,1 / 0,1) reproduce the frame unchanged, so you're always nudging from identity. Values are normalized to the image - 0.5 is the middle - and the ±4 range lets you push corners clean off the canvas, which is sometimes what you want when only part of a surface is visible.

In practice: drag the four corners toward the thing in your photo, then nudge. Output is a single image with transparent surroundings, so top.composite over the photo is the other half of the trick.

Install

ComfyUI Manager → search ꘇ Genereti → install, or:

git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt

Restart Comfy and refresh the page. Requirements are just a frontend pin, and none of the pack's texture nodes downloads a model or calls anything remote. The node appears as ꘇ top.cornerpin in Genereti / TOP. That leading character is a script glyph, not a typo, and it sorts to the bottom of the list - search genereti or cornerpin.

Traps

Numeric only, for now. The author's own docs say "Controls are numeric for now" - there's no on-canvas corner widget you can drag. You're dialling numbers, which is fine for a one-off and annoying for six shots. A vision-model node that spits out four corners for you is the obvious pairing.

No detail created. It samples the source at source resolution and reprojects. Pinning a small texture onto a big surface gets you a soft, upscaled-looking result. Order matters: pin first, then do your cleanup/enlarging.

Corner order. Going anticlockwise, or starting at TR, gives you a mirrored pretzel. TL/TR/BR/BL, clockwise, every time.

Queue is the float path. In live mode the chain stays on the browser GPU (WebGPU required), while Queue runs the PyTorch version. Live intermediates are 8-bit, Queue keeps floats, so the two are close but not identical.

The pack ships labelled super-alpha / early classroom testing. Back up workflows you care about.

CategoryGenereti / TOP

Inputs (9)

NameTypeDefaultDescription
imageIMAGE—
tl_xFLOAT0.00-4–4—
tl_yFLOAT0.00-4–4—
tr_xFLOAT1.00-4–4—
tr_yFLOAT0.00-4–4—
br_xFLOAT1.00-4–4—
br_yFLOAT1.00-4–4—
bl_xFLOAT0.00-4–4—
bl_yFLOAT1.00-4–4—

Outputs (1)

NameTypeDescription
imageIMAGE—