Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Halftone shader example for Tangram
# 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
You can’t perform that action at this time.