A high-performance, multi-threaded Mandelbrot and Julia set explorer written in C. This project uses an Engine-Centric Architecture targeting Native Desktop (CPU/AVX2), Web (WebAssembly/SIMD128), and GPU (Sokol GFX).
This project is currently in an active state of development.
- Web Engine: Currently unstable and undergoing debugging for WebGL2/Sokol initialization issues. You may encounter a black screen or runtime errors when running the web version.
- Desktop Engines (CPU/GPU): Stable and functional.
Live Web Demo - (https://tiw302.github.io/mandelbrot-c/)
- Introduction
- The Math
- Features
- Technical Architecture
- Quality Assurance
- Prerequisites
- Build and Run
- Usage
- Project Structure
- Configuration
- Roadmap
- Contributing
- License
Hi! I am currently diving into C programming and wanted to build something visual to understand pointers, memory, and hardware acceleration better. This project is the result of my experiments with SDL2, pthreads, SIMD intrinsics, and WebAssembly targeting.
For an in-depth technical analysis of the project's architecture, SIMD optimizations, and future development paths, please refer to the Technical Research Document.
The Mandelbrot set is the set of complex numbers
In simple terms:
- Start with
$z = 0$ . - Calculate the next value:
$z_{new} = z_{old}^2 + c$ . - Repeat. If the magnitude
$|z|$ stays small forever, the point$c$ is inside the set (colored black). - If
$|z|$ explodes (escapes to infinity), the point is outside. The color represents how fast it escaped.
A Julia set
- Real-time Rendering: Optimized arithmetic for smooth navigation.
- Hardware Acceleration: AVX2 and WASM SIMD128 vectorization for processing multiple pixels in parallel.
- Dynamic Multi-threading: Intelligent row-based workload distribution using pthreads.
- Cross-Platform Engines: Engine-Centric monorepo structure mapping logic to CPU and Web (Sokol GFX) targets.
- Julia Set Mode: Press
Jto instantly switch to the Julia set defined by the point under your cursor. - Tour Mode: Automated exploration paths for both Mandelbrot and Julia modes.
- Screenshot Export: PNG export functionality with no external library dependencies (uses integrated zlib and libpng).
- Interactive Controls: Advanced mouse-based panning and selection-based zooming.
- Robustness: Audited for memory safety and edge-case stability (stable during rapid window resizing).
The codebase strictly adheres to an Engine-Centric architecture to ensure Separation of Concerns (SoC).
- Core [SSOT]: Pure mathematical definitions (
mandelbrot.c,julia.c) reside here as the Single Source of Truth. They are entirely agnostic to rendering APIs, utilizing compiler intrinsics natively. - CPU Engine: Responsible for Native Desktop rendering using SDL2, handling input polling, and distributing workloads across logical core thread pools.
- Web Engine: Modern Web runtime using Sokol GFX, bridging the core mathematics to high-performance WebGL 2.0 distributions.
The WebAssembly implementation enables high-performance desktop-class rendering within the browser environment.
- Multithreading: Utilizes Emscripten's
pthreadsimplementation by leveraging Web Workers andSharedArrayBufferto parallelize the workload across all available logical CPU cores. - Instruction Optimization: Implements WASM SIMD128 intrinsics, allowing for simultaneous processing of two double-precision complex numbers per instruction.
- Security Compliance: For deployment on static hosting platforms (e.g., GitHub Pages), the engine utilizes a specialized Service Worker (
coi-serviceworker.js) to enforce Cross-Origin Opener Policy (COOP) and Cross-Origin Embedder Policy (COEP) headers.
The fractal engine utilizes 256-bit AVX2 registers on desktop and 128-bit SIMD on WebAssembly. This allows the system to perform complex squaring, addition, and escape radius testing on 4 (or 2) independent double-precision points simultaneously natively.
Parallelization is managed through a dynamic scheduling model on the CPU. Unlike static partitioning, which can lead to inefficient CPU usage in regions of high iteration density, the engine uses atomic counters to allow threads to claim the next available row.
The codebase has been audited to address common low-level risks:
- Resizing Resilience: Implemented division-by-zero guards to prevent crashes during window minimization or extreme resizing.
- Memory Hardening: Clamped coloring indices to prevent out-of-bounds access and added overflow checks to pixel buffer allocations.
- Error Handling: Enhanced resource initialization paths to ensure clean-up on failure and improved diagnostic reporting.
Core logic is validated through a suite of automated unit tests.
- Verification: Run
cd tests && maketo verify core math and AVX2 consistency. - Continuous Integration: Every modification is automatically built and tested via GitHub Actions on Ubuntu environments.
- C Compiler (GCC/Clang/MSVC with C11 support)
- CMake (3.10+, required for build system)
- Emscripten (emcc, required for Web target)
- SDL2 & SDL2_ttf development libraries (for CPU target)
- zlib & libpng (required for PNG screenshot export)
sudo apt install cmake libsdl2-dev libsdl2-ttf-dev zlib1g-dev libpng-devThe project uses CMake for cross-platform build management.
cmake -S . -B build -DBUILD_CPU=ON
cmake --build build
./build/mandelbrot-cpuemcmake cmake -S . -B build-web -DBUILD_WEB=ON
cmake --build build-webchmod +x build.sh
./build.sh cpu # Builds desktop
./build.sh web # Builds web
./build.sh clean # Cleans build artifacts| Action | Control |
|---|---|
| Zoom In | Left Mouse Drag (Selection box) |
| Pan | Right Mouse Drag |
| Zoom at Cursor | Mouse Wheel |
| Undo Zoom | Ctrl + Z |
| Iterations | Up / Down (Shift for x100, default x10) |
| Palettes | P |
| Reset View | R |
| Toggle Julia Mode | J |
| Save Screenshot | S |
| Tour Mode | T |
| Quit | Esc or Q |
.
├── src/core/ # Pure Mathematical Engine
├── src/cpu-engine/ # Desktop Renderer, SDL UI, and Thread Pools
├── src/web-engine/ # Sokol GFX WebAssembly Runtime
├── include/ # Global configuration headers
├── shaders/ # GLSL Shaders for Sokol engine
├── tests/ # Automated regression frameworks
├── third_party/ # External libraries (Sokol, stb, etc.)
├── CMakeLists.txt # Cross-platform Build System
└── build.sh # Build abstraction script
Rendering parameters can be tuned in include/config.h to balance performance and visual fidelity:
DEFAULT_ITERATIONS: Controls the initial detail level.MAX_ITERATIONS_LIMIT: Upper bound for runtime adjustments.DEFAULT_THREAD_COUNT: Number of parallel threads (0 = auto-detect).ESCAPE_RADIUS: Mathematical threshold for the set calculation.
- Implement dynamic load balancing using atomic row-counters to maximize CPU utilization across all logical cores.
- Integrate a pre-calculated Look-Up Table (LUT) for color mapping to bypass expensive real-time trigonometric calculations.
- Implement smooth coloring algorithms using fractional iteration counts for high-fidelity gradients.
- Deploy hardware-specific vectorization (AVX2 for Desktop, SIMD128 for WebAssembly) to process multiple pixels per cycle.
- Research and implement pure-shader fractal calculation for extreme-scale GPU rendering.
- Add interactive runtime controls for iteration depth adjustment and dynamic color palette switching.
- Implement automated "camera path" and "tour" modes for cinematic fractal exploration.
- Connect HTML5 Frontend APIs strictly to the
web-enginefor a responsive, cross-platform user experience. - Research and implement arbitrary-precision arithmetic to overcome the double-precision zoom limit.
- Establish a strict Engine-Centric Monorepo architecture, isolating platform rendering from core mathematical logic.
- Implement a high-performance CMake build system to streamline native and cross-compilation workflows.
- Expand unit testing coverage to ensure mathematical consistency across all hardware backends.
- Implement automatic CPU core detection to dynamically optimize thread pool allocation.
I am still learning, so if you spot any bugs or have suggestions for improvements (especially around memory safety or SIMD optimization!), I would really appreciate your help. Feel free to open an issue or pull request. Thank you!
This project is licensed under the MIT License - see the LICENSE file for details.





