voronoi 细胞边界距离

https://www.shadertoy.com/view/lXt3R2

Shader code
shader_type canvas_item;


uniform vec4 color = vec4(0.0,0.0,0.0,1.0);
uniform float scale : hint_range(0.1, 5.0, 0.1) = 1;
uniform vec2 disp = vec2(0.0, 0.0);
uniform float speed : hint_range(0.1, 5.0, 0.1) = 1.0;
uniform float nucleus = 1.0;
uniform float contrast : hint_range(0.0, 5.0, 0.1) = 0.5;
uniform float line : hint_range(0.0, 5.0, 0.1) = 1.0;
uniform float layer1 : hint_range(0.0, 5.0, 0.1) = 1.0;
uniform float layer2 : hint_range(0.0, 2.0, 0.1) = 1.0;

#define iTime TIME * speed
#define iResolution 1.0/ SCREEN_PIXEL_SIZE

varying vec4 iMouse;
float hash12(vec2 p)
{
        vec3 p3  = fract(vec3(p.xyx) * .1031);
        p3 += dot(p3, p3.zyx + 33.33);
        return fract((p3.x + p3.y) * p3.z);
}

// 轨迹半径
float rcel(vec2 ip){return mix(.25,.45, hash12(ip+.2));}                                      

vec2 cell(vec2 ip)
{// 求细胞核位置
        float ag = 6.28*hash12(ip + 1.23) + 5.*iTime ;//  * mix(.5,1.5,hash12(ip+3.));// 不同转速,有误差, 数字大点差就大了?                  
        return vec2(cos(ag), sin(ag)) * rcel(ip);
}

void fragment()
{
        vec4 O = color;
		float ratio = SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y;
        vec2 U = (SCREEN_UV-disp) * 1000.0 * scale / vec2(ratio, 1.0);
        #define bl if(iMouse.x < iResolution.x * .52)
        vec2 R = iResolution.xy,
             u = 3.*(U + U - R) / R.y+vec2(0,iTime),
             g =(u-.5)- round(u-.5);
        // 画格子
        g = abs(g); if( g.x<g.y )g = g.yx;
        bl O += .4 * exp(-1e2 * g.y) * layer1;
        // 原点
        bl O += exp(-1e2 * length(u)) * layer1;
        
        vec2 p  = u,
             ip = round(p),
             fp = p - ip,
             ct;
        
        //ct = normalize(hash22(ip))*rc;
        ct = cell(ip);
        
        // 细胞核轨迹
        O.x += exp(-30. * length(fp - ct)) * nucleus;
        bl O += .2 * exp(-99. * abs(length(fp) - rcel(ip))) * layer1 ;
        
        // 参考:https://iquilezles.org/articles/voronoilinex/
        // 找最近细胞核
        vec2 a,ia;
        float i,j,md=1e8,d;
        for(float j=-1.;j<2.;j++)
        for(float i=-1.;i<2.;i++)
        {
                vec2 e = ip + vec2(i,j),
                     c = cell(e)+e;
                d = length(c-p);
                if(d<md)
                {
                        md = d;
                        ia = e; // 正方形中心
                        a  = c; // 细胞核位置
                }
        }
        // 细胞上色,点 p 在细胞 a 里
        O += mix(vec4(.5,0,(ia.y-iTime)/2.,1)+.3,vec4(0,.3,(ia.x-0.)*.3,0)+.2,hash12(ia) ) * layer2;
        
        // 求到相交边界的距离
        md=1e8;
        for(float j=-2.;j<=2.;j++)
        for(float i=-2.;i<=2.;i++)
        {
                if(abs(i)+abs(j)>.1) // 不在原点,不跟自己比较
                //if(length(vec2(i,j))>.1)
                {
                        vec2 e = ia + vec2(i,j), // 邻居所在正方形
                             b = cell(e)+e;      // 第二细胞核位置
                        d = dot( p- (a+b)/2., normalize(a-b));
                        md=min(md, d);//md=min(md,abs(d));
                }
        }
        
        // 线框
        d = 10. * clamp(exp(-2e2*md), 0., 1.) * layer2;
        
        // 条纹
        d += .1* clamp(exp(-2e2*cos(80.*md)), 0., 1.) * line;
        
        O = (max(O-contrast*d,0.)+d );
		COLOR = vec4(O);
		COLOR.a *= color.a;
}
Live Preview
Tags
voronoi
This shader is a port from an existing Shadertoy project. Shadertoy shaders are by default protected under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) license unless anything else has been stated by the author. For more info, see our License terms.

More from RayL019

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments