2D SDF运算4_复制

200 阅读1分钟

image.png 通过对坐标空间的变换,完成一系列的效果。本文主要学习资料为

Mirror

最简单的就是基于Y Axis做镜像,

vec2 mirror( in vec2 p)
{
    p.x = abs(p.x);
    return p;
}

20240523-2dsdf_space_maipulation.png

当然我们可以通过unionrotate 达到类似于任意axis 镜像的效果

vec2 mirror2(in vec2 p) {
    float angle = sin(iTime) * 6.18;
    mat2 rotaion = mat2(
        cos(angle), -sin(angle),
        sin(angle), cos(angle)
    );
    return rotaion*p;
}

    
    // mirror2 
    float dist = circleAndBox(uv);;
    float dist2 = circleAndBox(mirror2(uv));
    dist = min(dist, dist2);

20240523-2dsdf_space_maipulation_lossy.gif

Repeat

shadertoy: www.shadertoy.com/view/M3t3z7

最简单就是将某个纬度不停的重复,就像下面这个函数,将x的值重复到了[-0.5, 0.5]之间。

vec2 repeat1( vec2 p )
{
    p.x = p.x - round(p.x);
	return p;
}

05234654-2dsdf_space_maipulation.png

当然也可以在两个纬度上进行这个操作

vec2 repeat2( vec2 p )
{
	return p- round(p );
}

05234736-2dsdf_space_maipulation.png

如果需要控制重复的频率,那么可以使用以下函数

vec2 repeat3( vec2 p, float rows )
{
    vec2 q = p * rows/2.0  ;
    q = mod(q, 1.);
    q = q * 2.0 - 1.0;
    return q;
}

05234808 2dsdf space maipulation

以上都是通过在直角坐标系下将两个axis值的范围从 [,][-\infty, \infty], 重复mod到[1,1][-1, 1]. 如果这个mod操作是针对极坐标下极角,那么会获得旋转重复的效果

vec2 polarRepeat(vec2 p, float cells) {
    const float PI = 3.141592653;
    float cellSize = PI * 2. / cells;
    vec2 polarP = vec2(atan(p.x, p.y), length(p));
    polarP.x = mod(mod(polarP.x, cellSize) + cellSize, cellSize);
    p.x = sin(polarP.x);
    p.y = cos(polarP.x);
    p = p * polarP.y;
    return p;
}

202405230245 2dsdf space maipulation