Skip to content

harry7557558/spirulae

Repository files navigation

Spirulae: Web-Based Math Visualization

by Harry Chen - updated January 2024

spirulae.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 on the internet, 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. Since I don't have much knowledge of advanced functions (especially the complex-variable ones, which I only found their graphs to be visually cool), I cannot guarantee the mathematical practicability and accuracy of these tools. 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
  • 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

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
  • Mathematically-defined custom colors
  • 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

Limitations

Spirulae has the following web dependencies:

  • WebGL 2
    • EXT_color_buffer_float and EXT_float_blend, 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 is previously distributed under the MIT license. 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: 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: How to draw shapes using equations?

Drawing meaningful shapes using equations is more about art techniques 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 and can be used as a dictionary.

Q: How does Spirulae evaluate functions on the GPU?

For readers with technical background, Spirulae recompiles shader every time the equation input or a graphing parameter is updated. Spirulae parses equations into postfix notation and generates code of a GLSL function that can be compiled. Automatic differentiation can be done in this step. Generated shader code can be found in the browser's F12 developer console.


Gallery

Note: This gallery has not been updated for a while.
To see more recent visual results, a gallery of unfiltered process screenshots can be found here. Note that the page is intended to be a progress overview rather than a showcase gallery.

Complex domain coloring

The gamma function in 3D

A sextic algebraic surface

A fractal with scalar field visualized

A clipped quintic implicit surface, with volumetrics showing isosurfaces

A parametric surface rendered in X-ray mode

A path-traced fractal