webgl+lil-gui实现可调节参数的眼珠眼睛图案背景动画效果代码
代码语言:html
所属分类:背景
代码描述:webgl+lil-gui实现可调节参数的眼珠眼睛图案背景动画效果代码
代码标签: webgl lil-gui 调节 参数 眼珠 图案 背景 动画 眼睛
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body, html { margin: 0; padding: 0; overflow: hidden; } canvas#eyes-pattern { display: block; width: 100%; } .lil-gui { --width: 450px; max-width: 90%; --widget-height: 20px; font-size: 15px; --input-font-size: 15px; --padding: 10px; --spacing: 10px; --slider-knob-width: 5px; --background-color: rgba(5, 0, 15, .8); --widget-color: rgba(255, 255, 255, .3); --focus-color: rgba(255, 255, 255, .4); --hover-color: rgba(255, 255, 255, .5); --font-family: monospace; } .lil-gui.autoPlace { top: 50%; left: 50%; transform-origin: center center; transform: translate(-50%, -50%); } </style> </head> <body translate="no"> <canvas id="eyes-pattern"></canvas> <script type="x-shader/x-fragment" id="vertShader"> precision mediump float; varying vec2 vUv; attribute vec2 a_position; void main() { vUv = .5 * (a_position + 1.); gl_Position = vec4(a_position, 0.0, 1.0); } </script> <script type="x-shader/x-fragment" id="fragShader"> precision mediump float; varying vec2 vUv; uniform float u_scale; uniform float u_time; uniform float u_speed; uniform float u_ratio; uniform float u_saturation; uniform float u_redness; uniform float u_blue_ratio; uniform vec2 u_pointer; #define TWO_PI 6.28318530718 // ================================================= // cell-related helpers vec2 hash(vec2 p) { p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); return fract(sin(p)*18.5453); } // polynomial-based smooth minimum; // used for rounded Voronoi shaping float smin(float angle, float b, float k) { float h = clamp(.5 + .5 * (b - angle) / k, 0., 1.); return mix(b, angle, h) - k * h * (1. - h); } // ================================================= // eye-related helpers float rand(vec2 n) { return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); } float noise(vec2 n) { const vec2 d = vec2(0.0, 1.0); vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n)); return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y); } float fbm(vec2 n) { float total = 0.0, amplitude = .4; for (int i = 0; i < 4; i++) { total += noise(n) * amplitude; n += n; amplitude *= 0.6; } return total; } vec3 hsv2rgb(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 eye_pattern(vec2 uv, float tile_time, float pointer_angle, float pointer_distance) { // tiles coordinates vec2 i_uv = floor(uv); vec2 f_uv = fract(uv); // outputs vec2 randomizer = vec2(0.); vec3 distance = vec3(1.); float angle = 0.; // get Voronoi cell data for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { vec2 tile_offset = vec2(float(x), float(y)); vec2 blick_tile_offset = tile_offset; vec2 o = hash(i_uv + tile_offset); tile_offset += (.5 + (.25 + pointer_distance) * sin(tile_time + TWO_PI * o)) - f_uv; blick_tile_offset += (.9 - f_uv); float dist = dot(tile_offset, tile_offset); float old_min_dist = distance.x; distance.z = max(distance.x, max(distance.y, min(distance.z, dist))); distance.y = max(distance.x, min(distance.y, dist)); distance.x = min(distance.x, dist); if (old_min_dist > distance.x) { angle = atan(tile_offset.x, tile_offset.y); randomizer = o; } } } distance = sqrt(distance); distance = sqrt(distance); float cell_shape = min(smin(distance.z, distance.y, .1) - distance.x, 1.); float cell_radius = distance.x; float eye_radius = 2. * cell_radius - .5 * cell_shape; // at this point, we have // -- randomizer (x2) // -- angle to use as polar coordinate // -- cell_shape - Voronoi cell w/ rounded endges // -- cell_radius - exact circle in the mid of cell // -- eye_radius - mix of two // ============================================================ float redness_angle = angle * 2. + randomizer.y; float eye_ball_redness = fbm(vec2(redness_angle, cell_shape * 3.)); eye_ball_redness *= pow(cell_radius, 1. / u_redness); // more on edges eye_ball_redness *= randomizer.y; // less for some cells eye_ball_redness *= (1. - smoothstep(5., 6.6, redness_angle) - smoothstep(-4.3, -5.7, redness_angle)); vec3 eye_ball_color = vec3(1., 1. - eye_ball_redness, 1. - eye_ball_redness); // iris color float iris_color_1_hue = (1. - u_blue_ratio) * pow(randomizer.x, 3. - 2. * u_blue_ratio) + u_blue_ratio * pow(randomizer.x, 1.3 - u_blue_ratio); iris_color_1_hue = mix(.07, .59, iris_color_1_hue); vec3 iris_color_1 = hsv2rgb(vec3(iris_color_1_hue, u_saturation, .5 + iris_color_1_hue)); vec3 iris_color_2 = hsv2rgb(vec3(.67 * randomizer.x - .1 * randomizer.y, .5, .1 + .2 * randomizer.y)); float outer_color_noise = fbm(vec2(angle * 4., cell_radius)); vec3 color = iris_color_1; color = mix(color, iris_color_2, outer_color_noise); vec3 iris_center_color = hsv2rgb(vec3(.2 - .1 * randomizer.y, u_saturation, .5)); color = mix(iris_center_color, color, smoothstep(.05 + randomizer.y * .25, .45, cell_radius - .2 * pointer_distance)); float white_incertion_noise = smoothstep(.4, 1., fbm(vec2(8. * angle, 10. * cell_shape))); white_incertion_noise *= (.9 + .5 * randomizer.x); color = mix(color, vec3(1.), white_incertion_noise); float dark_incertion_noise = smoothstep(.5, 1., fbm(vec2(3. * angle, 11. * cell_shape))); color = mix(color, vec3(0.), dark_incertion_noise); // dark pupil float pupil_shape = smoothstep.........完整代码请登录后点击上方下载按钮下载查看
网友评论0