slang-shaders/misc/chroma.slang

105 lines
3.6 KiB
Plaintext

#version 450
// Chroma / YIQ
// by torridgristle
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float BrightenLevel;
float BrightenAmount;
float ContrastAmount;
float ChromaLevel;
float IAmount;
float QAmount;
float ITilt;
float QTilt;
float ITiltHigh;
float QTiltHigh;
float ITiltMid;
float QTiltMid;
float ITiltLow;
float QTiltLow;
float LumBoost;
} params;
#pragma parameter BrightenLevel "Brighten Level" 2.0 1.0 10.0 1.0
#pragma parameter BrightenAmount "Brighten Amount" 0.0 0.0 1.0 0.1
#pragma parameter ContrastAmount "Contrast Amount" 0.0 0.0 1.0 0.1
#pragma parameter ChromaLevel "Chroma Level" 2.0 1.0 10.0 1.0
#pragma parameter IAmount "I Amount" 0.0 0.0 1.0 0.1
#pragma parameter QAmount "Q Amount" 0.0 0.0 1.0 0.1
#pragma parameter ITilt "I Tilt" 0.5 0.4 0.6 0.01
#pragma parameter QTilt "Q Tilt" 0.5 0.4 0.6 0.01
#pragma parameter ITiltHigh "I Tilt High" 0.5 0.4 0.6 0.01
#pragma parameter QTiltHigh "Q Tilt High" 0.5 0.4 0.6 0.01
#pragma parameter ITiltMid "I Tilt Mid" 0.5 0.4 0.6 0.01
#pragma parameter QTiltMid "Q Tilt Mid" 0.5 0.4 0.6 0.01
#pragma parameter ITiltLow "I Tilt Low" 0.5 0.4 0.6 0.01
#pragma parameter QTiltLow "Q Tilt Low" 0.5 0.4 0.6 0.01
#pragma parameter LumBoost "Luma Boost" 0.0 0.0 1.0 0.1
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
#define RGB_to_YIQ mat3x3( 0.299 , 0.595716 , 0.211456 , 0.587 , -0.274453 , -0.522591 , 0.114 , -0.321263 , 0.311135 )
#define YIQ_to_RGB mat3x3( 1.0 , 1.0 , 1.0 , 0.9563 , -0.2721 , -1.1070 , 0.6210 , -0.6474 , 1.7046 )
vec3 Chroma(vec3 Photo, float Level) {
Photo *= RGB_to_YIQ;
float I_Tilt = ((params.ITilt - 0.5) * 2);
float Q_Tilt = ((params.QTilt - 0.5) * 2);
float LumHigh = max(Photo.x-0.5,0.0)*2.0;
float LumMid = 1-abs(Photo.x-0.5)*2.0;
float LumLow = max((1-Photo.x)-0.5,0.0)*2.0;
float I_TiltHigh = ((params.ITiltHigh - 0.5) * 2) * LumHigh;
float Q_TiltHigh = ((params.QTiltHigh - 0.5) * 2) * LumHigh;
float I_TiltMid = ((params.ITiltMid - 0.5) * 2) * LumMid;
float Q_TiltMid = ((params.QTiltMid - 0.5) * 2) * LumMid;
float I_TiltLow = ((params.ITiltLow - 0.5) * 2) * LumLow;
float Q_TiltLow = ((params.QTiltLow - 0.5) * 2) * LumLow;
Photo.yz = mix(Photo.yz,(1.0-pow(1.0-abs(Photo.yz),vec2(Level)))*sign(Photo.yz),vec2(params.IAmount,params.QAmount));
Photo.y = Photo.y * (1-abs(I_Tilt)) + I_Tilt;
Photo.z = Photo.z * (1-abs(Q_Tilt)) + Q_Tilt;
Photo.y = Photo.y * (1-abs(I_TiltHigh)) + I_TiltHigh;
Photo.z = Photo.z * (1-abs(Q_TiltHigh)) + Q_TiltHigh;
Photo.y = Photo.y * (1-abs(I_TiltMid)) + I_TiltMid;
Photo.z = Photo.z * (1-abs(Q_TiltMid)) + Q_TiltMid;
Photo.y = Photo.y * (1-abs(I_TiltLow)) + I_TiltLow;
Photo.z = Photo.z * (1-abs(Q_TiltLow)) + Q_TiltLow;
Photo.x = mix(Photo.x,1-pow(1-Photo.x,2.0),params.LumBoost);
Photo *= YIQ_to_RGB;
Photo = clamp(Photo,0.0,1.0);
Photo = mix(Photo,1.0-pow(1.0-Photo,vec3(params.BrightenLevel)),params.BrightenAmount);
Photo = mix(Photo,Photo * Photo * (3 - 2 * Photo),params.ContrastAmount);
return Photo;
}
void main()
{
vec3 Picture = texture(Source, vTexCoord).xyz;
FragColor = vec4(Chroma(Picture,params.ChromaLevel),1.0);
}