Last active
August 29, 2015 14:05
-
-
Save meetar/c67f8c0eff23f132990a to your computer and use it in GitHub Desktop.
Halftone shader example for Tangram
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
# Adapted from Stefan Gustavson's GLSL halftone shader demo for WebGL | |
# http://webstaff.itn.liu.se/~stegu/webglshadertutorial/shadertutorial.html | |
globals: | | |
uniform float dot_frequency; | |
uniform float dot_scale; | |
uniform bool true_color; | |
// Antialiasing | |
float aastep(float threshold, float value) { | |
const float scale = 2.; | |
const float y_rot = 0.; | |
float afwidth = dot_frequency * (1.0/200.0) / scale / cos(y_rot); | |
return smoothstep(threshold-afwidth, threshold+afwidth, value); | |
} | |
fragment: | | |
// Distance to nearest point in a grid of | |
// (frequency x frequency) points over the unit square | |
// Scale dot size for a subset of zoom | |
const float max_scale_zoom = 19.; | |
const float min_scale_zoom = 17.; | |
const float scale_zoom_factor = .25; | |
float zoom_frequency = dot_frequency; | |
zoom_frequency *= 1. + ((max_scale_zoom - clamp(u_map_zoom, min_scale_zoom, max_scale_zoom)) * scale_zoom_factor); | |
// Sample based on screenspace | |
const float pixel_scale = 695.; // arbitrary pixel_scale based on playing w/values | |
vec2 st = gl_FragCoord.xy / pixel_scale; | |
// But peg to map center so dots on ground plane stay in place as we move | |
const float dot_wrap = 1000.; | |
st += mod(u_map_center / u_meters_per_pixel, dot_wrap) / pixel_scale; | |
vec3 white = vec3(0.97); | |
vec3 black = vec3(0.1); | |
// Perform a rough RGB-to-CMYK conversion | |
vec4 cmyk; | |
cmyk.xyz = 1.0 - color; | |
cmyk.w = min(cmyk.x, min(cmyk.y, cmyk.z)); // Create K | |
if (!true_color) {cmyk.xyz -= cmyk.w;} // Subtract K equivalent from CMY | |
// Distance to nearest point in a grid of | |
// (frequency x frequency) points over the unit square | |
vec2 Kst = zoom_frequency*mat2(0.707, -0.707, 0.707, 0.707)*st; | |
vec2 Kuv = dot_scale*fract(Kst)-(dot_scale/2.); | |
float k = aastep(0.0, sqrt(cmyk.w)-length(Kuv)); | |
vec2 Cst = zoom_frequency*mat2(0.966, -0.259, 0.259, 0.966)*st; | |
vec2 Cuv = dot_scale*fract(Cst)-(dot_scale/2.); | |
float c = aastep(0.0, sqrt(cmyk.x)-length(Cuv)); | |
vec2 Mst = zoom_frequency*mat2(0.966, 0.259, -0.259, 0.966)*st; | |
vec2 Muv = dot_scale*fract(Mst)-(dot_scale/2.); | |
float m = aastep(0.0, sqrt(cmyk.y)-length(Muv)); | |
vec2 Yst = zoom_frequency*st; // 0 deg | |
vec2 Yuv = dot_scale*fract(Yst)-(dot_scale/2.); | |
float y = aastep(0.0, sqrt(cmyk.z)-length(Yuv)); | |
vec3 rgbscreen = 1.0 - 0.9*vec3(c,m,y); // most saturated color = .9 | |
rgbscreen = mix(rgbscreen, black, 0.85*k); // darkest black = .85 | |
color = rgbscreen; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment