shader编程经典:分形--科赫曲线
序言
科赫(雪花)曲线是一个经典分形图案,来一起领略下分形之美。本篇内容用到一些基础的内容,例如UV的理解和画线技巧,有需要的话可以参考合集的画圆和画线两篇文章。
示例
shadertoy 代码:
#define T .01
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = (fragCoord.xy-0.5 * iResolution.xy) / iResolution.y;
vec3 col = vec3(0.);
float a = (4. / 6.) * 3.1415926;
vec2 n = vec2(sin(a), cos(a));
float s = 1.;
int t = int(sin(iTime) * 2. + 3.);
uv.x += .5;
uv.y += .25;
for (int i = 0; i < t; i++ )
{
s *= 3.;
uv *= 3.;
uv.x -= 1.5;
uv.x = abs(uv.x);
uv.x -= 0.5;
uv -= n * min(0., dot(uv, n)) * 2.;
}
float d = length(uv - vec2(clamp(uv.x, -1., 1.), 0.));
col += smoothstep(T, .0, d/s);
fragColor = vec4(col, 1.);
}
注解
先简化一下问题--只考虑一次迭代
观察到上述代码有偏移和对称,其实我们只需要关心对称轴的一侧,来看图像的左半边的绘制
它大概的形状如上图中的绿色线所示,观察负半轴,负半轴绿色的线可以有紫色线沿着蓝色线为对称轴反转得到,之反转原理如下
(对应上述代码 uv -= n * min(0., dot(uv, n)) * 2.)
- y 假设是对称轴
- n 是y的法线(单位向量)
- uv 是当前uv所在的位置
则dot(uv, n) * n 是u',这里稍微解释下
点乘的公式:dot(a, b) = |a||b|cosθ,a是单位向量,则dot(a, b) = |b|cosθ = |b'|,b'向量 = a * |b'|
u'与b'同理
易求得uv'' = -dot(uv, n) * n * 2.
uv -= dot(uv, n) * n * 2. 即从原uv点移动到了uv''所指的位置,从而画出绿线
再考虑多次迭代,其实就是不断重复上述过程,迭代uv,实现自相似(分形),其他的都比较好理解,相信大家仔细看看都能明白就不赘述了。