Skip to content

GPU-accelerated math function graphers in web browsers, both 3D and 2D.

License

Notifications You must be signed in to change notification settings

harry7557558/spirulae

Repository files navigation

Spirulae: Web-Based Math Visualization

by Harry Chen - Page updated September 2024

spirulae-2.jpg

GPU-accelerated math function graphers in web browsers, both 3D and 2D.

This is a personal passion project. Back in 2022 I couldn't find a 3D graphing calculator with satisfying 3D implicit surface rendering, so I made one, and the development continued. I was initially inspired by raymarching demos on Shadertoy, but as I extended the equation parser and renderer to other types of math functions, currently implemented function graphers are not limited to implicit ones.

It is important to note that these function graphers are developed completely by my effort, and many features I implemented are biased toward personal use. I'm not a "real" mathematician, and many features and examples I added are for visual impression rather than mathenatical accuracy and practicability. If you have any suggestions or believe you are experiencing a bug, feel free to open an issue on GitHub.

The name "Spirulae" comes from the name of a deep-ocean cephalopod mollusk that has distinctive spiral shells. I consider myself a fan of spirals, so it shouldn't be surprising that you see a lot of spirals in examples.


Features

The equation parser implements the following features:

  • Function and variable definition
  • Vector and complex number supports
  • Comments (start with #, %, or //)
  • LaTeX preview
  • Special functions
  • Automatic differentiation
  • etc.

The 3D graphers have the following features implemented:

  • Infinite and bounded domain
  • Scalar field visualization
  • Mathematically-defined custom colors
  • Speed vs. quality control
  • Multiple shading and grid modes
  • Dark and light color themes
  • Transparent surfaces
  • Lighting control
  • Red highlight discontinuity
  • etc.

Experimental features (subject to change):

  • Animation via iTime(0)
  • Export C++ code for 3D implicit grapher, via exportCurrentFunction('cppd') in the browser JS console
  • Custom code generation (/autodiff)
  • 2D implicit curve grapher (/implicit2)

Working in Progress

Spirulae is under active development. Tools and features that are being developed include:

  • 3D mesh generation (/meshgen3)
  • 2D mesh generation (/meshgen2)
  • 2D vector field (/ode2)

Features that may be implemented in the future (ordered approximately by priority):

  • More robust equation parsing
  • More flexible viewport control
  • Variable sliders
  • Graph sharing via URL, <iframe> embed for webpages
  • Better expression editor (highlighting, bracket matching, etc.)

Ongoing and proposed research topics (ordered approximately by progress):

  • Denoising path-traced images using deep learning
  • Mesh generation and simplification
  • FEA and general physical simulation
  • Visualization of 3D vector and tensor fields
  • Fitting to NURBS and subdivision surfaces

Limitations

Spirulae has the following web dependencies:

  • WebGL 2
    • EXT_color_buffer_float, required for path tracing and mesh generation
    • EXT_disjoint_timer_query_webgl2 (optional), an FPS counter will be shown when available
  • WebAssembly, required for mesh generation
  • MathJax 3, required for equation preview

Spirulae has the following known issues:

  • GPU-based graphers use single precision floating point and have incompatibility across devices for overflow and NaN behavior.
  • The parser has ambiguity in resolving conflicting variable names. You can avoid this issue by using unique and descriptive function and variable names.
  • Incomplete documentation for some graphers.

Spirulae is not available for commercial licensing due to C++ dependency Triangle and is currently distributed under GPLv3. Spirulae was previously distributed under the MIT license, an old version that allows commercial use can be found here. Note that shader sources adapted from Shadertoy, namely this, this, and this, are separately distributed under CC BY-SA-NC 3.0 according to Shadertoy terms of service.


Frequently Asked Questions

Q: How to draw shapes using math equations?

Creating equations whose graphs represent meaningful shapes is more about intuition than rigorous mathematics. To get started, you can check Inigo Quilez's YouTube channel and videos like this one. I also have a Google Slide intended to introduce Desmos art to high school students that may cover similar principles. I recommend starting simple – once you master math art in two dimensions, you can easily apply the same principles in 3D.

Q: What libraries do Spirulae use?

To make Spirulae lightweight and compatible, I tried to write it with as few dependencies as possible. With the exception of MathJax for rendering LaTeX equations, the JavaScript equation parser and renderers are written from scratch without use of external libraries and frameworks, other than native browser APIs like WebGL. The C++ part that powers mesh generation is compiled to WebAssembly with Emscripten, which uses the following third-party libraries:

  • Triangle, a fast header-only 2D mesh generation library
  • GLM and GLFW, popular math and GUI libraries for OpenGL

Spirulae also adapts shader sources from Shadertoy:

Q: What algorithm does spirulae use to render 3D math equations?

For 3D implicit surface grapher and 3D complex function grapher, for each pixel, Spirulae approximates the nearest intersection between camera ray and the equation's isosurface. The intersection is approximated with Newton's method in screen space, with line derivative estimated from previous function evaluations. The method is designed to be robust to highly nonlinear and unbounded functions. A two-pass hierarchical ray-surface intersection is used to speed up rendering.

The implicit surface path tracer uses a similar method as implicit graphers, except it estimates intersection in clipped object space and does not utilize a hierarchical ray-surface intersection. This allows robust tracing of indirect rays.

The 3D parametric grapher uses a rasterization pipeline. The fragment shader directly evaluates the function per-pixel to calculate albedo and normal, allowing resembling fine surface details even with a relatively coarse geometry. Mesh generators use a conventional OpenGL rasterization pipeline for rendering, with per-vertex albedo and normal from generated mesh.


Gallery

Note: To see more recent visual results, a gallery of unfiltered process screenshots can be found here. The page is intended to be a progress overview rather than a showcase gallery.

Complex domain coloring

The gamma function in 3D

A realistic rendering of gamma function in 3D

A sextic algebraic surface

Scalar field visualization

Parametric surfaces

A 3D Mandelbrot set

A path-traced fractal

Another path-traced fractal

Crystals modeled using math equations

3D mesh models generated from math equations

A 2D vector field streamline plot