Last active
May 12, 2022 04:02
-
-
Save jeferwang/4e14425cbfaed8bc17cfce11e40ecb06 to your computer and use it in GitHub Desktop.
HLSL Color Transform: RGB/HSV/HSL, WhiteBalance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Color Transform 颜色转换/调整 | |
HSV/RGB | |
HSL | |
WhiteBalance白平衡 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://blog.csdn.net/haowenlai2008/article/details/99317027 | |
// RGB每个分量转换成阴影中间调高光对应的权重 | |
float3 transfer(float value) | |
{ | |
float a = 64.0, b = 85.0, scale = 1.785; | |
float3 result; | |
float i = value * 255.0; | |
float shadows = clamp ((i - b) / -a + 0.5, 0.0, 1.0) * scale; | |
float midtones = clamp ((i - b) / a + 0.5, 0.0, 1.0) * clamp ((i + b - 255.0) / -a + .5, 0.0, 1.0) * scale; | |
float highlights = clamp (((255.0 - i) - b) / -a + 0.5, 0.0, 1.0) * scale; | |
result.r = shadows; | |
result.g = midtones; | |
result.b = highlights; | |
return result; | |
} | |
void main() | |
{ | |
float4 base = texture2D(inputImageTexture, textureCoordinate); | |
float3 hsl = rgb2hsl(base.rgb); | |
float3 weight_r = transfer(base.r); | |
float3 weight_g = transfer(base.g); | |
float3 weight_b = transfer(base.b); | |
float3 color = float3(base.rgb * 255.0); | |
color.r += cyan_red_shadow * weight_r.r; | |
color.r += cyan_red_midtones * weight_r.g; | |
color.r += cyan_red_highlights * weight_r.b; | |
color.g += magenta_green_shadow * weight_g.r; | |
color.g += magenta_green_midtones * weight_g.g; | |
color.g += magenta_green_highlights * weight_g.b; | |
color.b += yellow_blue_shadow * weight_b.r; | |
color.b += yellow_blue_midtones * weight_b.g; | |
color.b += yellow_blue_highlights * weight_b.b; | |
color.r = clamp(color.r, 0.0, 255.0); | |
color.g = clamp(color.g, 0.0, 255.0); | |
color.b = clamp(color.b, 0.0, 255.0); | |
float3 hsl2 = rgb2hsl(color / 255.0); | |
hsl2.z = hsl.z; | |
gl_FragColor=float4(hsl2rgb(hsl2), base.a); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://blog.csdn.net/haowenlai2008/article/details/99317027 | |
float3 hsl2rgb(float3 color) | |
{ | |
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | |
float3 p = abs(frac(color.xxx + K.xyz) * 6.0 - K.www); | |
return color.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl | |
float3 hsv2rgb(float3 InHSV) | |
{ | |
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | |
float3 p = abs(frac(InHSV.xxx + K.xyz) * 6.0 - K.www); | |
return InHSV.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), InHSV.y); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://blog.csdn.net/haowenlai2008/article/details/99317027 | |
float3 rgb2hsl(float3 color){ | |
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); | |
float4 p = lerp(float4(color.bg, K.wz), float4(color.gb, K.xy), step(color.b, color.g)); | |
float4 q = lerp(float4(p.xyw, color.r), float4(color.r, p.yzx), step(p.x, color.r)); | |
float d = q.x - min(q.w, q.y); | |
float e = 1.0e-10; | |
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); | |
} | |
if ( del_Max == 0 ) //This is a gray, no chroma... | |
{ | |
H = 0; | |
S = 0; | |
} | |
else //Chromatic data... | |
{ | |
if ( L < 0.5 ) { | |
S = del_Max / ( var_Max + var_Min ); | |
} | |
else { | |
S = del_Max / ( 2 - var_Max - var_Min ); | |
} | |
float del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max; | |
float del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max; | |
float del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max; | |
if ( var_R == var_Max ) H = del_B - del_G; | |
else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B; | |
else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R; | |
if ( H < 0 ) H += 1; | |
if ( H > 1 ) H -= 1; | |
} | |
return float3(H, S, L); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl | |
float3 rgb2hsv(vec3 InRGB) | |
{ | |
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); | |
float4 p = lerp(float4(InRGB.bg, K.wz), float4(InRGB.gb, K.xy), step(InRGB.b, InRGB.g)); | |
float4 q = lerp(float4(p.xyw, InRGB.r), float4(InRGB.r, p.yzx), step(p.x, InRGB.r)); | |
float d = q.x - min(q.w, q.y); | |
float e = 1.0e-10; | |
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://www.jianshu.com/p/7074fa4cb907 | |
float3 WhiteBalance_float(float3 In, float Temperature, float Tint) | |
{ | |
// Range ~[-1.67;1.67] works best | |
float t1 = Temperature * 10 / 6; | |
float t2 = Tint * 10 / 6; | |
// Get the CIE xy chromaticity of the reference white point. | |
// Note: 0.31271 = x value on the D65 white point | |
float x = 0.31271 - t1 * (t1 < 0 ? 0.1 : 0.05); | |
float standardIlluminantY = 2.87 * x - 3 * x * x - 0.27509507; | |
float y = standardIlluminantY + t2 * 0.05; | |
// Calculate the coefficients in the LMS space. | |
float3 w1 = float3(0.949237, 1.03542, 1.08728); // D65 white point | |
// CIExyToLMS | |
float Y = 1; | |
float X = Y * x / y; | |
float Z = Y * (1 - x - y) / y; | |
float L = 0.7328 * X + 0.4296 * Y - 0.1624 * Z; | |
float M = -0.7036 * X + 1.6975 * Y + 0.0061 * Z; | |
float S = 0.0030 * X + 0.0136 * Y + 0.9834 * Z; | |
float3 w2 = float3(L, M, S); | |
float3 balance = float3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z); | |
float3x3 LIN_2_LMS_MAT = { | |
3.90405e-1, 5.49941e-1, 8.92632e-3, | |
7.08416e-2, 9.63172e-1, 1.35775e-3, | |
2.31082e-2, 1.28021e-1, 9.36245e-1 | |
}; | |
float3x3 LMS_2_LIN_MAT = { | |
2.85847e+0, -1.62879e+0, -2.48910e-2, | |
-2.10182e-1, 1.15820e+0, 3.24281e-4, | |
-4.18120e-2, -1.18169e-1, 1.06867e+0 | |
}; | |
float3 lms = mul(LIN_2_LMS_MAT, In); | |
lms *= balance; | |
return mul(LMS_2_LIN_MAT, lms); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment