This is V2. V1 drew the warp on the CPU in plain JavaScript; V2 is a WebGL2 rebuild that compiles the equation itself into a shader.
Image2complex is a browser-based visualizer for complex functions: drop an image onto the complex plane, type a function f(z), and watch the image get bent by it — recomputed every frame while you pan, zoom, drag or resize. Everything runs client-side; there is no backend.
- Equation input, compiled to GLSL. Enter any expression in
zthrough the MathLive field (or pick a preset). mathjs parses it, and an emitter walks the AST and prints GLSL where every value is avec2(shaders have no complex) type, so the whole complex arithmetic library is hand-written in the prelude. SeeemitGlsl.js. - Per-vertex image warping. The image is pinned to a rectangle of the plane under a 256×256 mesh, uploaded once. The vertex shader evaluates
f(z)at every vertex and the texture unit fills in the colour between them; vertices that blow up (poles, branch cuts, non-finite values) are flagged and their fragments discarded. SeewarpPass.js. - Conformal grid. Instead of drawing the image, map the coordinate lines of the plane through the same shader and watch
fbend the grid itself. Finding which part of the source plane lands in the current view is the hard part — a JS planner probes rings of source points, refines misses with Newton steps toward the view centre, clusters the hits into regions, and picks a grid step scaled by the median|f'|so line spacing stays readable at any zoom. SeeconformalSource.js.
Expressions are algebraic in z, parsed by mathjs and then translated to GLSL, so the accepted subset is whatever the emitter knows how to translate:
- Constants:
i,e,pi,tau,phi. Any other symbol is rejected —zis the only variable. - Functions:
sin cos tan,sinh cosh tanh,asin acos atan,exp,log/ln,sqrt,abs,inv,conj,re,im,arg— all single-argument. - Powers: integer exponents up to ±64 are unrolled into repeated multiplication; anything else goes through the general (branch-cut-carrying)
cpow. - Each equation is validated on the CPU with mathjs before it reaches the GPU, so a bad expression reports an error instead of failing to compile a shader.
| Layer | Choice |
|---|---|
| Build | Vite (vanilla ES modules, no framework) |
| Rendering | WebGL2 offscreen canvas, blitted into a p5.js 2D canvas |
| Math input | MathLive, preset labels via KaTeX |
| Parsing | mathjs — AST for the GLSL emitter, complex arithmetic for the CPU-side planner |
| Styling | Tailwind (CDN) + styles.css |
Requires Node.js and npm.
npm install
npm run dev # http://localhost:5173npm run build # production build → dist/
npm run preview # serve the built outputThe build uses a relative base, so dist/ can be served from any subpath.
No license file is currently published in this repository — treat the code as all-rights-reserved unless a LICENSE is added.