Nodes/Comfy-LFO/LFO_Triangle
ComfyUI Node

LFO_Triangle

Sine's straight-edged cousin for even ramps

By richinsley·Created 3 years ago·Updated 2 years ago· 5
LFO_Triangle
    • FLOAT
    position0.000
    phase_offset0.500
    frequency1.000
    amplitude1.000
    offset0.000

    LFO_Triangle is the sine wave's linear sibling. Same smooth start and end, same oscillation between a min and a max - but instead of rounding off at the top and bottom, it travels at a constant speed, hits the exact limit, and turns around. If sine feels like it lingers too long near its peaks, this is the fix.

    For ComfyUI that means a value that ramps evenly up and evenly back down, spending equal time rising and falling. That's a genuinely useful shape: motion scale, ControlNet strength, or a denoise that should spend the same amount of time climbing as descending - not the "hang around the edges" feel a sine gives you.

    How it works

    The pack's lfonodes.py keeps it to a couple of lines:

    phase = (position * frequency) - int(position * frequency)   # the fractional part
    return offset + amplitude * (2 * abs(2 * phase - 1) - 1)
    

    The phase is just the fractional part of position * frequency, so it wraps cleanly from 1 back to 0 each cycle. That 2*abs(2*phase-1)-1 shape is the classic triangle: it starts at -1, climbs linearly to +1 halfway through the cycle, then descends linearly back to -1. Scale by amplitude, shift by offset, and the output sits in offset - amplitude to offset + amplitude.

    Like every node in this pack, it's a pure function of position. There's no built-in clock - the output only changes when the position input changes. Feed it a frame counter or a batch index if you want actual motion; wire nothing and it returns the same value every run. This catches people out every time, so let me repeat it: the node doesn't animate itself, you have to drive position.

    The inputs

    Five float inputs, same family as its siblings:

    • position - the driver. This is what you wire to something that advances over the run.
    • frequency - cycles per unit of position; your speed knob. Default 1.
    • amplitude - how far the wave swings from center. Default 1.
    • offset - the midpoint of the oscillation. Default 0.
    • phase_offset - shifts where in the cycle the wave starts (default 0.5), so you can start at a peak, a valley, or mid-ramp.

    Output is a single FLOAT. It wires straight into any float input - KSampler denoise, ControlNet strength, IPAdapter weight, AnimateDiff motion scale. Same pattern the audio-reactive AnimateDiff crowd uses, just deterministic and with no audio file needed.

    Install and troubleshooting

    The pack is one small Python file with no dependencies and no model downloads, so install is a two-liner from your ComfyUI folder:

    cd custom_nodes
    git clone https://github.com/richinsley/Comfy-LFO.git
    

    Restart ComfyUI and the node appears under the LFO menu (ComfyUI Manager can also find the pack by searching "Comfy-LFO"). No requirements to satisfy, nothing to download.

    If your output never moves, your position isn't moving - that's the whole failure mode for this pack. If the node is missing after install, you didn't restart. If you were hoping it would generate frames for you, that's not this node's job; it produces a number and you have to wire it somewhere that matters.

    There's barely any community chatter about this pack, which is the right amount of chatter for five tiny math nodes. When a workflow needs an even, predictable ramp - not the rounded, "hangs out at the extremes" sine - LFO_Triangle is the one.

    CategoryLFO

    Inputs (5)

    NameTypeDefaultDescription
    positionFLOAT0.000
    phase_offsetFLOAT0.500
    frequencyFLOAT1.000
    amplitudeFLOAT1.000
    offsetFLOAT0.000

    Outputs (1)

    NameTypeDescription
    FLOATFLOAT