Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save drewhamlett/d072e16dcf2fa62390780a189ee3380c to your computer and use it in GitHub Desktop.

Select an option

Save drewhamlett/d072e16dcf2fa62390780a189ee3380c to your computer and use it in GitHub Desktop.
glsl330
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
uniform sampler2D texture0;
uniform vec4 colDiffuse;
out vec4 finalColor;
// CRT effect controls (set from src/crt.c)
uniform float curvature;
uniform float chromaticAberrationPixels;
uniform float chromaticAberrationCurve;
uniform float contrast;
uniform float brightness;
uniform float scanlineStrength;
uniform float scanlineSpacing;
uniform float vignetteStrength;
uniform vec2 aspectScale;
uniform vec2 texelSize;
uniform vec3 tiltShiftParams; // focus start, strength, blur radius in pixels
uniform vec3 colorGradeParams; // purple tint, glow threshold, glow strength
void main()
{
vec2 centered = fragTexCoord*2.0 - 1.0;
vec2 aspectCentered = centered*aspectScale;
float radius = dot(aspectCentered, aspectCentered);
vec2 warped = centered*(1.0 + radius*curvature);
vec2 uv = warped*0.5 + 0.5;
if (max(abs(warped.x), abs(warped.y)) > 1.0)
{
finalColor = vec4(0.0);
return;
}
vec2 halfTexel = texelSize*0.5;
vec2 minimumUv = halfTexel;
vec2 maximumUv = vec2(1.0) - halfTexel;
float radialLength = sqrt(radius);
vec2 radialDirection = aspectCentered/max(radialLength, 0.0001);
float edgeAmount = pow(clamp(radius*0.5, 0.0, 1.0), chromaticAberrationCurve);
vec2 aberrationOffset = radialDirection*chromaticAberrationPixels*edgeAmount*texelSize;
vec2 centerUv = clamp(uv, minimumUv, maximumUv);
vec3 centerColor = texture(texture0, centerUv).rgb;
vec3 aberratedColor = vec3(
texture(texture0, clamp(uv + aberrationOffset, minimumUv, maximumUv)).r,
centerColor.g,
texture(texture0, clamp(uv - aberrationOffset, minimumUv, maximumUv)).b
);
vec2 blurOffset = vec2(0.0, texelSize.y*tiltShiftParams.z);
vec3 softColor = centerColor*0.5;
softColor += texture(texture0, clamp(uv + blurOffset, minimumUv, maximumUv)).rgb*0.25;
softColor += texture(texture0, clamp(uv - blurOffset, minimumUv, maximumUv)).rgb*0.25;
float defocus = smoothstep(tiltShiftParams.x, 1.0, abs(centered.y));
vec3 color = mix(aberratedColor, softColor, defocus*tiltShiftParams.y);
vec3 glow = max(softColor - vec3(colorGradeParams.y), vec3(0.0));
color += glow*colorGradeParams.z;
vec3 lumaWeights = vec3(0.2126, 0.7152, 0.0722);
vec3 violetColor = color*vec3(1.18, 0.82, 1.28);
float originalLuma = dot(color, lumaWeights);
float violetLuma = max(dot(violetColor, lumaWeights), 0.0001);
float shadowAmount = 1.0 - clamp(originalLuma*2.0, 0.0, 1.0);
violetColor *= originalLuma/violetLuma;
violetColor += vec3(0.035, 0.0, 0.06)*shadowAmount;
color = mix(color, violetColor, colorGradeParams.x);
// mod() keeps the sin() argument small so mediump gl_FragCoord (GLES) stays precise
float phase = mod(gl_FragCoord.y, scanlineSpacing)*6.28318531/scanlineSpacing;
float scanline = 1.0 - scanlineStrength*(0.5 - 0.5*sin(phase));
float vignetteEdge = smoothstep(0.25, 1.0, clamp(radius*0.5, 0.0, 1.0));
float vignette = 1.0 - vignetteStrength*vignetteEdge;
color = clamp(((color - 0.5)*contrast + 0.5)*brightness, 0.0, 1.0);
color *= scanline*vignette;
finalColor = vec4(color, 1.0)*colDiffuse*fragColor;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment