Retour à l'accueil

Animation Mandelbrot : 80 bits SSAA 8x8

L'implémentation du générateur d'animation fractale Mandelbrot utilise l'arithmétique 80 bits, suréchantillonnage 8×8 et OpenMP pour créer une vidéo haute qualité. Le pipeline en deux étapes optimise les calculs, FFmpeg fournit un encodage professionnel.

Mandelbrot 80 bits : vidéo avec SSAA 8×8 et OpenMP
Advertisement 728x90

Génération d'une animation fractale de Mandelbrot avec précision 80 bits et SSAA

L'utilitaire génère 255 images de l'ensemble de Mandelbrot au format BMP en résolution 1920×1080 et les compile en une vidéo MP4 à 30 FPS. L'intégration de FFmpeg automatise l'ensemble du pipeline : des calculs fractals au rendu final. Les paramètres FFmpeg sont optimisés pour préserver les détails : qp=20 assure une haute qualité, pix_fmt yuv420p garantit la compatibilité, et deblock=-6 minimise les artefacts de compression.

Options de commande clés :

  • -stream_loop 3 : quatre passes d'animation (base + 3 répétitions)
  • -framerate 30 : fréquence d'images d'entrée
  • -color_range full : plage de luminosité complète 0-255
  • no-psy : désactive les améliorations psycho-visuelles pour la pureté des structures fractales

Raccourcis clavier et coordonnées des points

Le programme prend en charge la sélection parmi 8 régions prédéfinies de l'ensemble ou le chargement de paramètres depuis un fichier Mandelbrot.txt (touche 9). Les coordonnées sont définies avec une précision 80 bits (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;

Arithmétique 80 bits et FPU x87

L'implémentation utilise long double pour travailler avec une plage d'échelle de 10^18 (contre 10^14 pour double). Le support matériel pour la FPU x87 assure une précision de calcul maximale sans émulation logicielle. Ceci est crucial pour les zooms profonds dans les mini-fractales sans pixellisation.

Avantages de la précision 80 bits :

  • +4 chiffres décimaux de précision
  • Échelle 10 000 fois plus profonde que les implémentations standard
  • Utilisation directe des registres x87 sans conversions intermédiaires

Parallélisation avec OpenMP

OpenMP est utilisé pour paralléliser les boucles de calcul d'itération. La directive #pragma omp parallel for schedule(dynamic) répartit efficacement la charge sur les cœurs, assurant une évolutivité des systèmes 4 cœurs aux serveurs avec 128 threads.

Google AdInline article slot

Suréchantillonnage 8×8 (64 échantillons par pixel)

Le SSAA est implémenté en rendant à une résolution ultra-élevée 15360×8640 (8× l'original 1920×1080). Chaque pixel final agrège 64 échantillons fractals indépendants avec des calculs de composants RGB séparés.

Algorithme de lissage :

  • Calculer les itérations pour chaque sous-pixel en arithmétique 80 bits
  • Coloration indépendante des sous-pixels avec rotation de palette
  • Accumuler les intensités R/G/B (moyenne des canaux)
  • Réduire l'échantillon à la résolution cible

Résultat : aucun bruit chromatique, clarté cinématographique des bords de structure fractale.

Google AdInline article slot

Génération d'images optimisée

Le pipeline est divisé en deux étapes pour minimiser les calculs :

Étape 1 : Carte d'itération

  • Créer un tableau uint8_t de 132 Mo (15360×8640)
  • Exécuter la boucle d'itération do-while une fois pour toute l'animation
  • Remplissage parallèle avec OpenMP

Étape 2 : Rendu de 255 images

  • Lire la carte d'itération depuis la mémoire
  • Appliquer une palette décalée pour chaque image
  • Moyenne locale des blocs 8×8 (sans long double)
  • Écriture parallèle des fichiers BMP

Palette sinusoïdale : 127 + 127 cos(2π a / 255) et 127 + 127 sin(2π a / 255).

Exemple d'implémentation

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

Points clés

  • Précision 80 bits long double + FPU x87 : zoom jusqu'à 10^18 sans artefacts
  • SSAA 8×8 : 64 échantillons par pixel, élimination complète du bruit
  • Rendu en deux étapes : carte d'itération de 132 Mo + assemblage rapide des couleurs
  • OpenMP : multithreading automatique avec planification dynamique
  • Intégration FFmpeg : qp=20, no-psy, deblock=-6 pour une qualité professionnelle

— Editorial Team

Advertisement 728x90

Lire ensuite