raylib的glsl分形着色器工作不正常



https://github.com/bananaboy139/fractal/tree/OpenGL-shader

https://github.com/bananaboy139/fractal/blob/OpenGL-shader/images/2.png?raw=true这是我用zig制作的原始图像。

https://github.com/bananaboy139/fractal/blob/OpenGL-shader/images/I%20dont%20know%20发生了什么%20part%202.png?原始=真这是我从着色器中得到的图像。

(我不能发布图片,我没有10个声誉(

它应该迭代于z^{3}-1的牛顿优化并且使用像素的坐标作为z的复数。

我从使用zig来计算它变成了使用着色器,因为zig太慢了,无法用来探索分形。有了着色器,它会更快,唯一的问题是它错了。我认为问题出在我对复数的实现上,但我不知道在哪里。

欧拉形式表示为半径*e^{i*theta}笛卡尔是经典的a+bi

这是着色器:

#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
uniform vec2 screenDims;
uniform float acceptable_err;
uniform int max_trial;
uniform vec2 offset;
uniform float zoom;
out vec4 color;

const float PI = 3.1415926535;
struct Complex_cartesian {
float re;
float im;
};
struct Complex_euler {
float radius;
float theta;
};
//cartesian to euler
Complex_euler C_c__to__C_e(Complex_cartesian z) {
float r = sqrt(pow(z.re, 2) + pow(z.im, 2));
float t = atan(z.im/z.re);
return(Complex_euler(r, t));
}
//euler to cartesian
Complex_cartesian C_e__to__C_c(Complex_euler z) {
float a = z.radius * cos(z.theta);
float b = z.radius * sin(z.theta);
return(Complex_cartesian(a, b));
}
//complex addition
Complex_cartesian C_add(Complex_cartesian z_1, Complex_cartesian z_2) {
return(Complex_cartesian(z_1.re + z_2.re, z_1.im + z_2.im));
}
//complex subtraction
Complex_cartesian C_sub(Complex_cartesian z_1, Complex_cartesian z_2) {
return(Complex_cartesian(z_1.re - z_2.re, z_1.im - z_2.im));
}
//complex division
Complex_euler C_div(Complex_euler z_1, Complex_euler z_2) {
return(Complex_euler(z_1.radius / z_2.radius, z_1.theta - z_2.theta));
}
//complex multiplication
Complex_euler C_mul(Complex_euler z_1, Complex_euler z_2) {
return(Complex_euler(z_1.radius * z_2.radius, z_1.theta + z_2.theta));
}
//complex powers
Complex_euler C_pow(Complex_euler z, float power) {
return(Complex_euler(pow(z.radius, power), z.theta * power));
}
//absolute answers
const Complex_euler z_1 = Complex_euler(1, 0);
const Complex_euler z_2 = Complex_euler(1, 2.0*PI/3.0);
const Complex_euler z_3 = Complex_euler(1, 4.0*PI/3.0);
const Complex_euler answers[3] = Complex_euler[3](z_1, z_2, z_3);
float check_err(Complex_cartesian guess, Complex_euler ans) {
Complex_cartesian Cart_ans = C_e__to__C_c(ans);
return(C_div(C_c__to__C_e(C_sub(Cart_ans, guess)), ans).radius);
}
float check(Complex_cartesian guess) {
float errs[3];
for (int i = 0; i < 3; i++) {
errs[i] = check_err(guess, answers[i]);
}
//really cool sort 2.0
if (errs[1] > errs[2]) {
errs[1] = errs[2];
}
if (errs[0] > errs[1]) {
errs [0] = errs[1];
}
return(errs[0]);
}
Complex_euler optimized(Complex_euler z) {
//2z^3+1 / 3*z^2
Complex_cartesian top = C_add(C_e__to__C_c(C_mul(Complex_euler(2, 0), C_pow(z, 3))), Complex_cartesian(1, 0));
Complex_euler bottom = C_mul(Complex_euler(3, 0), C_pow(z, 2));
return(C_div(C_c__to__C_e(top), bottom));
}
void main() {
Complex_cartesian coor = Complex_cartesian((fragTexCoord.x + offset.x/screenDims.x)/zoom, (fragTexCoord.y + offset.y/screenDims.y)/zoom);
Complex_euler z = C_c__to__C_e(coor);
float trial = 0.0;
while ((check(C_e__to__C_c(z)) > acceptable_err) && (trial < max_trial)) {
z = optimized(z);
trial += 1;
}
trial /= 500;
// trial *= 10;
color = vec4(trial, trial, trial, 1);
}

https://www.shadertoy.com/view/fldBWN

我认为主要问题在于atan函数。为了从一个方向获得全360度的角度,通常使用atan(y, x)(在其他编程语言中也称为"atan2"(,而x/y的反正切是模糊的。

最新更新