mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-22 15:51:30 +11:00
commit
1335068b05
|
@ -1,16 +1,21 @@
|
|||
#version 450
|
||||
|
||||
// white point adjustment
|
||||
// by hunterk
|
||||
// based on blog post by Tanner Helland
|
||||
// http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
// White Point Mapping
|
||||
// ported by Dogway
|
||||
//
|
||||
// From the first comment post (sRGB primaries and linear light compensated)
|
||||
// http://www.zombieprototypes.com/?p=210#comment-4695029660
|
||||
// Based on the Neil Bartlett's blog update
|
||||
// http://www.zombieprototypes.com/?p=210
|
||||
// Inspired itself by Tanner Helland's work
|
||||
// http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float temperature;
|
||||
float luma_preserve;
|
||||
float wp_red;
|
||||
|
@ -18,7 +23,7 @@ layout(push_constant) uniform Push
|
|||
float wp_blue;
|
||||
} params;
|
||||
|
||||
#pragma parameter temperature "White Point" 6500.0 0.0 12000.0 100.0
|
||||
#pragma parameter temperature "White Point" 9311.0 1031.0 12047.0 72.0
|
||||
#pragma parameter luma_preserve "Preserve Luminance" 1.0 0.0 1.0 1.0
|
||||
#pragma parameter wp_red "Red Shift" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter wp_green "Green Shift" 0.0 -1.0 1.0 0.01
|
||||
|
@ -26,7 +31,7 @@ layout(push_constant) uniform Push
|
|||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
mat4 MVP;
|
||||
} global;
|
||||
|
||||
#pragma stage vertex
|
||||
|
@ -45,51 +50,109 @@ layout(location = 0) in vec2 vTexCoord;
|
|||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
// white point adjustment
|
||||
// based on blog post by Tanner Helland
|
||||
// http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
|
||||
|
||||
vec3 wp_adjust(vec3 color){
|
||||
const float target_white_point = 9300.0;
|
||||
const mat3 RGBtoYIQ = mat3(
|
||||
0.2989, 0.5870, 0.1140,
|
||||
0.5959, -0.2744, -0.3216,
|
||||
0.2115, -0.5229, 0.3114);
|
||||
|
||||
const mat3 YIQtoRGB = mat3(
|
||||
1.0, 0.956, 0.6210,
|
||||
1.0, -0.2720, -0.6474,
|
||||
1.0, -1.1060, 1.7046);
|
||||
float temp = params.temperature / 100.;
|
||||
float k = params.temperature / 10000.;
|
||||
float lk = log(k);
|
||||
|
||||
float temp = params.temperature / 100.0;
|
||||
|
||||
// all calculations assume a scale of 255. We'll normalize this at the end
|
||||
vec3 wp = vec3(255.);
|
||||
|
||||
// calculate RED
|
||||
wp.r = (temp <= 66.) ? 255. : 329.698727446 * pow((temp - 60.), -0.1332047592);
|
||||
|
||||
// calculate GREEN
|
||||
wp.g = (temp <= 66.) ? 99.4708025861 * log(temp) - 161.1195681661 : 288.1221695283 * pow((temp - 60.), -0.0755148492);
|
||||
|
||||
// calculate BLUE
|
||||
wp.b = (temp >= 66.) ? 255. : (temp <= 19.) ? 0. : 138.5177312231 * log(temp - 10.) - 305.0447927307;
|
||||
|
||||
// clamp and normalize
|
||||
wp.rgb = clamp(wp.rgb, vec3(0.), vec3(255.)) / vec3(255.);
|
||||
|
||||
// this is dumb, but various cores don't always show white as white. Use this to make white white...
|
||||
wp.rgb += vec3(params.wp_red, params.wp_green, params.wp_blue);
|
||||
|
||||
// apply transformation
|
||||
vec3 adjusted = (color * wp);
|
||||
vec3 base_luma = color * RGBtoYIQ;
|
||||
vec3 adjusted_luma = adjusted * RGBtoYIQ;
|
||||
adjusted = (params.luma_preserve > 0.5) ? adjusted_luma + (vec3(base_luma.r,0.,0.) - vec3(adjusted_luma.r,0.,0.)) : adjusted_luma;
|
||||
|
||||
return adjusted * YIQtoRGB;
|
||||
vec3 wp = vec3(1.);
|
||||
|
||||
// calculate RED
|
||||
wp.r = (temp <= 65.) ? 1. : 0.32068362618584273 + (0.19668730877673762 * pow(k - 0.21298613432655075, - 1.5139012907556737)) + (- 0.013883432789258415 * lk);
|
||||
|
||||
// calculate GREEN
|
||||
float mg = 1.226916242502167 + (- 1.3109482654223614 * pow(k - 0.44267061967913873, 3.) * exp(- 5.089297600846147 * (k - 0.44267061967913873))) + (0.6453936305542096 * lk);
|
||||
float pg = 0.4860175851734596 + (0.1802139719519286 * pow(k - 0.14573069517701578, - 1.397716496795082)) + (- 0.00803698899233844 * lk);
|
||||
wp.g = (temp <= 65.5) ? ((temp <= 8.) ? 0. : mg) : pg;
|
||||
|
||||
// calculate BLUE
|
||||
wp.b = (temp <= 19.) ? 0. : (temp >= 66.) ? 1. : 1.677499032830161 + (- 0.02313594016938082 * pow(k - 1.1367244820333684, 3.) * exp(- 4.221279555918655 * (k - 1.1367244820333684))) + (1.6550275798913296 * lk);
|
||||
|
||||
// clamp
|
||||
wp.rgb = clamp(wp.rgb, vec3(0.), vec3(1.));
|
||||
|
||||
// R/G/B independent manual White Point adjustment
|
||||
wp.rgb += vec3(params.wp_red, params.wp_green, params.wp_blue);
|
||||
|
||||
// Linear color input
|
||||
return color * wp;
|
||||
}
|
||||
|
||||
vec3 sRGB_to_XYZ(vec3 RGB){
|
||||
|
||||
const mat3x3 m = mat3x3(
|
||||
0.4124564, 0.3575761, 0.1804375,
|
||||
0.2126729, 0.7151522, 0.0721750,
|
||||
0.0193339, 0.1191920, 0.9503041);
|
||||
return RGB * m;
|
||||
}
|
||||
|
||||
|
||||
vec3 XYZtoYxy(vec3 XYZ){
|
||||
|
||||
float XYZrgb = XYZ.r+XYZ.g+XYZ.b;
|
||||
float Yxyr = XYZ.g;
|
||||
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
||||
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
||||
return vec3(Yxyr,Yxyg,Yxyb);
|
||||
}
|
||||
|
||||
vec3 XYZ_to_sRGB(vec3 XYZ){
|
||||
|
||||
const mat3x3 m = mat3x3(
|
||||
3.2404542, -1.5371385, -0.4985314,
|
||||
-0.9692660, 1.8760108, 0.0415560,
|
||||
0.0556434, -0.2040259, 1.0572252);
|
||||
return XYZ * m;
|
||||
}
|
||||
|
||||
|
||||
vec3 YxytoXYZ(vec3 Yxy){
|
||||
|
||||
float Xs = Yxy.r * (Yxy.g/Yxy.b);
|
||||
float Xsz = (Yxy.r <= 0.0) ? 0 : 1;
|
||||
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
||||
return XYZ;
|
||||
}
|
||||
|
||||
|
||||
vec3 linear_to_sRGB(vec3 color, float gamma){
|
||||
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
color.r = (color.r <= 0.00313066844250063) ?
|
||||
color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055;
|
||||
color.g = (color.g <= 0.00313066844250063) ?
|
||||
color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055;
|
||||
color.b = (color.b <= 0.00313066844250063) ?
|
||||
color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055;
|
||||
|
||||
return color.rgb;
|
||||
}
|
||||
|
||||
|
||||
vec3 sRGB_to_linear(vec3 color, float gamma){
|
||||
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
color.r = (color.r <= 0.04045) ?
|
||||
color.r / 12.92 : pow((color.r + 0.055) / (1.055), gamma);
|
||||
color.g = (color.g <= 0.04045) ?
|
||||
color.g / 12.92 : pow((color.g + 0.055) / (1.055), gamma);
|
||||
color.b = (color.b <= 0.04045) ?
|
||||
color.b / 12.92 : pow((color.b + 0.055) / (1.055), gamma);
|
||||
|
||||
return color.rgb;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(wp_adjust(texture(Source, vTexCoord).rgb), 1.0);
|
||||
}
|
||||
vec3 original = sRGB_to_linear(texture(Source, vTexCoord).rgb, 2.40);
|
||||
vec3 adjusted = wp_adjust(original);
|
||||
vec3 base_luma = XYZtoYxy(sRGB_to_XYZ(original));
|
||||
vec3 adjusted_luma = XYZtoYxy(sRGB_to_XYZ(adjusted));
|
||||
adjusted = (params.luma_preserve == 1.0) ? adjusted_luma + (vec3(base_luma.r,0.,0.) - vec3(adjusted_luma.r,0.,0.)) : adjusted_luma;
|
||||
FragColor = vec4(linear_to_sRGB(XYZ_to_sRGB(YxytoXYZ(adjusted)), 2.40), 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue