Last active
July 7, 2021 12:59
-
-
Save Hebali/5950485 to your computer and use it in GitHub Desktop.
Quick GLSL sketch heading towards a more generalized tool...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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