A shader test for vkrunner that draws a voronoi tunnel.
[require] | |
fbsize 800 600 | |
[vertex shader passthrough] | |
[fragment shader] | |
#version 450 | |
layout(location = 0) out vec4 out_color; | |
#define M_PI 3.141592653589793 | |
const vec2 res = vec2(800.0, 600.0); | |
const float aspect = 1.3333333; | |
const vec2 center = vec2(0.5 * aspect, 0.5); | |
vec4 voronoi(in vec2 uv); | |
vec3 hsv2rgb(in vec3 c) | |
{ | |
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | |
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); | |
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); | |
} | |
vec3 gcolorhsv(in vec3 c) | |
{ | |
return c / vec3(360.0, 100.0, 100.0); | |
} | |
vec3 texture(in vec2 uv) | |
{ | |
vec4 v = voronoi(uv); | |
vec3 chsv = gcolorhsv(vec3(201.0, 66.0, 93.0)); | |
chsv.x = chsv.x + v.x * 0.3; | |
chsv = chsv * smoothstep(-1.0, 1.0, pow(v.w, 3.0) * 0.5 + 0.5); | |
return hsv2rgb(chsv); | |
} | |
void main() | |
{ | |
vec2 uv = gl_FragCoord.xy / res * vec2(aspect, 1.0); | |
vec2 v = uv - center; | |
float angle = atan(v.y, v.x); | |
float polar_x = angle * 0.5 / M_PI + 0.5; | |
float polar_y = sqrt(dot(v, v)); | |
float depth = 2.0 / polar_y; | |
vec2 tex_uv; | |
tex_uv.x = min(polar_x * 2.0, 2.0 - polar_x * 2.0) * 14.0; | |
tex_uv.y = depth * 4.0; | |
float fog = clamp(35.0 / pow(depth, 2.5), 0.0, 1.0); | |
out_color.rgb = texture(tex_uv) * fog; | |
out_color.a = 1.0; | |
} | |
// modification of this noise function by Inigo Quilez: | |
// https://www.shadertoy.com/view/XsXfRH | |
float hash(in vec2 p) | |
{ | |
p = 50.0 * fract(p * 0.3183099 + vec2(0.71, 0.113)); | |
return -1.0 + 2.0 * fract(p.x * p.y * (p.x + p.y)); | |
} | |
float noised(in vec2 x) | |
{ | |
vec2 p = floor(x); | |
vec2 w = fract(x); | |
#if 0 | |
// quintic interpolation | |
vec2 u = w*w*w*(w*(w*6.0-15.0)+10.0); | |
vec2 du = 30.0*w*w*(w*(w-2.0)+1.0); | |
#else | |
// cubic interpolation | |
vec2 u = w*w*(3.0-2.0*w); | |
vec2 du = 6.0*w*(1.0-w); | |
#endif | |
float a = hash(p+vec2(0.0,0.0)); | |
float b = hash(p+vec2(1.0,0.0)); | |
float c = hash(p+vec2(0.0,1.0)); | |
float d = hash(p+vec2(1.0,1.0)); | |
float k0 = a; | |
float k1 = b - a; | |
float k2 = c - a; | |
float k3 = a - b - c + d; | |
return k0 + k1 * u.x + k2 * u.y + k3 * u.x * u.y; | |
} | |
vec2 v2noise(in vec2 uv) | |
{ | |
return vec2(noised(uv + vec2(132.47, 821.12)), noised(uv)); | |
} | |
vec3 v3noise(in vec2 uv) | |
{ | |
return vec3(noised(uv + vec2(828.7, 21.12)), | |
noised(uv + vec2(13.258, 12.57)), | |
noised(uv + vec2(324.61, 57.8))); | |
} | |
// modified version of the following one by Inigo Quilez: | |
// http://www.iquilezles.org/www/articles/smoothvoronoi/smoothvoronoi.htm | |
vec4 voronoi(in vec2 uv) | |
{ | |
ivec2 p = ivec2(floor(uv)); | |
vec2 f = fract(uv); | |
float res = 8.0; | |
ivec2 cell = p; | |
for(int j=-1; j<=1; j++) { | |
for(int i=-1; i<=1; i++) { | |
ivec2 b = ivec2(i, j); | |
vec2 r = vec2(b) - f + v2noise(p + b) * 0.5 + 0.5; | |
float d = dot(r, r); | |
if(d < res) { | |
res = d; | |
cell = p + b; | |
} | |
} | |
} | |
return vec4(v3noise(vec2(cell)) * 0.5 + 0.5, sqrt(res)); | |
} | |
[test] | |
draw rect -1 -1 2 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment