I have a material that calculates a 2D vector to use as the UV lookup for a texture. If that 2D vector is outside of the [0,1] range, I want to use black for the texture (not tile or clamp the texture edges). I can do it with four If
nodes, but that seems really gross.
Is there a more elegant way to achieve my (rather simple) goal than the monstrosity I’ve made here?
Two coworkers gave me good tips, and emphasized the importance of removing if
statements from materials. (Since every conditional branch is calculated, and then unused ones are discarded.)
One solution was to dynamically generate a texture that is pure white inside the [0,1] square, black elsewhere, and multiply the texture by this as a color mask. Generating that texture was some impressive trickery:
The other solution, which I chose to use, was to create a black texture with a 1px white border at the edges of the alpha channel, and then use that to lerp to black at the edges. I initially tried setting this control texture to clamp
, but was unable to make that work. (No idea why.) Instead, I clamped the generated UVs to 0,1 so that they would just repeat the edge color everywhere.
In addition to being quite simple, this second solution has the added benefit of being able to pick any color (or texture) you want for the out-of-bounds region. The only downside is that the masking texture will throw away the very edges of your main image. The amount that is discarded depends on the size of your masking texture. (A 4x4 image with 1px white borders will throw away 25% on each edge; a 512x512 texture with 1px borders will only throw away 0.2% on each edge.)