Zurück zur Startseite

Mandelbrot-Animation: 80-Bit SSAA 8x8

Die Implementierung des Mandelbrot-Fraktal-Animationsgenerators verwendet 80-Bit-Arithmetik, 8×8 Supersampling und OpenMP, um hochqualitative Videos zu erstellen. Die zweistufige Pipeline optimiert Berechnungen, FFmpeg bietet professionelle Kodierung.

80-Bit Mandelbrot: Video mit SSAA 8×8 und OpenMP
Advertisement 728x90

Generierung von Mandelbrot-Fraktalanimationen mit 80-Bit-Präzision und SSAA

Das Programm generiert 255 Einzelbilder der Mandelbrot-Menge im BMP-Format bei 1920×1080 Auflösung und kompiliert sie zu einem MP4-Video mit 30 FPS. Die FFmpeg-Integration automatisiert die gesamte Pipeline: von den Fraktalberechnungen bis zum finalen Render. Die FFmpeg-Parameter sind optimiert, um Details zu erhalten: qp=20 gewährleistet hohe Qualität, pix_fmt yuv420p garantiert Kompatibilität und deblock=-6 minimiert Kompressionsartefakte.

Wichtige Befehlsoptionen:

  • -stream_loop 3: vier Animationsdurchläufe (Basis + 3 Wiederholungen)
  • -framerate 30: Eingabe-Bildrate
  • -color_range full: voller Helligkeitsbereich 0-255
  • no-psy: deaktiviert psycho-visuelle Verbesserungen für die Reinheit der Fraktalstrukturen

Tastenkürzel und Punktkoordinaten

Das Programm unterstützt die Auswahl aus 8 voreingestellten Bereichen der Menge oder das Laden von Parametern aus einer Mandelbrot.txt-Datei (Taste 9). Koordinaten werden mit 80-Bit-Präzision (long double) gesetzt:

Google AdInline article slot
case 1: absc = -0.5503432753421602L; ordi = -0.6259312704294012L; size_val = 0.0000000000004L; break;
case 2: absc = -0.691488093510181825L; ordi = -0.465680729473216972L; size_val = 0.000000000000003L; break;
case 3: absc = -0.550345905862346513L; ordi = 0.625931416301985337L; size_val = 0.000000000000005L; break;
case 4: absc = -1.78577278039667471L; ordi = -0.00000075696313293L; size_val = 0.000000000000004L; break;
case 5: absc = -1.785772754399825165L; ordi = -0.000000756806080773L; size_val = 0.0000000000000014L; break;
case 6: absc = -1.40353608594492038L; ordi = -0.02929181552009826L; size_val = 0.000000000000095L; break;
case 7: absc = -1.7485462508265219L; ordi = 0.000002213770706L; size_val = 0.00000000000029L; break;
case 8: absc = -1.94053809966024986L; ordi = -0.00000120260253359L; size_val = 0.00000000000003L; break;

80-Bit-Arithmetik und x87-FPU

Die Implementierung verwendet long double, um mit einem Skalierungsbereich von 10^18 zu arbeiten (gegenüber 10^14 für double). Die Hardware-Unterstützung für die x87-FPU gewährleistet maximale Berechnungsgenauigkeit ohne Software-Emulation. Dies ist kritisch für tiefe Zooms in Mini-Fraktale ohne Pixelbildung.

Vorteile der 80-Bit-Präzision:

  • +4 Dezimalstellen Genauigkeit
  • 10.000 Mal tiefere Skalierung als Standardimplementierungen
  • Direkte Nutzung von x87-Registern ohne Zwischenkonvertierungen

Parallelisierung mit OpenMP

OpenMP wird verwendet, um Iterationsberechnungsschleifen zu parallelisieren. Die Direktive #pragma omp parallel for schedule(dynamic) verteilt die Last effektiv auf die Kerne und gewährleistet Skalierbarkeit von 4-Kern-Systemen bis zu Servern mit 128 Threads.

Google AdInline article slot

8×8-Super-Sampling (64 Samples pro Pixel)

SSAA wird implementiert, indem bei ultra-hoher Auflösung 15360×8640 (8× das originale 1920×1080) gerendert wird. Jedes finale Pixel aggregiert 64 unabhängige Fraktal-Samples mit separaten RGB-Komponentenberechnungen.

Glättungsalgorithmus:

  • Berechnung der Iterationen für jedes Sub-Pixel in 80-Bit-Arithmetik
  • Unabhängige Färbung der Sub-Pixel mit Palettenrotation
  • Akkumulierung der R/G/B-Intensitäten (Kanaldurchschnitt)
  • Herunterskalieren auf die Zielauflösung

Ergebnis: kein chromatisches Rauschen, kinoreife Klarheit der Fraktalstrukturkanten.

Google AdInline article slot

Optimierte Einzelbildgenerierung

Die Pipeline ist in zwei Stufen unterteilt, um Berechnungen zu minimieren:

Stufe 1: Iterationskarte

  • Erstellen eines uint8_t-Arrays mit 132 MB Größe (15360×8640)
  • Einmalige Ausführung der do-while-Iterationsschleife für die gesamte Animation
  • Paralleles Füllen mit OpenMP

Stufe 2: Render 255 Einzelbilder

  • Lesen der Iterationskarte aus dem Speicher
  • Anwenden einer verschobenen Palette für jedes Einzelbild
  • Lokale Mittelwertbildung von 8×8-Blöcken (ohne long double)
  • Paralleles Schreiben der BMP-Dateien

Sinus-Palette: 127 + 127 cos(2π a / 255) und 127 + 127 sin(2π a / 255).

Implementierungsbeispiel

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cstdint>
#include <string>
#include <atomic>
#include <omp.h>
#include <cstdio>
using namespace std;

const double PI = 3.14159265358979323846;

#pragma pack(push, 1)
struct BMPHeader {
    uint16_t type{0x4D42};
    uint32_t size{0};
    uint16_t reserved1{0};
    uint16_t reserved2{0};
    uint32_t offBits{54};
    uint32_t structSize{40};
    int32_t  width{0};
    int32_t  height{0};
    uint16_t planes{1};
    uint16_t bitCount{24};
    uint32_t compression{0};
    uint32_t sizeImage{0};
    int32_t  xpelsPerMeter{2834};
    int32_t  ypelsPerMeter{2834};
    uint32_t clrUsed{0};
    uint32_t clrImportant{0};
};
#pragma pack(pop)

void save_bmp(const string& filename, const vector<uint8_t>& data, int w, int h) {
    int rowSize = (w * 3 + 3) & ~3;
    BMPHeader header;
    header.width = w;
    header.height = h;
    header.sizeImage = rowSize * h;
    header.size = header.sizeImage + 54;
    ofstream f(filename, ios::binary);
    f.write(reinterpret_cast<char*>(&header), 54);
    f.write(reinterpret_cast<const char*>(data.data()), data.size());
    f.close();
}

Wichtigste Erkenntnisse

  • 80-Bit-Präzision long double + FPU x87: Zoom bis zu 10^18 ohne Artefakte
  • SSAA 8×8: 64 Samples pro Pixel, vollständige Rauscheliminierung
  • Zweistufiges Render: 132 MB Iterationskarte + schnelle Farbzusammenstellung
  • OpenMP: automatische Multithreading mit dynamischer Planung
  • FFmpeg-Integration: qp=20, no-psy, deblock=-6 für professionelle Qualität

— Editorial Team

Advertisement 728x90

Weiterlesen