Texture Sampler
Make a UV gradient actually do something — sampling a texture through coordinates
- texture
- uvmap
- IMAGE
A UV map alone is just a gradient - pretty, but useless until something reads it. Texture Sampler is the reader. It takes a UV map (the R/G channel gradients from the pack's UV Coordinate Generator, or anything you've warped since) and uses it to rearrange a real image. This is the node that turns the pack's "texture" idea into actual image warping.
Think of it as a lookup table: for each output pixel, the UV map says "go get the pixel at coordinate (U, V) from the texture." The texture is the pool of source pixels, the UV map is the instruction sheet, and the result is a resampled image. Pan the UV and the texture appears to slide; rotate it and the texture spins; feed it a distorted map and you get warps that would take ten hand-built ComfyUI graph nodes otherwise.
How it works
Under the hood it's PyTorch's F.grid_sample, the same workhorse used for spatial transformer networks. The node:
- Checks your texture is a
[B, H, W, 3]tensor and the UV map is[1, H, W, 3]. - Resizes the texture to match the UV map's dimensions if they differ - using your chosen interpolation mode, so the resample is smooth rather than blocky.
- Converts the UV coordinates from 0–1 to the -1–1 space
grid_sampleexpects and runs it withpadding_mode='border', meaning out-of-bounds coordinates clamp to the nearest edge pixel instead of wrapping or going black.
The interpolation enum - bilinear or bicubic (default) - picks the resampling quality. Bicubic is sharper; bilinear is faster and slightly softer. For coordinate data that's been rounded by an intermediate step, bilinear is usually forgiving enough that you won't notice the difference.
Inputs
texture- the image you're sampling from.uvmap- the coordinate field doing the warping.interpolation- bilinear or bicubic.
Single IMAGE output.
The canonical chain
The pattern that makes the whole pack click:
UV Coordinate Generator ──> Texture Sampler ──> your warped image
└── (optional) Panner / Rotator / CustomScript-NumPy between
Insert a Panner or Rotator between the generator and the sampler and you're animating the lookup coordinates, which reads as the texture moving. That's the cheapest "moving material" trick in the pack.
Install
ComfyUI Manager → search "FuncAsTexture", or:
cd ComfyUI/custom_nodes
git clone https://github.com/CoiiChan/ComfyUI-FuncAsTexture-CoiiNode
# restart ComfyUI
No model files, no dependency install - it uses only what ComfyUI already ships. Category: FunctionAsTexture.
Where people get burned
- The UV map's blue channel is ignored. Only R and G are read as coordinates, so a UV map that has junk in the blue channel still works fine. Don't let that surprise you when you inspect the map.
- Out-of-range coordinates clamp to the border rather than tiling. If you want a repeating texture, you need a UV map whose values stay 0–1 - the UV Coordinate Generator's
scalegives you repeats inside 0–1, but arbitrary math can push values past 1, and then you get stretched edge pixels, not seamless tiling. - Resolution mismatches are handled, but cost quality. If your texture is much larger than the UV map, the downsize is where you lose detail. Size the UV map to match what you actually need.
It's the node that makes the pack's texture system feel real. The math is one function call deep, but it's the right function, and having it exposed as a clean IMAGE-in/IMAGE-out node beats hand-rolling a grid sampler every time.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| texture | IMAGE | — | |
| uvmap | IMAGE | — | |
| interpolation | COMBO | bicubic | 2 options: bilinear, bicubic |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |