Volver al inicio

Animación Mandelbrot: SSAA 80 bits 8x8

La implementación del generador de animación del fractal Mandelbrot utiliza aritmética de 80 bits, sobremuestreo 8×8 y OpenMP para crear video de alta calidad. El pipeline en dos etapas optimiza los cálculos, FFmpeg proporciona codificación profesional.

Mandelbrot 80 bits: video con SSAA 8×8 y OpenMP
Advertisement 728x90

Generación de animación del fractal de Mandelbrot con precisión de 80 bits y SSAA

La utilidad genera 255 fotogramas del conjunto de Mandelbrot en formato BMP a una resolución de 1920×1080 y los compila en un video MP4 a 30 FPS. La integración con FFmpeg automatiza todo el pipeline: desde los cálculos fractales hasta el renderizado final. Los parámetros de FFmpeg están optimizados para preservar los detalles: qp=20 asegura alta calidad, pix_fmt yuv420p garantiza compatibilidad y deblock=-6 minimiza los artefactos de compresión.

Opciones clave del comando:

  • -stream_loop 3: cuatro pases de animación (base + 3 repeticiones)
  • -framerate 30: tasa de fotogramas de entrada
  • -color_range full: rango de brillo completo 0-255
  • no-psy: desactiva las mejoras psico-visuales para la pureza de las estructuras fractales

Teclas rápidas y Coordenadas de Puntos

El programa admite seleccionar entre 8 regiones preestablecidas del conjunto o cargar parámetros desde un archivo Mandelbrot.txt (tecla 9). Las coordenadas se establecen con precisión de 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;

Aritmética de 80 bits y FPU x87

La implementación usa long double para trabajar con un rango de escalado de 10^18 (frente a 10^14 para double). El soporte hardware para la FPU x87 asegura la máxima precisión de cálculo sin emulación por software. Esto es crítico para zooms profundos en mini-fractales sin pixelación.

Ventajas de la precisión de 80 bits:

  • +4 dígitos decimales de precisión
  • Escalado 10,000 veces más profundo que las implementaciones estándar
  • Uso directo de registros x87 sin conversiones intermedias

Paralelización con OpenMP

OpenMP se utiliza para paralelizar los bucles de cálculo de iteraciones. La directiva #pragma omp parallel for schedule(dynamic) distribuye efectivamente la carga entre los núcleos, asegurando escalabilidad desde sistemas de 4 núcleos hasta servidores con 128 hilos.

Google AdInline article slot

Super-Muestreo 8×8 (64 Muestras por Píxel)

SSAA se implementa renderizando a ultra alta resolución 15360×8640 (8× el original 1920×1080). Cada píxel final agrega 64 muestras fractales independientes con cálculos separados de componentes RGB.

Algoritmo de suavizado:

  • Calcular iteraciones para cada sub-píxel en aritmética de 80 bits
  • Coloreado independiente de sub-píxeles con rotación de paleta
  • Acumular intensidades R/G/B (promedio de canal)
  • Reducir muestreo a resolución objetivo

Resultado: sin ruido cromático, claridad cinematográfica en los bordes de la estructura fractal.

Google AdInline article slot

Generación de Fotogramas Optimizada

El pipeline se divide en dos etapas para minimizar cálculos:

Etapa 1: Mapa de Iteraciones

  • Crear un array uint8_t de 132 MB (15360×8640)
  • Ejecutar el bucle de iteración do-while una vez para toda la animación
  • Llenado paralelo con OpenMP

Etapa 2: Renderizar 255 Fotogramas

  • Leer mapa de iteraciones desde memoria
  • Aplicar paleta desplazada para cada fotograma
  • Promedio local de bloques 8×8 (sin long double)
  • Escritura paralela de archivos BMP

Paleta sinusoidal: 127 + 127 cos(2π a / 255) y 127 + 127 sin(2π a / 255).

Ejemplo de Implementación

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

Conclusiones Clave

  • Precisión de 80 bits long double + FPU x87: zoom hasta 10^18 sin artefactos
  • SSAA 8×8: 64 muestras por píxel, eliminación completa de ruido
  • Renderizado en dos etapas: mapa de iteraciones de 132 MB + ensamblaje de color rápido
  • OpenMP: multi-hilo automático con planificación dinámica
  • Integración FFmpeg: qp=20, no-psy, deblock=-6 para calidad profesional

— Editorial Team

Advertisement 728x90

Leer después