LFO_Sine
Make your ComfyUI parameters breathe with LFO_Sine
- FLOAT
The name is not marketing. LFO_Sine is a low-frequency oscillator, and its entire job is to hand you one smoothly oscillating number you can plug into almost any float input in ComfyUI. Want denoise strength to pulse in a loop instead of sitting at a fixed 0.5? Want ControlNet weight to breathe in and out across a batch? That's this node.
No audio, no API, no model file, no key. It's a math function dressed as a node, and that's exactly what makes it so harmless and so handy.
How it works
Under the hood it's three lines of arithmetic. Comfy-LFO's lfonodes.py computes:
phase = (position + phase_offset) * frequency * 2 * math.pi
return offset + amplitude * math.sin(phase)
So the output is offset + amplitude * sin(...), which means it always lands somewhere in the range offset - amplitude to offset + amplitude. Frequency 1, amplitude 1, offset 0 gives you a value swinging between -1 and 1 for every unit of position. Bump amplitude to 0.5 and offset to 0.75 and you're waving between 0.25 and 1.25.
The catch you need to internalize: there's no internal clock. This is a function of position, not a self-running oscillator. If position never changes, the output never changes. To actually get motion, feed position from something that advances between executions - a frame counter from an animation scheduler, a batch index, whatever your workflow uses to count. Leave position unwired at its default and the node will just sit there returning the same value every run, which confuses exactly the people who expected a magic wobble.
The inputs that matter
Five inputs, all floats, all with a 0.001 step. You'll really touch three of them:
- frequency - how many full cycles happen per unit of
position. Default 1. This is your "speed" control. - amplitude - how far the wave swings from center. Default 1.
- offset - the midpoint the wave oscillates around. Default 0.
- position - the driver. Wire a changing value here.
- phase_offset - where in the cycle you start, so you can shift a sine so it begins mid-pulse or at a peak. Default 0.5 in the shipped node.
There's a single output, a plain FLOAT. Wire it into any float socket - KSampler denoise, ControlNet strength, IPAdapter weight, AnimateDiff motion scale, CFG. Audio-reactive AnimateDiff workflows do exactly this with audio weights; this is the deterministic, no-audio version of the same trick.
Install
Trivial, because the pack has zero dependencies and no model downloads. From your ComfyUI folder:
cd custom_nodes
git clone https://github.com/richinsley/Comfy-LFO.git
Restart ComfyUI and you'll find the nodes under the LFO menu. ComfyUI Manager usually has it too - search "Comfy-LFO". The whole pack is five nodes and one small Python file, so there's nothing to break.
Where people get burned
- Static output. The #1 complaint-shaped confusion. Your value doesn't move because
positiondoesn't move. Drive it from a changing source. - Node not showing up. You added the folder but didn't restart ComfyUI. Restart, then it's there.
- Over-expectation. This won't animate a video on its own - it produces a number. You still have to wire that number somewhere that affects the output, and the pack ships nothing to hook a frame counter to it.
It's a tiny utility from a spartan, MIT-licensed pack by richinsley (the same dev behind comfy2go, a Go client for driving ComfyUI programmatically). There's essentially no community discussion around it - not because it's bad, but because there's nothing to argue about. If you need a clean, predictable sine for a float input, this is the one you reach for.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| position | FLOAT | 0.000 | — |
| phase_offset | FLOAT | 0.500 | — |
| frequency | FLOAT | 1.000 | — |
| amplitude | FLOAT | 1.000 | — |
| offset | FLOAT | 0.000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| FLOAT | FLOAT | — |