Download Latest Version SurfaceExplorer-1.3-windows-x64.zip (71.4 MB) Google Add to Preferred Sources
Home / v1.2
Name Modified Size InfoDownloads / Week
Parent folder
install-linux.sh 2026-09-13 7.6 kB
SurfaceExplorer-1.2-windows-x64.zip 2026-09-12 72.1 MB
SurfaceExplorer-v1.2-linux-x86_64.AppImage 2026-09-12 86.7 MB
README.md 2026-09-12 8.6 kB
Surface Explorer v1.2 source code.tar.gz 2026-09-12 216.8 MB
Surface Explorer v1.2 source code.zip 2026-09-12 217.4 MB
SurfaceExplorer-v1.2-macos.dmg 2026-09-11 34.0 MB
Totals: 7 Items   627.1 MB 0

Which file do I need?

  • macOS 12.0+ (Universal) — SurfaceExplorer-v1.2-macos.dmg: open it and drag the app to your Applications folder. It is signed and notarized, so it opens normally on first launch.
  • Windows 10/11, 64-bit — SurfaceExplorer-1.2-windows-x64.zip: extract it anywhere and run SurfaceExplorer.exe.
  • Linux, any x86_64 distribution — SurfaceExplorer-v1.2-linux-x86_64.AppImage, plus the optional install-linux.sh: see Linux below.

An iOS version is available on the App Store.

Linux

Download both SurfaceExplorer-v1.2-linux-x86_64.AppImage and install-linux.sh into the same folder, then run:

bash install-linux.sh

It copies the AppImage to ~/Applications, makes it executable and adds it to your applications menu with its icon, so from then on you launch it like any other app. Re-run it to update, bash install-linux.sh --uninstall to remove. No root needed.

To run the AppImage directly instead, make it executable first. A downloaded file carries no permissions, and without this your desktop may hand it to a disk-image tool instead of launching it:

chmod +x SurfaceExplorer-v1.2-linux-x86_64.AppImage
./SurfaceExplorer-v1.2-linux-x86_64.AppImage

Requirements

  • GPU with Vulkan 1.0+, Metal, Direct3D 11+ or OpenGL 3.3+
  • Built with Qt 6.10.2

Known issues

Windows / Direct3D. Presets that drive the Geodesic Flow solver from a metric written in the Equations panel may fail to render correctly on the Direct3D backend: the application can stop responding and be closed by the system. They work as expected on the other platforms.

Source and bug reports

What's new since v1.1

  • Multi-mesh surfaces: a surface can now be built from several independent grids, one per branch, instead of a single one stretched over everything. Each mesh carries its own appearance — colour, transparency, light, wireframe and line density — and its own procedural texture, with a clock that Stop freezes per mesh or all at once. It is what makes the Clifford labyrinths and the Hopf families possible: six tubes, each with the fibration of its own axis.

  • An empty scene, and a NEW button to reach it: distinct from restoring the default surface, which is what clicking the active tab does. Leaving a scene, switching tab or starting a new one now asks before discarding unsaved work — a warning that covers surfaces, textures, sounds and the renderer controls, and that finally also appears when the app is closed.

  • Change Library Folder: moving the library was not possible from the interface at all. The command respects the folder you pick, installs into its own presets subfolder, and warns before putting the library somewhere iCloud may later empty.

  • Search across the whole manual: a field at the top of the Documentation window searches every page at once — the manual is split across seventeen files, so a local find would miss whatever sits elsewhere. Results list the page, the number of occurrences and a line of context; opening one highlights every match.

  • On-screen hints: presets, records and textures can carry a short overlay message shown when they load, saying which sliders are live and what they do. Records carry two, one for the surface and one for its texture.

  • Discrete constants and lower bounds in scripts: a script can declare A := int(1,10) and the slider snaps to whole numbers, or A := min(1.0) to keep it above a floor. It is how a single preset can offer "how many tubes" as a slider instead of shipping four near-identical files.

  • A–F/S constants in the U/V/W limits: the six limit fields now accept the constants, so the domain can follow a slider.

  • A single FOV slider in the renderer dock: it replaces the two per-path sliders, which fought over the same value.

  • A notice when two parts of the scene want the same slider: the seven constants are one global set shared by the surface, its texture and the background, so a letter claimed twice makes one slider drive two unrelated things. Applying a texture that claims a constant already in use now says so, naming the letters and the ones still free. Nothing is refused — sharing a slider can be deliberate.

  • The status bar scrolls with a finger on mobile: with eleven buttons in a row the last ones were unreachable on a phone.

  • Video export on macOS no longer needs ffmpeg: the recorder called an external binary, which the App Store build could not ship. It now encodes natively.

  • Per-mesh domain limits: the Multi Mesh box now carries four fields — u_a, u_b, v_a, v_b — that cut the parametric domain of a grid without editing the script. In Mesh scope they restrict the selected grid alone; in All they drive a domain of their own that applies to every grid and suspends the individual ones, which return untouched on switching back. What you type overrides the //MESH_BEGIN section and is saved with the preset, so a figure can be opened up to look inside it and kept that way.

Main fixes

  • The equations module applies as one, on Run: X/Y/Z/P, compositions, constraints, geodesic flow and the u/v/w domain used to enter at different moments — some on Enter, some on Run — so a surface could be drawn from a mixture of old and new fields. They now wait for Run together when the surface is still, while a running surface accepts changes on Enter without a Stop/Run round trip. The same rule was extended to the Ray Marching spatial limits.

  • Android: blank screen on Adreno devices: the uniform block was declared with one field fewer in the vertex shader than in the fragment shader. Desktop GPUs accept the mismatch, Adreno refuses the link, and every pipeline failed at once — with no error visible in the app.

  • Presets kept in a synced folder froze the app: pointing the library at an iCloud Drive folder could hang it on startup. Files that iCloud has evicted still report as existing, and reading one blocks until it is downloaded.

  • macOS App Store: the library survived neither a restart nor playback: under sandbox the library came back empty on the second launch, and the media in records would not play.

  • Surfaces were clipped in Orthogonal projection: with parallel rays the view volume is a box of constant section, so everything in front of the near plane was cut away — half a figure disappeared whenever the camera sat inside it.

  • No more hole in the background when flying inside a surface: the S³ stereographic clamp acted on the denominator, which is not monotonic near the pole.

  • A shader that failed to compile cleared the view: the pipelines were discarded before the new ones were known to be good, so a typo left an empty screen instead of the previous surface.

  • Records lost their image texture: a record saved with an image reopened showing the default one, and image textures were never highlighted in the Library. Two separate causes — the working copy of the texture code was cleared before the //IMG: tag could be read, and the triplanar snippet the app generates was mistaken for user code.

  • Image backgrounds did not survive the save: a record whose background was an image driven by one of the Animated Images scripts reopened showing whichever picture the previously opened record had loaded. Those scripts sample the image from iChannel0 and never contain it, so the tag naming it is the only record of which one it was.

  • The About dialog showed the wrong version: the number was written by hand in three places.

  • macOS: the direct download and the App Store build were treated as one app: they shared a bundle identifier, so preferences collided and the wrong copy could open.

  • The Kerr funnel's vertical profile was inaccurate: the numerical integration of z(r) mishandled the integrable singularity at the horizon.

Library

The presets shipped with the app were reviewed as a whole. Names now describe the surface rather than the value of a slider, families that were the same construction at different settings have been merged into one preset with a slider, and every preset that responds to the constants says which ones are live.

Source: README.md, updated 2026-09-12