Skip to content

Repository files navigation

UUON Fractal Engine

A browser-based 3D fractal renderer — pure WebGL ray marching with real-time parameter controls and a full mesh/image export pipeline.

Run & Operate

  • pnpm --filter @workspace/fractal-engine run dev — start the fractal engine (auto-wired to the fractal-engine: web workflow)
  • pnpm run typecheck — full typecheck across all packages
  • pnpm --filter @workspace/fractal-engine run typecheck — typecheck the fractal engine only
  • pnpm --filter @workspace/fractal-engine run test:e2e — run Playwright E2E tests (requires browsers installed)

No environment variables or database required — the app is entirely client-side.

Stack

  • pnpm workspaces, Node.js 24, TypeScript 5.9
  • Frontend: Vite + vanilla TypeScript (no React in the engine core)
  • Rendering: pure WebGL 1 raymarcher (no Three.js)
  • UI: vanilla DOM + custom CSS (engine.css)
  • Export: CPU-side marching cubes → OBJ / PLY / STL / PNG / WebP

Where things live

artifacts/fractal-engine/src/
  main.ts            — entry point, wires everything together
  state.ts           — global engine state (S object)
  renderer.ts        — WebGL raymarcher (real-time preview)
  controls.ts        — all UI event bindings and syncSliders()
  shaders.ts         — GLSL vertex + fragment shaders (inline strings)
  engine.css         — all engine-specific styles
  export/
    marchingCubes.ts — CPU field evaluation + Marching Cubes triangulation
    exportStudio.ts  — full mesh export pipeline (weld, Taubin smooth, normals, OBJ/PLY/STL)
    imageExport.ts   — offscreen WebGL render → PNG / WebP download
    foldConstants.ts — FOLD_RANGE / FOLD_ISO constants shared across export
    tables.ts        — MC_EDGES / MC_TRIS lookup tables
artifacts/fractal-engine/tests/e2e/
  controls.spec.ts   — preset switching, button groups, sliders
  export-studio.spec.ts — mesh generation + OBJ/PLY/STL download validation
  image-export.spec.ts  — PNG/WebP buttons + BUG-6 code audit
playwright.config.ts   — Playwright config (SwiftShader for headless WebGL)

Architecture decisions

  • No framework in the engine core. All rendering and UI is vanilla TypeScript + DOM. React/Radix are only present in lib/ packages inherited from the monorepo scaffold; the fractal engine does not use them.
  • CPU marching cubes for export. The real-time view is a GLSL raymarcher, but mesh export re-evaluates the SDF in JavaScript so export works without GPU access.
  • Taubin smoothing, not Laplacian. Pure Laplacian shrinks the mesh. Taubin two-step (λ shrink → μ inflate, μ = −λ/(1−0.1λ)) preserves volume.
  • Weld tolerance is range-adaptive. weldVertices() uses max(5e-6, FOLD_RANGE[ft] × 2e-6) so large-scale fractals don't miss duplicates.
  • Post-weld normals always recomputed. Welding remaps vertex indices; copying pre-weld gradient normals after weld produces corrupted shading. Standard/High/Cinematic always call recomputeNormals().

Product

Six fractal presets (Pure Menger, Box-B, Kleinian, Lattice, Tetra, Deep-∞) with real-time parameter sliders for iterations, scale, offsets, fold type, Julia constants, blend, and rotation. Export Studio generates production-quality meshes (DRAFT 32³ through CINEMATIC 128³) with optional Taubin smoothing, vertex welding, triplanar/spherical UV maps, and vertex colors. Image export renders hi-res PNG (1×/2×/4×) and WebP screenshots using the full matcap shading pipeline.

User preferences

  • Keep the engine core free of React and framework dependencies.

Gotchas

  • Do not run pnpm dev at the workspace root — each artifact needs PORT and BASE_PATH from the workflow config. Use restart_workflow or the preview pane instead.
  • console.error in renderer.ts is intentional — those are WebGL shader compile/link error reporters, not debug noise.
  • Image export requires WebGLbuildOffscreenGL() alerts "Could not create offscreen WebGL context" in headless environments. Mesh export (marching cubes) is pure CPU and works everywhere.
  • Typecheck the engine with tsc --noEmit, not buildbuild needs PORT/BASE_PATH from the workflow env.

Pointers

  • See the pnpm-workspace skill for workspace structure and TypeScript project references.
  • foldConstants.ts is the single source of truth for FOLD_RANGE and FOLD_ISO values.
  • STL binary format: 80-byte header + 4-byte LE uint32 (triangle count) + triCount × 50 bytes.

About

A browser-based 3D fractal renderer, pure WebGL ray marching with real-time parameter controls and a full mesh/image export pipeline. No environment variables or database required, the app is entirely client-side.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages