通过对坐标空间的变换,完成一系列的效果。本文主要学习资料为
- IQ 3D SDF iquilezles.org/articles/di…
- RONJA 2D SDF www.ronja-tutorials.com/post/036-sd…
Mirror
最简单的就是基于Y Axis做镜像,
vec2 mirror( in vec2 p)
{
p.x = abs(p.x);
return p;
}
当然我们可以通过union加rotate 达到类似于任意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);
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;
}
当然也可以在两个纬度上进行这个操作
vec2 repeat2( vec2 p )
{
return p- round(p );
}
如果需要控制重复的频率,那么可以使用以下函数
vec2 repeat3( vec2 p, float rows )
{
vec2 q = p * rows/2.0 ;
q = mod(q, 1.);
q = q * 2.0 - 1.0;
return q;
}
以上都是通过在直角坐标系下将两个axis值的范围从 , 重复mod到. 如果这个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;
}