Anet & Nejno
Nejno Nejno
Hey Anet, I was thinking about how colors shift when light hits paper, like the way a bright lamp can make a painted hue look warmer or cooler. Do you ever try to model that in code, making a digital canvas that reacts to light like a real piece of art?
Anet Anet
Yeah, I’ve built a few shaders that tweak the color temperature on the fly. I feed the RGB values through a simple spectral lookup and then blend it with the scene’s light source. It’s all about keeping the gamma curve right and letting the light’s hue drive the interpolation. The result? A digital canvas that actually feels the lamp change the mood of a paint stroke. Want to dive into the math?
Nejno Nejno
That sounds really cool. Just to make sure I’m not missing something—when you map RGB to a spectral look‑up table, do you convert each channel to a wavelength estimate first, then blend that with the scene light’s spectral distribution? And for the gamma, do you apply a linear‑to‑sRGB conversion before blending or after? Also, how do you keep the interpolation smooth when the light hue jumps a bit? It’d be great to see the equations you’re using.
Anet Anet
Sure, here’s the gist in plain math so you can drop it straight into a shader or a small script. First linearise the colour, because RGB in most images is gamma‑encoded. **Linearise RGB** R_lin = R^γ G_lin = G^γ B_lin = B^γ where γ ≈ 2.2 for sRGB. **Estimate a dominant wavelength** (a very rough “pseudo‑spectral” map). You can do a weighted sum that pulls more from the red channel for the low end of the spectrum and from blue for the high end. λ_est = a·R_lin + b·G_lin + c·B_lin Typical weights: a≈0.4, b≈0.3, c≈0.3. This gives you a number in the 400–700 nm range if you scale it appropriately. **Blend with the light’s spectral distribution** Suppose L(λ) is the light’s spectrum (a table of intensity vs wavelength). Your pigment’s reflectance S_p(λ) is another table (or a simple model). Compute the reflected spectrum at the estimated wavelength: S_out(λ) = S_p(λ) · L(λ) If you want a single RGB value, sample S_out(λ) at the three key wavelengths that map back to R, G, B (roughly 700 nm, 546 nm, 435 nm) and convert them back to linear RGB: R' = S_out(700 nm) G' = S_out(546 nm) B' = S_out(435 nm) **Gamma correction** Apply gamma to get back to display space: R_disp = (R')^(1/γ) G_disp = (G')^(1/γ) B_disp = (B')^(1/γ) **Smooth interpolation when light hue jumps** Use linear interpolation in the spectral domain, not in RGB. If your light switches from one dominant λ to another, do: S_out_interp(λ) = (1‑t)·S_out_prev(λ) + t·S_out_new(λ) where t∈[0,1] is the interpolation factor over time. This keeps the spectral shape changing smoothly, so the perceived colour changes gradually instead of jumping. Put it all together, you get a chain: 1. Linearise input RGB. 2. Estimate λ_est. 3. Sample pigment spectrum at that λ and multiply by light spectrum. 4. Interpolate if the light changes. 5. Convert the resulting spectral sample back to RGB. 6. Apply gamma to output. That’s the core of a light‑reactive paint shader. Feel free to tweak the weights or add a more sophisticated reflectance model if you want more realism. Happy hacking.
Nejno Nejno
Wow, that’s a lot of detail—thanks for the step‑by‑step. I’ll try plugging it into my shader and see how the colors shift with a changing lamp. Maybe I’ll tweak the weights a bit, just to keep my canvas from feeling too flat. Let me know if you notice any “jump” in the hue when the light changes; I’m hoping the interpolation will keep it smooth. Good luck experimenting!
Anet Anet
Sounds solid. Hit me up with screenshots if it still stutters—maybe a faster lerp on the spectral samples or a little noise can mask a hiccup. Happy tweaking!
Nejno Nejno
Glad to hear it’s working! I’ll let you know if I hit any hiccups and if I add any noise tricks. Thanks for the tip, and happy tweaking too!
Anet Anet
Nice, keep me posted on how it pans out. If the colors still feel off, we can play with the spectral weight map or add a subtle dithering function. Catch you later.