#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); }