Skip to content

Commit

Permalink
fix(whitebalance): stability when changing temperature range
Browse files Browse the repository at this point in the history
avoid flickering
  • Loading branch information
MrLixm committed Dec 29, 2023
1 parent ecb07a8 commit 04e0a8f
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/whitebalance/WhiteBalance.nk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Group {
addUserKnob {6 show_coefficients l "show RGB coefficients" t "Fill the input with RGB coefficients instead of white-balancing." +STARTLINE}
addUserKnob {20 About}
addUserKnob {26 toolName l name T WhiteBalance}
addUserKnob {26 toolVersion l version T 0.1.0}
addUserKnob {26 toolVersion l version T 0.1.1}
addUserKnob {26 toolAuthor l author T "<a style=\"color: rgb(200,200,200);\" href=\"https://mrlixm.github.io/\">Liam Collod</a>"}
addUserKnob {26 toolDescription l description T "Creative white-balancing with temperature and tint control."}
addUserKnob {26 toolUrl l url T "<a style=\"color: rgb(200,200,200);\" href=\"https://github.com/MrLixm/Foundry_Nuke\">https://github.com/MrLixm/Foundry_Nuke</a>"}
Expand All @@ -26,8 +26,8 @@ Group {
inputs 1
recompileCount 2
ProgramGroup 1
KernelDescription "3 \"WhiteBalance\" iterate pixelWise 18eb8371345f90c6c9786195225c12c35bf1c5b11eeec618d305318349545608 2 \"src\" Read Point \"dst\" Write Point 4 \"u_show_coeffs\" Bool 1 AA== \"u_temperature\" Float 1 AACvRQ== \"u_tint\" Float 1 AAB4wQ== \"u_intensity\" Float 1 AACAPw== 4 \"u_show_coeffs\" 1 1 Default \"u_temperature\" 1 1 Default \"u_tint\" 1 1 Default \"u_intensity\" 1 1 Default 0"
kernelSource "// version 2\n//\n// References :\n// - \[2] Ohno, Yoshi (2014). Practical Use and Calculation of CCT and Duv. LEUKOS, 10(1), 47-55. doi:10.1080/15502724.2014.839020\n// - \[3] https://en.wikipedia.org/wiki/Planckian_locus#Approximation\n// - \[4] SMPTE Recommended Practice - Derivation of Basic Television Color Equations https://ieeexplore.ieee.org/document/7291155\n\n#define ohno_deltaT float(0.01)\n\n\nfloat powsafe(float color, float power)\{\n // pow() but safe for NaNs/negatives\n return pow(fabs(color), power) * sign(color);\n\}\n\n\nfloat2 convert_CCT_to_uv_Krystek1985(float CCT)\{\n // Convert the given CCT to CIE 1960 u,v colorspace values using Krystek\\'s method.\n //\n // Krystek\\'s method is an approximation and not intended for accuracy.\n //\n // :param CCT: in kelvin, ~\[1000-15000] range\n // --\[3]\n float CCT_2 = pow(CCT,2.0f);\n float u = 0.860117757f + 1.54118254f * pow(10.0f,-4.0f) * CCT + 1.28641212f * pow(10.0f,-7.0f) * CCT_2;\n u = u / (1.0f + 8.42420235f * pow(10.0f,-4.0f) * CCT + 7.08145163f * pow(10.0f,-7.0f) * CCT_2);\n float v = 0.317398726f + 4.22806245f * pow(10.0f,-5.0f) * CCT + 4.20481691f * pow(10.0f,-8.0f) * CCT_2;\n v = v / (1.0f - 2.89741816f * pow(10.0f,-5.0f) * CCT + 1.61456053f * pow(10.0f,-7.0f) * CCT_2);\n return float2(u, v);\n\}\n\n\nfloat2 convert_CCT_Duv_to_xy(float CCT, float Duv)\{\n // :param CCT: correlated color temperature in kelvin, ~\[1000-15000] range\n // :param Duv: also called \"tint\" \[-0.05-+0.05] range\n // -- \[2]\n float2 uv0 = convert_CCT_to_uv_Krystek1985(CCT);\n float2 uv1 = convert_CCT_to_uv_Krystek1985(CCT + ohno_deltaT);\n\n float du = uv0.x - uv1.x;\n float dv = uv0.y - uv1.y;\n\n float hypothenus = sqrt(powsafe(du,2.0f) + powsafe(dv,2.0f));\n float sinTheta = dv / hypothenus;\n float cosTheta = du / hypothenus;\n\n float u = uv0.x - Duv * sinTheta;\n float v = uv0.y + Duv * cosTheta;\n\n float u_p = u;\n float v_p = 1.5f * v;\n\n float x = 9.0f * u_p / (6.0f * u_p - 16.0f * v_p + 12.0f);\n float y = 2.0f * v_p / (3.0f * u_p - 8.0f * v_p + 6.0f);\n return float2(x, y);\n\}\n\n\nkernel WhiteBalance : ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\n param:\n bool u_show_coeffs;\n float u_temperature;\n float u_tint;\n float u_intensity;\n\n void define()\{\n // default values try to match illuminant E\n defineParam(u_temperature, \"u_temperature\", 5600.0f);\n defineParam(u_tint, \"u_tint\", -15.5f);\n defineParam(u_intensity, \"u_intensity\", 1.0f);\n \}\n\n float lerp(float a1, float a2, float amount)\{\n // linear interpolation between 2 values\n return (1.0f - amount) * a1 + amount * a2;\n \}\n\n void process() \{\n\n // 3000 is an arbitrary scale for the tint parameter to have a more UI friendly range.\n // (actually same as Adobe)\n float2 new_white_xy = convert_CCT_Duv_to_xy(u_temperature, u_tint/3000.0f);\n\n // --\[4] normalise primary matrix algorithm but only with whitepoint\n float Wz = 1.0f - new_white_xy.x - new_white_xy.y;\n float3 W = float3(new_white_xy.x / new_white_xy.y, 1.0f, Wz / new_white_xy.y);\n\n float4 rgba = src();\n float3 new_rgb(rgba.x, rgba.y, rgba.z);\n\n if (u_show_coeffs)\{\n new_rgb.x = W.x;\n new_rgb.y = W.y;\n new_rgb.z = W.z;\n \} else \{\n new_rgb.x = lerp(rgba.x, new_rgb.x * W.x, u_intensity);\n new_rgb.y = lerp(rgba.y, new_rgb.y * W.y, u_intensity);\n new_rgb.z = lerp(rgba.z, new_rgb.z * W.z, u_intensity);\n \}\n\n dst() = float4(\n new_rgb.x,\n new_rgb.y,\n new_rgb.z,\n rgba.w\n );\n \}\n\};"
KernelDescription "3 \"WhiteBalance\" iterate pixelWise 1e37811d49ed72f52f149eacc3441cefe58cfd4837e03224552f931c206b3589 2 \"src\" Read Point \"dst\" Write Point 4 \"u_show_coeffs\" Bool 1 AA== \"u_temperature\" Float 1 AACvRQ== \"u_tint\" Float 1 AAB4wQ== \"u_intensity\" Float 1 AACAPw== 4 \"u_show_coeffs\" 1 1 Default \"u_temperature\" 1 1 Default \"u_tint\" 1 1 Default \"u_intensity\" 1 1 Default 0"
kernelSource "// version 2\n//\n// References :\n// - \[2] Ohno, Yoshi (2014). Practical Use and Calculation of CCT and Duv. LEUKOS, 10(1), 47-55. doi:10.1080/15502724.2014.839020\n// - \[3] https://en.wikipedia.org/wiki/Planckian_locus#Approximation\n// - \[4] SMPTE Recommended Practice - Derivation of Basic Television Color Equations https://ieeexplore.ieee.org/document/7291155\n\n#define ohno_deltaT float(1.0)\n\n\nfloat powsafe(float color, float power)\{\n // pow() but safe for NaNs/negatives\n return pow(fabs(color), power) * sign(color);\n\}\n\n\nfloat2 convert_CCT_to_uv_Krystek1985(float CCT)\{\n // Convert the given CCT to CIE 1960 u,v colorspace values using Krystek\\'s method.\n //\n // Krystek\\'s method is an approximation and not intended for accuracy.\n //\n // :param CCT: in kelvin, ~\[1000-15000] range\n // --\[3]\n float CCT_2 = pow(CCT,2.0f);\n float u = 0.860117757f + 1.54118254f * pow(10.0f,-4.0f) * CCT + 1.28641212f * pow(10.0f,-7.0f) * CCT_2;\n u = u / (1.0f + 8.42420235f * pow(10.0f,-4.0f) * CCT + 7.08145163f * pow(10.0f,-7.0f) * CCT_2);\n float v = 0.317398726f + 4.22806245f * pow(10.0f,-5.0f) * CCT + 4.20481691f * pow(10.0f,-8.0f) * CCT_2;\n v = v / (1.0f - 2.89741816f * pow(10.0f,-5.0f) * CCT + 1.61456053f * pow(10.0f,-7.0f) * CCT_2);\n return float2(u, v);\n\}\n\n\nfloat2 convert_CCT_Duv_to_xy(float CCT, float Duv)\{\n // :param CCT: correlated color temperature in kelvin, ~\[1000-15000] range\n // :param Duv: also called \"tint\" \[-0.05-+0.05] range\n // -- \[2]\n float2 uv0 = convert_CCT_to_uv_Krystek1985(CCT);\n float2 uv1 = convert_CCT_to_uv_Krystek1985(CCT + ohno_deltaT);\n\n float du = uv0.x - uv1.x;\n float dv = uv0.y - uv1.y;\n\n float hypothenus = sqrt(powsafe(du,2.0f) + powsafe(dv,2.0f));\n float sinTheta = dv / hypothenus;\n float cosTheta = du / hypothenus;\n\n float u = uv0.x - Duv * sinTheta;\n float v = uv0.y + Duv * cosTheta;\n\n float u_p = u;\n float v_p = 1.5f * v;\n\n float x = 9.0f * u_p / (6.0f * u_p - 16.0f * v_p + 12.0f);\n float y = 2.0f * v_p / (3.0f * u_p - 8.0f * v_p + 6.0f);\n return float2(x, y);\n\}\n\n\nkernel WhiteBalance : ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\n param:\n bool u_show_coeffs;\n float u_temperature;\n float u_tint;\n float u_intensity;\n\n void define()\{\n // default values try to match illuminant E\n defineParam(u_temperature, \"u_temperature\", 5600.0f);\n defineParam(u_tint, \"u_tint\", -15.5f);\n defineParam(u_intensity, \"u_intensity\", 1.0f);\n \}\n\n float lerp(float a1, float a2, float amount)\{\n // linear interpolation between 2 values\n return (1.0f - amount) * a1 + amount * a2;\n \}\n\n void process() \{\n\n // 3000 is an arbitrary scale for the tint parameter to have a more UI friendly range.\n // (actually same as Adobe)\n float2 new_white_xy = convert_CCT_Duv_to_xy(u_temperature, u_tint/3000.0f);\n\n // --\[4] normalise primary matrix algorithm but only with whitepoint\n float Wz = 1.0f - new_white_xy.x - new_white_xy.y;\n float3 W = float3(new_white_xy.x / new_white_xy.y, 1.0f, Wz / new_white_xy.y);\n\n float4 rgba = src();\n float3 new_rgb(rgba.x, rgba.y, rgba.z);\n\n if (u_show_coeffs)\{\n new_rgb.x = W.x;\n new_rgb.y = W.y;\n new_rgb.z = W.z;\n \} else \{\n new_rgb.x = lerp(rgba.x, new_rgb.x * W.x, u_intensity);\n new_rgb.y = lerp(rgba.y, new_rgb.y * W.y, u_intensity);\n new_rgb.z = lerp(rgba.z, new_rgb.z * W.z, u_intensity);\n \}\n\n dst() = float4(\n new_rgb.x,\n new_rgb.y,\n new_rgb.z,\n rgba.w\n );\n \}\n\};"
rebuild ""
WhiteBalance_u_temperature {{parent.temperature}}
WhiteBalance_u_tint {{parent.tint}}
Expand Down
2 changes: 1 addition & 1 deletion src/whitebalance/src/WhiteBalance-template.nk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Group {
addUserKnob {6 show_coefficients l "show RGB coefficients" t "Fill the input with RGB coefficients instead of white-balancing." +STARTLINE}
addUserKnob {20 About}
addUserKnob {26 toolName l name T WhiteBalance}
addUserKnob {26 toolVersion l version T 0.1.0}
addUserKnob {26 toolVersion l version T 0.1.1}
addUserKnob {26 toolAuthor l author T "<a style=\"color: rgb(200,200,200);\" href=\"https://mrlixm.github.io/\">Liam Collod</a>"}
addUserKnob {26 toolDescription l description T "Creative white-balancing with temperature and tint control."}
addUserKnob {26 toolUrl l url T "<a style=\"color: rgb(200,200,200);\" href=\"https://github.com/MrLixm/Foundry_Nuke\">https://github.com/MrLixm/Foundry_Nuke</a>"}
Expand Down
2 changes: 1 addition & 1 deletion src/whitebalance/src/WhiteBalance.blink
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// - [3] https://en.wikipedia.org/wiki/Planckian_locus#Approximation
// - [4] SMPTE Recommended Practice - Derivation of Basic Television Color Equations https://ieeexplore.ieee.org/document/7291155

#define ohno_deltaT float(0.01)
#define ohno_deltaT float(1.0)


float powsafe(float color, float power){
Expand Down

0 comments on commit 04e0a8f

Please sign in to comment.