我想知道这个微小的分形着色器背后的魔力;我不太了解代码和提到的线程...

是否有易于理解的说明?

https://www.shadertoy.com/view/4ttBWM

#1 楼

这是我的着色器的逐行细分:

#define mainImage(o,p)\
    for( vec2 r = iResolution.xy, q = 2.*(p+p-r)/r.y; o.a++ < 30.; )\
        o += length( q = abs(q)/dot(q,q) - iMouse.xy/r) / 2e2


首先,重要的是要知道前两行末尾的“ \”计数到字符计数,只是通过将代码分成多行来使代码更具可读性。

#define mainImage(o,p)


开始定义通常要编写的函数
避免mainImage(out fragColor,in fragCoord){...}
这样可以节省一些字符。

循环的第一部分:

vec2 r = iResolution.xy, q = 2.*(p+p-r)/r.y;


建立两个Vector2类型的变量:

r是允许我以后用更少的字符多次引用iResolution的分辨率。

q是从fragCoord p计算出的分形坐标,然后在每个循环中进行迭代。

而不是fragCoord从左下角的(0,0)开始并扩展到( rx,ry)(p + pr)转换每个fragCoord,以便ce屏幕的中间是(0,0)。这将使fragCoord值加倍,然后减去窗口的分辨率。最后,乘以2的结果只是缩小了2倍。

然后对于迭代器,我使用oa(alpha通道的o)。
o是vec4的输出颜色。根据Shadertoy的定义,o以值vec4(0,0,0,1)开头。我使用它是为了不需要使用将新的float声明为迭代器的字符。 o.a ++ <30在for循环中结合了测试表达式和迭代器。

循环的内容是一行,在输出颜色的每个通道上添加了一个数字。这行代码:

o += length( q = abs(q)/dot(q,q) - iMouse.xy/r) / 2e2


可以分解成几个部分。
分形中坐标的每次迭代都在这里发生:

q = abs(q)/dot(q,q) - iMouse.xy/r


其中iMouse.xy / r是一种将鼠标坐标从像素转换为(0,0)到(1,1)范围的方法

此函数的每次迭代都会更改要使用的q值。

产生此分形的想法是,q的某些初始值将逃逸到无穷大,而另一些将收敛或在几个小值附近循环。每次迭代都会根据q与(0,0)的距离来增加像素的亮度。然后将q的长度除以常数2e2(200),以防止o.rgb增长过快。

循环的内容可以理解为两个步骤:

q = abs(q)/dot(q,q) - iMouse.xy/r;
o += length(q) / 2e2;


最后,即使o在其通道之一中包含大于1的值,它也会被Shadertoy自动钳位,并且不需要尾随分号在最后一行。

评论


$ \ begingroup $
太好了!您如何找到此公式abs(q)/ dot(q,q)-iMouse.xy / r?是实证研究还是您有一种方法可以找到具有良好性能的公式?
$ \ endgroup $
– arthur.sw
18-10-23在21:20

$ \ begingroup $
@ arthur.sw我在这里找到了这个公式:链接,然后对其进行了修改以使其适合我的着色器。
$ \ endgroup $
– Mathmasterzach
18-10-24在1:57

$ \ begingroup $
如果您对打高尔夫球技术有兴趣,我们也为您提供网站...他们发布比赛挑战,但也接受标有“技巧”的问题,以提供有关打高尔夫球的一般建议或减少某些特定问题码。
$ \ endgroup $
– trichoplax
18-10-24在22:00