Fix T98036: Cycles blackbody inaccurate for low temperature and wide gamut
Regenerate blackbody RGB curve fit to not clamp values, and extend down to 800K since it does now change below 965K. Note that as before, blackbody is only defined in the range 800K to 12000K and has a fixed value outside of that. But within that range there should be no more unnecessary gamut clamping.
This commit is contained in:
parent
8f79fa9c67
commit
a22ad7fbd3
Notes:
blender-bot
2023-02-14 02:30:11 +01:00
Referenced by issue #98036, RGB Blackbody Node Still Broken After The Fix
|
@ -24,6 +24,7 @@ ccl_device_noinline void svm_node_blackbody(KernelGlobals kg,
|
|||
float temperature = stack_load_float(stack, temperature_offset);
|
||||
|
||||
float3 color_rgb = rec709_to_rgb(kg, svm_math_blackbody_color_rec709(temperature));
|
||||
color_rgb = max(color_rgb, zero_float3());
|
||||
|
||||
stack_store_float3(stack, col_offset, color_rgb);
|
||||
}
|
||||
|
|
|
@ -192,28 +192,26 @@ ccl_device float svm_math(NodeMathType type, float a, float b, float c)
|
|||
ccl_device float3 svm_math_blackbody_color_rec709(float t)
|
||||
{
|
||||
/* Calculate color in range 800..12000 using an approximation
|
||||
* a/x+bx+c for R and G and ((at + b)t + c)t + d) for B
|
||||
* Max absolute error for RGB is (0.00095, 0.00077, 0.00057),
|
||||
* which is enough to get the same 8 bit/channel color.
|
||||
*/
|
||||
* a/x+bx+c for R and G and ((at + b)t + c)t + d) for B.
|
||||
*
|
||||
* The result of this can be negative to support gamut wider than
|
||||
* than rec.709, just needs to be clamped. */
|
||||
|
||||
if (t >= 12000.0f) {
|
||||
return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
|
||||
return make_float3(0.8262954810464208f, 0.9945080501520986f, 1.566307710274283f);
|
||||
}
|
||||
else if (t < 965.0f) {
|
||||
/* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
|
||||
return make_float3(4.70366907f, 0.0f, 0.0f);
|
||||
else if (t < 800.0f) {
|
||||
/* Arbitrary lower limit where light is very dim, matching OSL. */
|
||||
return make_float3(5.413294490189271f, -0.20319390035873933f, -0.0822535242887164f);
|
||||
}
|
||||
|
||||
/* Manually align for readability. */
|
||||
/* clang-format off */
|
||||
int i = (t >= 6365.0f) ? 5 :
|
||||
(t >= 3315.0f) ? 4 :
|
||||
(t >= 1902.0f) ? 3 :
|
||||
(t >= 1449.0f) ? 2 :
|
||||
(t >= 1167.0f) ? 1 :
|
||||
int i = (t >= 6365.0f) ? 6 :
|
||||
(t >= 3315.0f) ? 5 :
|
||||
(t >= 1902.0f) ? 4 :
|
||||
(t >= 1449.0f) ? 3 :
|
||||
(t >= 1167.0f) ? 2 :
|
||||
(t >= 965.0f) ? 1 :
|
||||
0;
|
||||
/* clang-format on */
|
||||
|
||||
ccl_constant float *r = blackbody_table_r[i];
|
||||
ccl_constant float *g = blackbody_table_g[i];
|
||||
|
|
|
@ -4,30 +4,33 @@
|
|||
/* clang-format off */
|
||||
|
||||
ccl_inline_constant float blackbody_table_r[][3] = {
|
||||
{2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f},
|
||||
{3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f},
|
||||
{4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f},
|
||||
{4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f},
|
||||
{4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f},
|
||||
{3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f}
|
||||
{1.61919106e+03f, -2.05010916e-03f, 5.02995757e+00f},
|
||||
{2.48845471e+03f, -1.11330907e-03f, 3.22621544e+00f},
|
||||
{3.34143193e+03f, -4.86551192e-04f, 1.76486769e+00f},
|
||||
{4.09461742e+03f, -1.27446582e-04f, 7.25731635e-01f},
|
||||
{4.67028036e+03f, 2.91258199e-05f, 1.26703442e-01f},
|
||||
{4.59509185e+03f, 2.87495649e-05f, 1.50345020e-01f},
|
||||
{3.78717450e+03f, 9.35907826e-06f, 3.99075871e-01f}
|
||||
};
|
||||
|
||||
ccl_inline_constant float blackbody_table_g[][3] = {
|
||||
{-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f},
|
||||
{-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f},
|
||||
{-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f},
|
||||
{-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f},
|
||||
{-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f},
|
||||
{-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f}
|
||||
{-4.88999748e+02f, 6.04330754e-04f, -7.55807526e-02f},
|
||||
{-7.55994277e+02f, 3.16730098e-04f, 4.78306139e-01f},
|
||||
{-1.02363977e+03f, 1.20223470e-04f, 9.36662319e-01f},
|
||||
{-1.26571316e+03f, 4.87340896e-06f, 1.27054498e+00f},
|
||||
{-1.42529332e+03f, -4.01150431e-05f, 1.43972784e+00f},
|
||||
{-1.17554822e+03f, -2.16378048e-05f, 1.30408023e+00f},
|
||||
{-5.00799571e+02f, -4.59832026e-06f, 1.09098763e+00f}
|
||||
};
|
||||
|
||||
ccl_inline_constant float blackbody_table_b[][4] = {
|
||||
{0.0f, 0.0f, 0.0f, 0.0f}, /* zeros should be optimized by compiler */
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
{-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f},
|
||||
{-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f},
|
||||
{6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f}
|
||||
{5.96945309e-11f, -4.85742887e-08f, -9.70622247e-05f, -4.07936148e-03f},
|
||||
{2.40430366e-11f, 5.55021075e-08f, -1.98503712e-04f, 2.89312858e-02f},
|
||||
{-1.40949732e-11f, 1.89878968e-07f, -3.56632824e-04f, 9.10767778e-02f},
|
||||
{-3.61460868e-11f, 2.84822009e-07f, -4.93211319e-04f, 1.56723440e-01f},
|
||||
{-1.97075738e-11f, 1.75359352e-07f, -2.50542825e-04f, -2.22783266e-02f},
|
||||
{-1.61997957e-13f, -1.64216008e-08f, 3.86216271e-04f, -7.38077418e-01f},
|
||||
{6.72650283e-13f, -2.73078809e-08f, 4.24098264e-04f, -7.52335691e-01f}
|
||||
};
|
||||
|
||||
ccl_inline_constant float cie_colour_match[][3] = {
|
||||
|
|
|
@ -5765,7 +5765,7 @@ void BlackbodyNode::constant_fold(const ConstantFolder &folder)
|
|||
if (folder.all_inputs_constant()) {
|
||||
const float3 rgb_rec709 = svm_math_blackbody_color_rec709(temperature);
|
||||
const float3 rgb = folder.scene->shader_manager->rec709_to_scene_linear(rgb_rec709);
|
||||
folder.make_constant(rgb);
|
||||
folder.make_constant(max(rgb, zero_float3()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -946,7 +946,7 @@ TEST_F(RenderGraph, constant_fold_bright_contrast)
|
|||
TEST_F(RenderGraph, constant_fold_blackbody)
|
||||
{
|
||||
EXPECT_ANY_MESSAGE(log);
|
||||
CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.94163, 0.226523, 0).");
|
||||
CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.96553, 0.227897, 0).");
|
||||
|
||||
builder
|
||||
.add_node(ShaderNodeBuilder<BlackbodyNode>(graph, "Blackbody").set("Temperature", 1200.0f))
|
||||
|
|
Loading…
Reference in New Issue