Mandelbrot使用LOVE2d通过GLSL中的着色器设置渲染圆,而不是分形

Mandelbrot使用LOVE2d通过GLSL中的着色器设置渲染圆,而不是分形,glsl,fractals,love2d,mandelbrot,Glsl,Fractals,Love2d,Mandelbrot,我正在尝试使用GLSL渲染Mandelbrot集,但我得到的只是一个完整的圆。。。 我已经检查了很多数学题,但我根本找不到错误,所以我想可能是语义问题 有人能看到出了什么问题吗 还有,有人能给我一些关于组织、结构等方面的见解吗?我正在努力学习正确的编码,但很难找到关于样式的材料 Obs.:着色器可以应用于任何图像 想法很简单(你可以跳过这个): 如果z未发散(即abs(z)

我正在尝试使用GLSL渲染Mandelbrot集,但我得到的只是一个完整的圆。。。 我已经检查了很多数学题,但我根本找不到错误,所以我想可能是语义问题

有人能看到出了什么问题吗

还有,有人能给我一些关于组织、结构等方面的见解吗?我正在努力学习正确的编码,但很难找到关于样式的材料

Obs.:着色器可以应用于任何图像

想法很简单(你可以跳过这个):

  • 如果z未发散(即abs(z)<4),则checkConvergence返回true
    • sumSquare返回复数乘法(z.r,z.i)*(z.r,z.i)-(c.r,c.i),其中K.r=Re(K)和K.i=Im(K)
    • iterate是实际的算法:它保持z平方,直到它发散或达到最大迭代次数(tol)
    • clr是一个参数化函数,它返回一个依赖于n的RGB数组
    • 最后,效果是魔术应该发生的地方,通过做两件事:
      • 它将像素(GLSL)的坐标规格化为间隔(0,1),并将其规格化为Mandelbrot集大小(-2)
      • 它调用clr对坐标进行迭代
GLSLShader=love.graphics.newShader[[
vec2c=vec2(1.0,0.0);
int-tol=100;
vec4黑色=vec4(0.0,0.0,0.0,1.0);
vec4白色=vec4(1.0,1.0,1.0,1.0);
布尔校验收敛(vec2z){
返回(z[0]*z[0]+z[1]*z[1]<4);
}
vec2平方米(vec2 z){
返回vec2(z[0]*z[0]-z[1]*z[1]-c[0],2*z[0]*z[1]-c[1]);
}
整数迭代(vec2z){
int n=0;
while(校验收敛(z)&(n255){r=255;}
否则{
如果(r 255){g=255;}
否则{
如果(g255){b=255;}
否则{
如果(b1 | | n<0){返回绿色;}
int r,g,b;
r=int(255*n+47*(1-n));
g=int(180*n+136*(1-n));
b=int(38*n+255*(1-n));
返回向量4(r,g,b,1.0);
}
vec4效果(vec4颜色、图像纹理、vec2纹理协调、vec2屏幕协调){
vec2z=vec2(纹理坐标x*4-2,纹理坐标y*4-2);
返回clr(迭代(z));
}

迭代的起始点应作为向量c传递,而z从{0.0.0}开始

正如你在

复数c是Mandelbrot集合的一部分,如果 当z=0且反复应用迭代z=z²+c时,则 无论n变得多大,z的绝对值都保持有界

对于颜色,您使用的是vec4,但在代码中,您使用的是整数值计算RGB分量,而不是float。您应该强制转换为float,并将每个分量规格化为(0.0,1.0)范围。我试图更正您的代码,但我恐怕不太了解lua或love2d,而且我无法使用纹理坐标,所以我使用了屏幕坐标。我能做的最好的事情是:

function love.load()
    GLSLShader = love.graphics.newShader[[

        vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
        vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
        int max_iter = 1024;

        vec4 clr(int n){
            if(n == max_iter){return black;}

            float m = float(n)/float(max_iter);
            float r = float(mod(n,256))/32;
            float g = float(128 - mod(n+64,127))/255;
            float b = float(127 + mod(n,64))/255;

            if (r > 1.0) {r = 1.0;}
            else{ 
                if(r<0){r = 0;}
            }

            if (g > 1.0) {g = 1.0;}
            else{
                if(g<0){g = 0;}
            }

            if (b > 1.0) {b = 1.0;}
            else{
                if(b<0){b = 0;}
            }
            return vec4(r, g, b, 1.0);
        }

        vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords){

            vec2 c = vec2((screen_coords[0]-500)/200,(screen_coords[1]-300)/200);
            vec2 z = vec2(0.0,0.0);
            vec2 zn = vec2(0.0,0.0);
            int n_iter = 0;
            while ( (z[0]*z[0] + z[1]*z[1] < 4) &&  (n_iter < max_iter) ) {
                zn[0] = z[0]*z[0] - z[1]*z[1] + c[0];
                zn[1] = 2*z[0]*z[1] + c[1];
                z[0] = zn[0];
                z[1] = zn[1];
                n_iter++;
            }
            return clr(n_iter);
        }
    ]]
end

function love.draw()

    love.graphics.setShader(GLSLShader)
    love.graphics.rectangle('fill', 0,0,800,600)
    love.graphics.setShader()
end
函数love.load()
GLSLShader=love.graphics.newShader[[
vec4黑色=vec4(0.0,0.0,0.0,1.0);
vec4白色=vec4(1.0,1.0,1.0,1.0);
int max_iter=1024;
vec4 clr(内部网络){
如果(n==max_iter){返回黑色;}
浮动m=浮动(n)/浮动(最大值);
浮动r=浮动(模(n,256))/32;
浮点数g=浮点数(128-mod(n+64127))/255;
浮动b=浮动(127+mod(n,64))/255;
如果(r>1.0){r=1.0;}
否则{
如果(r1.0){g=1.0;}
否则{
如果(g1.0){b=1.0;}
否则{
如果(b)

去掉vec2,每次迭代都会声明一个新变量。除此之外,请遵循@Bob_uuuuu的一些建议(即迭代(vec2c))。

z不是对应于坐标的复数吗?z不是(x,y)=(1.2,-0.5)在空间中的给定点?每个迭代不是独立的吗?我不明白你的意思…z是对应于坐标的复数,但它的初始值是(0,0)。复数空间中的起始点,比如(1.2,-0.5)以c的形式传递给函数。请参见右侧的一个链接,甚至是我关于类似主题的另一个答案:使用(0,0)或(x,y)开始迭代只会产生1次迭代的差异,因为使用(0,0)开始时,函数值是(x,y)在第一次迭代之后。@WeatherVane是的。假设你可以从z=c开始,1次迭代的差异不是什么大问题。我在帖子中做了一个更新。谢谢你的帮助,但它不起作用:(你没有在每次迭代中减去c,你应该加上它。
f(z)=z²+c
n=n/tol
在整数算术中总是等于
0
,如果
n
(?)@BrettHale尝试了
float k=float(n)/tol;如果(k>1 | | k<0){返回绿色;}
和k而不是n,但仍然有一个黑色窗口
    vec2 c = vec2(0.0, 0.0);
    int tol = 1000;

    vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
    vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
    vec4 green = vec4(0.0, 1.0, 0.0, 1.0);

    int iterate(vec2 z) {
      int n = 0;

      while ( (z[0]*z[0] + z[1]*z[1] < 4) && (n < tol) ) {
        vec2 z =  vec2( z[0]*z[0] - z[1]*z[1]  + c[0], 2 * z[0] * z[1] + c[1] );
        n = n + 1;
      }

      return n;
    }

    vec4 clr(int n){
        n = n / tol;

        if(n == 1){return black;}
        if(n > 1 || n < 0){return green;}

        int r, g, b;
        r = int(255*n + 47*(1-n));
        g = int(180*n + 136*(1-n));
        b = int(38*n + 255*(1-n));

        return vec4(r, g, b, 1.0);

      }

    vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords){
      vec2 z = vec2(texture_coords.x*4-2, texture_coords.y*4-2);

      return clr(iterate(z));
    }
function love.load()
    GLSLShader = love.graphics.newShader[[

        vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
        vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
        int max_iter = 1024;

        vec4 clr(int n){
            if(n == max_iter){return black;}

            float m = float(n)/float(max_iter);
            float r = float(mod(n,256))/32;
            float g = float(128 - mod(n+64,127))/255;
            float b = float(127 + mod(n,64))/255;

            if (r > 1.0) {r = 1.0;}
            else{ 
                if(r<0){r = 0;}
            }

            if (g > 1.0) {g = 1.0;}
            else{
                if(g<0){g = 0;}
            }

            if (b > 1.0) {b = 1.0;}
            else{
                if(b<0){b = 0;}
            }
            return vec4(r, g, b, 1.0);
        }

        vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords){

            vec2 c = vec2((screen_coords[0]-500)/200,(screen_coords[1]-300)/200);
            vec2 z = vec2(0.0,0.0);
            vec2 zn = vec2(0.0,0.0);
            int n_iter = 0;
            while ( (z[0]*z[0] + z[1]*z[1] < 4) &&  (n_iter < max_iter) ) {
                zn[0] = z[0]*z[0] - z[1]*z[1] + c[0];
                zn[1] = 2*z[0]*z[1] + c[1];
                z[0] = zn[0];
                z[1] = zn[1];
                n_iter++;
            }
            return clr(n_iter);
        }
    ]]
end

function love.draw()

    love.graphics.setShader(GLSLShader)
    love.graphics.rectangle('fill', 0,0,800,600)
    love.graphics.setShader()
end
while ( ... ) {
    vec2 z = ...
}