Skip to content

Instantly share code, notes, and snippets.

@justinbowes
Created June 18, 2014 18:13
Show Gist options
  • Save justinbowes/ac849866a35855e2c5f7 to your computer and use it in GitHub Desktop.
Save justinbowes/ac849866a35855e2c5f7 to your computer and use it in GitHub Desktop.
Blackbody to SRGB code based on piecewise blackbody curve reconstruction. Depends on XPL, but you can easily replace its vector-construction calls in blackbody_rgbi and blackbody_rgb with your own.
// science/blackbody_srgb.c. ©2014 Informi Software Inc. Use and modify this file for any purpose without attribution.
#include "science/blackbody_srgb.h"
#ifndef XPL_STATIC_INLINE
# define XPL_STATIC_INLINE static inline
#endif
XPL_STATIC_INLINE float r_0_6700(float k) {
return 1.0f;
}
XPL_STATIC_INLINE float r_6700_10000(float k) {
return 6380.0f / k;
}
XPL_STATIC_INLINE float r_10000(float k) {
return 0.313f * k / (k - 5100.0f);
}
XPL_STATIC_INLINE float g_0_1100(float k) {
return 0.000005f * k;
}
XPL_STATIC_INLINE float g_1100_4000(float k) {
return 0.000204f * k - 0.164f;
}
XPL_STATIC_INLINE float g_4000_6700(float k) {
return -2956.0f / k + 1.39f;
}
XPL_STATIC_INLINE float g_6700_10000(float k) {
return 5030.0f / k + 0.196f;
}
XPL_STATIC_INLINE float g_10000(float k) {
return 0.436f * k / (k - 3820.0f) - 0.0006f;
}
XPL_STATIC_INLINE float b_0_2086(float k) {
return 0.0f;
}
XPL_STATIC_INLINE float b_2086_4000(float k) {
return 0.00018f * k - 0.378f;
}
XPL_STATIC_INLINE float b_4000_6700(float k) {
return 0.000245f * k - 0.64f;
}
XPL_STATIC_INLINE float b_6700(float k) {
return 1.0f;
}
XPL_STATIC_INLINE float i_0_15000(float k) {
return (k == 0.f) ? 0.f : 179.3f * powf(k, (-3509.0f / (k + 0.001f)));
}
XPL_STATIC_INLINE float i_15000(float k) {
return 0.00313f * k - 28.04f;
}
xvec4 blackbody_rgbi(float k) {
if (k <= 1100.0f) return xvec4_set(r_0_6700(k), g_0_1100(k), b_0_2086(k), i_0_15000(k));
if (k <= 2086.0f) return xvec4_set(r_0_6700(k), g_1100_4000(k), b_0_2086(k), i_0_15000(k));
if (k <= 4000.0f) return xvec4_set(r_0_6700(k), g_1100_4000(k), b_2086_4000(k), i_0_15000(k));
if (k <= 6700.0f) return xvec4_set(r_0_6700(k), g_4000_6700(k), b_4000_6700(k), i_0_15000(k));
if (k <= 10000.0f) return xvec4_set(r_6700_10000(k), g_6700_10000(k), b_6700(k), i_0_15000(k));
if (k <= 15000.0f) return xvec4_set(r_10000(k), g_10000(k), b_6700(k), i_0_15000(k));
return xvec4_set(r_10000(k), g_10000(k), b_6700(k), i_15000(k));
}
xvec3 blackbody_rgb(float k) {
if (k <= 1100.0f) return xvec3_set(r_0_6700(k), g_0_1100(k), b_0_2086(k));
if (k <= 2086.0f) return xvec3_set(r_0_6700(k), g_1100_4000(k), b_0_2086(k));
if (k <= 4000.0f) return xvec3_set(r_0_6700(k), g_1100_4000(k), b_2086_4000(k));
if (k <= 6700.0f) return xvec3_set(r_0_6700(k), g_4000_6700(k), b_4000_6700(k));
if (k <= 10000.0f) return xvec3_set(r_6700_10000(k), g_6700_10000(k), b_6700(k));
if (k <= 15000.0f) return xvec3_set(r_10000(k), g_10000(k), b_6700(k));
return xvec3_set(r_10000(k), g_10000(k), b_6700(k));
}
#ifndef p1_blackbody_srgb_h
#define p1_blackbody_srgb_h
#include <xpl/math/vec4.h>
#include <xpl/math/vec3.h>
xvec4 blackbody_rgbi(float kelvin);
xvec3 blackbody_rgb(float kelvin);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment