Използвам SFML за c++ за генериране на набора на Манделброт. Действителната част от генерирането се извършва във фрагментния шейдър за производителност. Моля, имайте предвид, че нямам много опит с шейдърите.
По някаква причина, когато приближа над определена точка, това се случва.
Наистина няма много смисъл, тъй като не мащабирам нищо, а само настройвам параметри в генерирането. Най-доброто ми предположение е, че има нещо общо с рисуването на фрагменти, а не на пиксели.
Ето шейдъра на фрагменти (копирането/поставянето направи нещо странно с форматирането)
#version 400
uniform int window_width;
uniform int window_height;
uniform float x_translation;
uniform float y_translation;
uniform float zoom;
uniform int iterations = 255;
uniform int color;
float map(float n, float start1, float stop1, float start2, float stop2)
{
return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
}
void main()
{
float diversion_threshold = 4.0;
float saved_brightness = 0.0;
float real_translated_a = ((-2.0 - x_translation));
float real_translated_b = ((2.0 - x_translation));
float imaginary_translated_a = ((-2.0 + y_translation));
float imaginary_translated_b = ((2.0 + y_translation));
//float z_real = map(gl_FragCoord.x, 0.0, float(window_width), real_translated_a * zoom, real_translated_b * zoom);
//float z_imaginary = map(gl_FragCoord.y, 0.0, float(window_height), imaginary_translated_a * zoom, imaginary_translated_b * zoom);
float z_real = x_translation + (gl_FragCoord.x/window_width - 0.5) * zoom;
float z_imaginary = y_translation + (gl_FragCoord.y/window_height - 0.5) * zoom;
float z_real_original = z_real;
float z_imaginary_original = z_imaginary;
float z_real_temp;
float z_imaginary_temp;
float brightness = 0.0;
for (int n = 0;n <= iterations; n++) {
z_real_temp = z_real * z_real - z_imaginary * z_imaginary;
z_imaginary_temp = 2.0 * z_real * z_imaginary;
z_real = z_real_temp + z_real_original;
z_imaginary = z_imaginary_temp + z_imaginary_original;
if (color != 0)brightness = map(float(n), 0.0, float(iterations), 0.0, 1.0);
else brightness = map(float(n), 0.0, float(iterations), 1.0, 0.0);
brightness = map(sqrt(brightness), 0.0, 1.0, 0.0, 1.0);
if ((z_real * z_real + z_imaginary * z_imaginary) > diversion_threshold) {
break;
}
}
if (color == 0) gl_FragColor = vec4(brightness, brightness, brightness, 1.0);
if (color == 1) gl_FragColor = vec4(brightness, 0.0, 0.0, 1.0);
if (color == 2) gl_FragColor = vec4(0.0, 0.0, brightness, 1.0);
if (color == 3) gl_FragColor = vec4(0.0, brightness, 0.0, 1.0);
if (color == 4) gl_FragColor = vec4(brightness, 0.0, brightness * 0.67, 1.0);
if (color == 5) gl_FragColor = vec4(brightness * 0.1, brightness, brightness * 0.56, 1.0);
}
Шейдърът просто се прилага върху правоъгълник и това е всичко.
double
променливи вместоfloat
, но дори и тогава ще има момент, в който разделителната способност ще се провали. В зависимост от вашата платформа/компилатор може дори да имате типlong double
с разширена точност. Това ще стигне още по-дълбоко (но ще бъде забележимо по-бавно отfloat
илиdouble
). - person Adrian Mole   schedule 09.03.2021varying double
между връх и фрагмент. Така че всички дубли ще бъдат само във фрагментния шейдър и внимавайте, трябва да прехвърлите всички преобразувания междуdouble
иfloat
. Вижте също как да получа безкрайно малки числа (за фрактали). Вашият въпрос е ОК, но е дубликат, така че затворих гласуването - person Spektre   schedule 10.03.2021long double
е тип, определен от стандартите C и C+. При някои (много?) реализации, обаче, той е същият катоdouble
. Относно проблема със скоростта: не знам каква платформа използва OP, но на x86/x64 системи аритметикатаdouble
не е забележимо по-бавна отfloat
(единична точност). Но за тези системи, които прилагат 80- или 128-битовиlong double
типове, използвайки софтуерна емулация, тогаваlong double
аритметиката ще бъде много по-бавна, както казах в първия си коментар. Вижте например тук. - person Adrian Mole   schedule 10.03.2021brightness
вътре вfor
цикъла не е идеално. Това със сигурност може да се остави, докато не стане известен окончателният брой итерации. - person Adrian Mole   schedule 10.03.2021if else
, причиняващ забавяне, свързано с разклоняване, което при GLSL обикновено е голям удар във Fragment. - person Spektre   schedule 11.03.2021double
мога да стигна доzoom=10^14
, където започва да се появява пикселизация. - person Spektre   schedule 11.03.2021