Linear Light
The two nodes that make your EXR saves physically honest
- images
- images
Every picture you generate is stored with an sRGB curve baked in. A preview reads its numbers correctly, a PNG save writes them out correctly, and a blend between two of them is wrong in a subtle, hard-to-see way - because sRGB codes aren't light. Linear Light is the node that moves a batch between the sRGB curve a file is stored with and the light it actually stands for, with an exposure adjustment in stops thrown in on the way. It's the two nodes you need between "this came out of a sampler" and "this goes into an EXR."
When you actually need it
The description is refreshingly clear about who wants this: any node that works in light rather than in codes. The pack's own EXR Save and DNG Save are the headline cases - write an sRGB-encoded tensor to a float EXR and the file is gamma-wrong, the sort of thing that only bites when you open it in a grading tool. Blends and blurs "should behave the way light does," which is another way of saying the pack has HDR-aware paths where a linear input matters.
The voice in the VFX world puts it bluntly - decode to scene-linear, carry as float, speak the same transforms as the rest of the shot - and Linear Light is that decode/encode pair on a socket. If you're a solo generator making finished images, you don't need any of this and the sRGB path is correct. You need it the moment an AI element has to survive next to real footage, or when you're deliberately pushing highlights above white.
The controls
direction-sRGB to linearfor a picture that came out of a PNG, JPEG or sampler on its way into EXR Save, DNG Save or a light-linear blend;linear to sRGBfor light on its way back to a preview, a save, or any node that expects ordinary 0–1 picture codes.exposure- stops applied to the light. 0.0 leaves it alone; -1.0 halves; +1.0 doubles. Here's the neat bit: going to linear, values above 1.0 survive the curve - the transfer function is a power law and it extends - so-2.0is the tooltip's example of bringing a highlight that reached 4.0 back under white on the way out.
Under the hood it applies the actual piecewise sRGB transfer curve per channel, not a lazy gamma 2.2, and keeps any alpha channel untouched. A preview reading the linear output will look too dark - that's not a bug, that's the difference between codes and light; put a linear to sRGB node after it and the picture comes back.
Installing it
Part of WAS Node Suite:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git
or ComfyUI Manager → "WAS Node Suite v3", then restart. Requires ComfyUI 0.14.0+ and Python 3.10+; v3 installs no pip packages.
Where people trip
The most common mistake is a linear output wired straight to a PreviewImage, followed by "why is everything so dark" - encode back to sRGB before anything that assumes picture codes, and only stay linear for the EXR/DNG/light-linear destinations. Second: don't double-convert. If you feed already-linear data into sRGB to linear, you darken it by another gamma's worth. Know which space your source is in before you pick a direction. And remember exposure is in stops, so ±1 is a doubling or halving - a hair of movement on the slider is a real change, not a subtle one.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | The images to convert. Everything above 1.0 survives the trip to linear and is brought back into range by exposure on the way out. | |
| direction | COMBO | 'sRGB to linear' = for a picture that came out of a PNG, a JPEG or a sampler, on its way into EXR Save, DNG Save or a light-linear blend; 'linear to sRGB' = for light on its way to a preview, a save or any node that expects ordinary picture codes. | |
| exposure | FLOAT | 0.0-16–16 | Stops of exposure applied to the light. 0.0 leaves it alone, -1.0 halves it, +1.0 doubles it. -2.0 brings a highlight that reached 4.0 back under white. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | The converted images. Going to linear, the values are light and a preview reads them too dark; coming back, they are ordinary picture codes from 0 to 1. |