基本的分形着色问题

时间:2018-04-05 16:29:23

标签: graphics glsl fractals

我正在尝试更好地掌握分形着色背后的数学并更好地理解着色算法。我是以下文件:

http://jussiharkonen.com/files/on_fractal_coloring_techniques%28lo-res%29.pdf

本文给出了每个函数的具体参数,但是当我使用它时,我的结果并不完全正确。我不知道会发生什么。

我正在使用迭代计数着色算法来启动和使用以下julia集:

c = 0.5 + 0.25i and p = 2 

使用着色算法:

The coloring function simply returns the number of
elements in the truncated orbit divided by 20

调色板功能:

I(u) = k(u − u0),
where k = 2.5 and u0 = 0, was used.

调色板在0和1处为白色,并在其间插入黑色。

并遵循此算法:

  1. 将z0设置为对应于复平面中像素的位置。
  2. 通过迭代公式zn = f(zn-1)开始计算截断轨道 从z0到任何一个 •| zn | > M,或 •n = Nmax, 其中Nmax是最大迭代次数。
  3. 使用着色和颜色索引功能,映射生成的截断 轨道到颜色指数值。
  4. 使用调色板功能
  5. 确定像素的RGB颜色

    使用此代码如下所示:

    float izoom = pow(1.001, zoom );
    
    vec2 z = focusPoint + (uv * 4.0 - 2.0)  * 1.0 / izoom;
    
    vec2 c = vec2(0.5f, 0.25f) ;
    
    
    const float B = 2.0;
    float l;
    
    for( int i=0; i<100; i++ )
    {
         z = vec2( z.x*z.x - z.y*z.y, 2.0*z.x*z.y ) + c;
    
         if( length(z)>10.0) break;
         l++;
    
    }
    float ind = basicindex(l);
    vec4 col = color(ind);
    

    并具有以下索引和着色功能:

    float basicindex(float val){
        return val / 20.0;
    }
    
    vec4 color(float index){
    
        float r  = 2.5 * index;
        float g = r; 
        float b = g;
        vec3 v = 0.5 - 0.5 *  sin(3.14/2.0 + 3.14 * vec3(r, g, b));
        return vec4(1.0 - v, 1.0) ;
    
    }
    

    本文提供以下图片: https://imgur.com/YIZMhaa

    虽然我的代码产生: https://imgur.com/OrxdMsN

    通过使用k = 1.0而不是2.5来获得正确的结果,但我更愿意理解为什么我的结果不正确。当将其扩展为平滑着色算法时,我的结果仍然不正确,所以我想首先想出来。

    如果这不是这类问题的正确位置,请告诉我,我可以将其移至数学堆栈交换。我不确定哪个地方更合适。

1 个答案:

答案 0 :(得分:1)

本文完美实现了图3.3。您发布的另一张图片使用了不同的例程。

figure 3.3

你的数字似乎在顶部有一些透视代码,但删除它并且它们应该是相同的。

your result

如果您的异议是极端的颜色,您可以使用&#34; 0.5 - 0.5 * ...&#34;部分代码。这使得最暗的黑色最初为0.5,在示例图像中,您尝试复制最暗的黑色应为1,最亮的白色应为0.

您将白度等于0.5

的距离

如果你忽略了分形,你会得到一堆可以在0和1之间归一化的值,并且你会以某些特定的方式对它们进行着色。很明显,你复制的图像在0和1之间是线性的,所以将黑色设为0.5可能是不正确的。

&#13;
&#13;
o = {
    length : 500,
    width : 500,
    c : [.5, .25], // c = x + iy will be [x, y]
    maxIterate : 100,
    canvas : null
}

function point(pos, color){
    var c = 255 - Math.round((1 + Math.log(color)/Math.log(o.maxIterate)) * 255);
    c = c.toString(16);
    
    if (c.length == 1) c = '0'+c;
    o.canvas.fillStyle="#"+c+c+c;
    o.canvas.fillRect(pos[0], pos[1], 1, 1);
}

function conversion(x, y, R){
    var m = R / o.width;
    var x1 = m * (2 * x - o.width);
    var y2 = m * (o.width - 2 * y);
    return [x1, y2];
}

function f(z, c){
    return [z[0]*z[0] - z[1] * z[1] + c[0], 2 * z[0] * z[1] + c[1]];
}

function abs(z){
    return Math.sqrt(z[0]*z[0] + z[1]*z[1]);
}

function init(){
    var R = (1 + Math.sqrt(1+4*abs(o.c))) / 2,
        z, x, y, i;

    o.canvas = document.getElementById('a').getContext("2d");
    for (x = 0; x < o.width; x++){
        for (y = 0; y < o.length; y++){
            i = 0;
            z = conversion(x, y, R);
            while (i < o.maxIterate && abs(z) < R){
                z = f(z, o.c);
                if (abs(z) > R) break;
                i++;
            }
            

            if (i) point([x, y], i / o.maxIterate);
        }
    }
}

init();
&#13;
<canvas id="a" width="500" height="500"></canvas>
&#13;
&#13;
&#13;

通过:http://jsfiddle.net/3fnB6/29/