Skip to content

Instantly share code, notes, and snippets.

@Hebali
Last active July 7, 2021 12:59
Show Gist options
  • Save Hebali/5950485 to your computer and use it in GitHub Desktop.
Save Hebali/5950485 to your computer and use it in GitHub Desktop.
Quick GLSL sketch heading towards a more generalized tool...
// GLSL Image Filters
// Curated by Patrick Hebron
// Influences:
// http://thndl.com
// https://gist.github.com/BlackBulletIV/4218802
// http://mouaif.wordpress.com/?p=94
uniform sampler2D tex;
//////////////////////////////
// IMAGE FILTERS:
//////////////////////////////
// Bloom filter function: (Defaults: iSamples = 5, iQuality = 2.5)
vec4 bloomFilter(sampler2D iTexture, vec2 iTextureCoord, vec2 iDimensions, int iSamples, float iQuality, vec4 iTint) {
vec4 tSrc = texture2D( iTexture, iTextureCoord );
vec4 tSum = vec4( 0.0 );
int tDiff = (iSamples - 1) / 2;
vec2 tFact = vec2( 1.0 ) / iDimensions * iQuality;
for(int x = -tDiff; x <= tDiff; x++) {
for(int y = -tDiff; y <= tDiff; y++) {
tSum += texture2D( iTexture, iTextureCoord + ( vec2( x, y ) * tFact ) );
}
}
return ( ( tSum / ( pow( float( iSamples ), 2.0 ) ) ) + tSrc ) * iTint;
}
// Vignette filter function: (Defaults: iExtent = 1.5)
vec4 vignetteFilter(sampler2D iTexture, vec2 iTextureCoord, float iExtent) {
float tDist = distance( vec2( 0.5, 0.5 ), iTextureCoord ) * iExtent;
vec3 tRgb = texture2D( iTexture, iTextureCoord ).rgb * ( 1.0 - tDist * tDist );
return vec4( tRgb, 1.0 );
}
//////////////////////////////
// IMAGE FRAME DECORATORS:
//////////////////////////////
// roundedRect() returns an alpha value representing the visibility
// of the pixel at a given coordinate within a rounded-rectangle frame:
float roundedRect(vec2 iCoord) {
// Todo: externalize parameters!
// Todo: resolve inscribed scale!
vec2 tCoordAdj = abs( iCoord * 2.0 - vec2( 1.0, 1.0 ) );
return 1.0 - step( 0.2, length( max( tCoordAdj - 0.3, 0.0 ) ) );
}
// squircledRect() returns an alpha value representing the visibility
// of the pixel at a given coordinate within a squared-circle frame:
// (Defaults: iSquaringPower = 8.0)
float squircledRect(vec2 iCoord, float iSquaringPower) {
// Todo: externalize parameters!
vec2 tCoordAdj = abs( iCoord * 2.0 - vec2( 1.0, 1.0 ) );
return smoothstep( 0.0, 0.1, 1.0 - length( pow( tCoordAdj, vec2( iSquaringPower ) ) ) );
}
//////////////////////////////
// IMAGE PROCESSING FUNCTIONS:
//////////////////////////////
// Desaturate function:
vec4 desaturate(vec4 iColor, float iExtent) {
vec3 tCoeff = vec3( 0.3, 0.59, 0.11 );
vec3 tGray = vec3( dot( tCoeff, iColor.rgb ) );
return vec4( mix( iColor.rgb, tGray, iExtent ), iColor.a );
}
// Contrast, saturation and brightness adjustment function:
vec4 contrastSaturationBrightness(vec4 iColor, float iBrightness, float iSaturation, float iContrast) {
const vec3 tLumAvg = vec3( 0.5, 0.5, 0.5 );
const vec3 tLumCoeff = vec3( 0.2125, 0.7154, 0.0721 );
vec3 tBriClr = iColor.rgb * iBrightness;
vec3 tIntens = vec3( dot( tBriClr, tLumCoeff ) );
vec3 tSatClr = mix( tIntens, tBriClr, iSaturation );
vec3 tConClr = mix( tLumAvg, tSatClr, iContrast );
return vec4( tConClr, iColor.a );
}
// RGB to HSL colorspace conversion function:
vec3 rgbToHsl(vec3 iColor) {
vec3 tHsl = vec3( 0.0 );
float tMin = min( min( iColor.r, iColor.g), iColor.b );
float tMax = max( max( iColor.r, iColor.g), iColor.b );
float tDelta = tMax - tMin;
tHsl.z = (tMax + tMin) / 2.0;
if( tDelta != 0.0 ) {
if( tHsl.z < 0.5 ) { tHsl.y = tDelta / (tMax + tMin); }
else { tHsl.y = tDelta / (2.0 - tMax - tMin); }
float tDeltaR = (((tMax - iColor.r) / 6.0) + (tDelta / 2.0)) / tDelta;
float tDeltaG = (((tMax - iColor.g) / 6.0) + (tDelta / 2.0)) / tDelta;
float tDeltaB = (((tMax - iColor.b) / 6.0) + (tDelta / 2.0)) / tDelta;
if( iColor.r == tMax ) { tHsl.x = tDeltaB - tDeltaG; }
else if( iColor.g == tMax ) { tHsl.x = (1.0 / 3.0) + tDeltaR - tDeltaB; }
else if( iColor.b == tMax ) { tHsl.x = (2.0 / 3.0) + tDeltaG - tDeltaR; }
if( tHsl.x < 0.0 ) { tHsl.x += 1.0; }
else if( tHsl.x > 1.0 ) { tHsl.x -= 1.0; }
}
return tHsl;
}
// Hue to RGB colorspace conversion helper function:
float hueToRgb(float iF1, float iF2, float iHue) {
if( iHue < 0.0 ) { iHue += 1.0; }
else if( iHue > 1.0 ) { iHue -= 1.0; }
float tRes;
if( (6.0 * iHue) < 1.0 ) { tRes = iF1 + (iF2 - iF1) * 6.0 * iHue; }
else if ((2.0 * iHue) < 1.0) { tRes = iF2; }
else if ((3.0 * iHue) < 2.0) { tRes = iF1 + (iF2 - iF1) * ((2.0 / 3.0) - iHue) * 6.0; }
else { tRes = iF1; }
return tRes;
}
// HSL to RGB colorspace conversion function:
vec3 hslToRgb(vec3 iHsl) {
vec3 tRgb;
if( iHsl.y == 0.0 ) {
tRgb = vec3( iHsl.z );
}
else {
float f2;
if( iHsl.z < 0.5 ) { f2 = iHsl.z * (1.0 + iHsl.y); }
else { f2 = (iHsl.z + iHsl.y) - (iHsl.y * iHsl.z); }
float f1 = 2.0 * iHsl.z - f2;
tRgb.r = hueToRgb( f1, f2, iHsl.x + (1.0/3.0) );
tRgb.g = hueToRgb( f1, f2, iHsl.x);
tRgb.b = hueToRgb( f1, f2, iHsl.x - (1.0/3.0) );
}
return tRgb;
}
// Combines luminance and saturation of iBaseColor with hue of iBlendColor:
vec3 blendHue(vec3 iBaseColor, vec3 iBlendColor) {
vec3 tBase = rgbToHsl( iBaseColor );
return hslToRgb( vec3( rgbToHsl(iBlendColor).r, tBase.g, tBase.b ) );
}
// Combines luminance and hue of iBaseColor with the saturation of iBlendColor:
vec3 blendSaturation(vec3 iBaseColor, vec3 iBlendColor) {
vec3 tBase = rgbToHsl( iBaseColor );
return hslToRgb( vec3( tBase.r, rgbToHsl(iBlendColor).g, tBase.b ) );
}
// Combines hue and saturation of iBaseColor with the luminance of iBlendColor:
vec3 blendLuminosity(vec3 iBaseColor, vec3 iBlendColor) {
vec3 tBase = rgbToHsl( iBaseColor );
return hslToRgb( vec3( tBase.r, tBase.g, rgbToHsl(iBlendColor).b ) );
}
// Uses brightness of iBaseColor with the hue and saturation of iBlendColor:
vec3 blendColor(vec3 iBaseColor, vec3 iBlendColor) {
vec3 tBlend = rgbToHsl( iBlendColor );
return hslToRgb( vec3( tBlend.r, tBlend.g, rgbToHsl(iBaseColor).b ) );
}
void main() {
// GENERAL:
vec2 tCoord = gl_TexCoord[0].xy;
vec4 tBaseColor = texture2D( tex, tCoord );
// Example output:
vec4 tColorA = contrastSaturationBrightness( vec4( bloomFilter( tex, tCoord, vec2( 512, 512 ), 5, 2.5, vec4( 1.0, 1.0, 1.0, 1.0 ) ).rgb, squircledRect( tCoord, 8.0 ) ), 1.0, 3.0, 1.0 );
gl_FragColor = tColorA;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment