Last active
April 12, 2022 06:09
-
-
Save zach-klippenstein/f92f7d59c1bdabcda67a3aed51a3fe3a to your computer and use it in GitHub Desktop.
SkSL shader program to render a comic-book style effect.
This file contains hidden or 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
// Paste this code into shaders.skia.org | |
float tileSize = 12; | |
float dotMinDiameter = 9; | |
vec2 maxRedShift = vec2(-2, 3); | |
vec2 maxGreenShift = vec2(2.5, 0); | |
vec2 maxBlueShift = vec2(1, -2); | |
half3 baseColor = half3(0, 0, 0); | |
half4 main(vec2 fragcoord) { | |
float maxDimension = max(iResolution.x, iResolution.y); | |
float focalSizeCutoff = maxDimension / 2; | |
float focalChromaticCutoff = maxDimension; | |
vec2 focalPoint = iMouse.xy; | |
vec2 tileIndex = vec2( | |
floor(fragcoord.x / tileSize), | |
floor(fragcoord.y / tileSize) | |
); | |
vec2 tileOrigin = tileIndex * tileSize; | |
vec2 tileCoord = fragcoord - tileOrigin; | |
vec2 tileCenter = vec2(tileSize / 2, tileSize / 2); | |
// Take a sample of the source's color from the center of the tile. | |
vec2 sampleCoord = tileOrigin + tileCenter; | |
half4 sampleColor = iImage1.eval(sampleCoord); | |
// Modulate the size of the dot by the mouse position. | |
float distFromMouse = distance(fragcoord, focalPoint.xy); | |
float dotRadius = max( | |
dotMinDiameter / 2, | |
mix(tileSize / 2, 0, distFromMouse / focalSizeCutoff) | |
); | |
// Chromatic aberration | |
float sampleRed = sampleColor.r; | |
float sampleGreen = sampleColor.g; | |
float sampleBlue = sampleColor.b; | |
// …also modulated by mouse position. | |
vec2 redShift = maxRedShift * distFromMouse / focalChromaticCutoff; | |
vec2 greenShift = maxGreenShift * distFromMouse / focalChromaticCutoff; | |
vec2 blueShift = maxBlueShift * distFromMouse / focalChromaticCutoff; | |
float distRed = distance(tileCoord, tileCenter + redShift); | |
float distGreen = distance(tileCoord, tileCenter + greenShift); | |
float distBlue = distance(tileCoord, tileCenter + blueShift); | |
return half4( | |
distRed <= dotRadius ? sampleRed : baseColor.r, | |
distGreen <= dotRadius ? sampleGreen : baseColor.g, | |
distBlue <= dotRadius ? sampleBlue : baseColor.b, | |
sampleColor.a | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment