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):
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.
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.
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
Zatím žádné komentáře.