Zpět na domů

Animace Mandelbrota: 80bitová SSAA 8x8

Implementace generátoru animace fraktálu Mandelbrota používá 80bitovou aritmetiku, supersampling 8×8 a OpenMP pro vytvoření vysoce kvalitního videa. Dvoufázový pipeline optimalizuje výpočty, FFmpeg zajišťuje profesionální kódování.

80bitový Mandelbrot: video s SSAA 8×8 a OpenMP
Advertisement 728x90

Generování animace fraktálu Mandelbrot s 80bitovou přesností a SSAA

Utilita generuje 255 snímků množiny Mandelbrot ve formátu BMP s rozlišením 1920×1080 a sestavuje je do MP4 videa s frekvencí 30 FPS. Integrace FFmpeg umožňuje automatizovat celý pipeline: od výpočtů fraktálu až po finální render. Parametry FFmpeg jsou optimalizovány pro zachování detailů: qp=20 zajišťuje vysokou kvalitu, pix_fmt yuv420p garantuje kompatibilitu, deblock=-6 minimalizuje kompresní artefakty.

Klíčové option příkazu:

  • -stream_loop 3: čtyři průchody animace (základní + 3 opakování)
  • -framerate 30: vstupní frekvence snímků
  • -color_range full: plný rozsah jasu 0-255
  • no-psy: vypnutí psycho-vizuálních vylepšení pro čistotu fraktálních struktur

Klávesové zkratky a souřadnice bodů

Program podporuje výběr z 8 přednastavených regionů množiny nebo načtení parametrů ze souboru Mandelbrot.txt (klávesa 9). Souřadnice jsou zadány s 80bitovou přesností (long double):

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;

80bitová aritmetika a FPU x87

Implementace využívá long double pro práci s rozsahem škálování 10^18 (oproti 10^14 u double). Hardwarová podpora FPU x87 zajišťuje maximální přesnost výpočtů bez programové emulace. To je kritické pro hluboký zoom do mini-fraktálů bez pixelace.

Výhody 80bitové přesnosti:

  • +4 desetinná místa přesnosti
  • Škálování 10 000krát hlouběji než standardní implementace
  • Přímé využití registrů x87 bez mezičlánkových konverzí

Paralelizace s OpenMP

OpenMP se aplikuje pro paralelizaci cyklů výpočtů iterací. Direktiva #pragma omp parallel for schedule(dynamic) efektivně rozděluje zátěž na jádra, zajišťující škálovatelnost od 4jádrových systémů až po servery se 128 vlákny.

Google AdInline article slot

Supervzorkování 8×8 (64 vzorků na pixel)

SSAA je realizováno renderem ve super-vysokém rozlišení 15360×8640 (8× původní 1920×1080). Každý finální pixel agreguje 64 nezávislých fraktálních vzorků s odděleným výpočtem RGB komponent.

Algoritmus vyhlazování:

  • Výpočet iterací pro každý subpixel v 80bitové aritmetice
  • Nezávislé obarvení subpixelů s rotací palety
  • Akumulace R/G/B intenzit (průměrování po kanálech)
  • Downsampling na cílové rozlišení

Výsledek: absence chromatického šumu, kinematografická ostrost hran fraktálních struktur.

Google AdInline article slot

Optimalizovaná generace snímků

Pipeline je rozdělen na dvě fáze pro minimalizaci výpočtů:

Fáze 1: Mapa iterací

  • Vytvoření pole uint8_t o velikosti 132 MB (15360×8640)
  • Provedení do-while cyklu iterací jednou pro celou animaci
  • Paralelní vyplnění s OpenMP

Fáze 2: Render 255 snímků

  • Čtení mapy iterací z paměti
  • Aplikace posunuté palety pro každý snímek
  • Lokální průměrování 8×8 bloků (bez long double)
  • Paralelní zápis BMP souborů

Sinusoidální paleta: 127 + 127 cos(2π a / 255) a 127 + 127 sin(2π a / 255).

Příklad implementace

#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();
}

Co je důležité

  • 80bitová přesnost long double + FPU x87: zoom až 10^18 bez artefaktů
  • SSAA 8×8: 64 vzorků na pixel, úplné odstranění šumu
  • Dvoufázový render: mapa iterací 132 MB + rychlá barevná sestava
  • OpenMP: automatická mnohovláknovost s dynamickým plánováním
  • FFmpeg integrace: qp=20, no-psy, deblock=-6 pro profesionální kvalitu

— Editorial Team

Advertisement 728x90

Číst dál