Я использую 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 / x64double
арифметика не заметно медленнее, чем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