Nodes/Jovimetrix/πŸ”† Pixel Shader (jov)
ComfyUI Node

πŸ”† Pixel Shader (jov)

Write your own per-pixel math, no image required

By AmoranoΒ·Created 3 years agoΒ·Updated 12 months agoΒ· 397
πŸ”† Pixel Shader (jov)
    • image
    • mask
    β—„R1. - np.minimum(1, np.sqrt((($u-0.5)**2 + ($v-0.5)**2) * 2))β–Ί
    β—„Gβ€”β–Ί
    β—„Bβ€”β–Ί
    β—„width256β–Ί
    β—„height256β–Ί

    Pixel Shader is Jovimetrix's "make an image out of pure math" node. You write one small numpy expression per color channel, give it a canvas size, and it evaluates those expressions at every pixel to generate an image and a mask. No input image needed - the output comes entirely from the formulas you type. Think of it as a procedural texture generator, with the shader concept done in numpy instead of GLSL.

    Here's the trick that makes it work. In each channel's expression you have $u and $v, the normalized coordinates of the current pixel, both running 0 to 1 across the canvas. The default Red channel is a textbook example:

    1. - np.minimum(1, np.sqrt((($u-0.5)**2 + ($v-0.5)**2) * 2))
    

    That's a radial gradient - distance from the center of the frame, so a bright blob that fades to black at the edges. The R, G, and B inputs are each a multiline string holding one expression like that; whatever numpy returns per pixel becomes that channel. Leave a channel empty and it contributes nothing. width and height set the canvas (32–8192). Two outputs come out: image (the rendered RGB) and mask (a single-channel version), so you can use the result either as a texture or as a mask without a conversion node.

    So what can you actually do with it? Any function of pixel position is fair game - stripes with np.sin($u * freq), a checkerboard from sign-flipping the coordinates, vignettes from the radial formula, masks that are smooth instead of binary. If you've ever thought "I wish I had a soft-edged gradient mask right here," this is the node. Pair it with a THRESHOLD or a TRANSFORM and you can bend the output into most mask shapes you'd want.

    Now the honest part. This is a legacy node - the lowercase "(jov)" in the name dates it to older Jovimetrix builds, and it's not in the current pack source. The GLSL shader era of the pack got spun out into the separate Jovi_GLSL package in v2.0, and this numpy-style shader didn't survive the cleanup as a supported node. If you loaded an old workflow and this node is missing, that's why. It still works if you pin an older Jovimetrix version, and the math here is the same idea you'd write with a real GLSL node from Jovi_GLSL - just CPU-side and slower.

    If you want it, you'll be installing the whole pack. ComfyUI Manager β†’ search "Jovimetrix", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Amorano/Jovimetrix.git
    pip install -r Jovimetrix/requirements.txt
    

    Dependencies are the pack-wide set (numpy, opencv-contrib-python, Pillow, matplotlib, the cozy-comfyui helpers). And a warning that applies to every node in this pack: Jovimetrix explicitly warns not to update past 1.7.48 if you rely on the migrated GLSL/streaming nodes - the pack splits, not just features, so version-pin deliberately when you need an old node like this one.

    CategoryJOVIMETRIX πŸ”ΊπŸŸ©πŸ”΅

    Inputs (5)

    NameTypeDefaultDescription
    RoptSTRING1. - np.minimum(1, np.sqrt((($u-0.5)**2 + ($v-0.5)**2) * 2))β€”
    GoptSTRINGβ€”
    BoptSTRINGβ€”
    widthoptINT25632–8192β€”
    heightoptINT25632–8192β€”

    Outputs (2)

    NameTypeDescription
    imageIMAGEβ€”
    maskMASKβ€”