Skip to content

Instantly share code, notes, and snippets.

@bytejon
Last active February 18, 2025 09:45
Show Gist options
  • Select an option

  • Save bytejon/2519b1a2cf5f1ff76cc4e94da28a6577 to your computer and use it in GitHub Desktop.

Select an option

Save bytejon/2519b1a2cf5f1ff76cc4e94da28a6577 to your computer and use it in GitHub Desktop.
-- jonbyte, 2024
-- approximate a kelvin temperature as RGB
-- the result of messing around with equations and seeing the results
local R, G, B = 560, 530, 420 -- sample wavelengths
local c = 299792458 -- speed of light (m/s)
local h = 6.62607015e-34 -- planck constant
local k = 1.380649e-23 -- boltzmann constant
local vec0 = vector.create(0, 0, 0)
local function normalize(vec: vector)
if vec == vec0 then
return vec
end
return vec / math.max(vec.x, vec.y, vec.z)
end
local function planck_radiance(W: number, T: number)
W *= 1e-9 -- convert nm to m
local denom = W^5 * (math.exp(h * c / (W * k * T)) - 1)
return (2 * h * c^2) / denom
end
local standard = table.freeze {
[6500] = vector.create(
planck_radiance(R, 6500),
planck_radiance(G, 6500),
planck_radiance(B, 6500)
)
}
local function kelvin_to_rgb(kelvin: number, white: number?): vector
-- compute spectral radiance per channel
-- sampled at one wavelength for performance
local white = white or 6500
local std = standard[white]
local r = planck_radiance(R, kelvin)
local g = planck_radiance(G, kelvin)
local b = planck_radiance(B, kelvin)
local rgb = vector.create(
r / (std and std.x or planck_radiance(R, white)),
g / (std and std.y or planck_radiance(G, white)),
b / (std and std.z or planck_radiance(B, white))
)
rgb = normalize(rgb)
rgb *= math.min(1, (kelvin / 1000)^2) -- quadratic fade-in
return rgb
end
@bytejon
Copy link
Author

bytejon commented Dec 8, 2024

example visualization
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment