Halfspace

Introduction
Halfspace is an experimental IDE for
strong modeling with distance fields.
(The demo is finest skilled on a pc; cellular Safari has some WebGPU
points, and pan / tilt / zoom interactions will not be but designed for multitouch)
Halfspace is a showcase app for the Fidget kernel, which is used
for rasterization and meshing. Within the GUI, photographs are rasterized in
actual(ish)-time; fashions might be exported as both photographs or triangle meshes:

Since it is 2026, let me word on the outset that that is not vibe-coded.
I’ve been engaged on it since
April 2025
and am writing the code utilizing my human mind, for
various reasons
(and Fidget dates again to
2022).
Now, the remainder of this writeup assumes some information of implicit surfaces;
please see many previous
writeups for details for extra
background data (or simply preserve studying, you will be tremendous).
Why?
I’ve spent a bunch of time writing implicit kernels, barely much less time writing
GUIs on these kernels, and even much less time really modeling with these instruments.
In observe, I do not really have to do a lot strong modeling in my each day life,
so many of the stuff that I create is a demo or an instance of the right way to use a
specific kernel.
Still, I’ve observed a selected pressure when working with implicit surfaces.
Working with low-level implicit surfaces is a bit like writing meeting: it is
low-level, highly effective, and annoying. If all you are given is x, y, z
variables – and it is your duty to mix them into all of the shapes of
your goals – that may be a painful expertise.
When confronted with the ache of writing meeting, most individuals construct abstractions on
prime of it: high-level languages and libraries that compile all the way down to a low-level
illustration. The equal here’s a normal library of shapes and
transformations: sphere, field, translate, scale, and many others.

There’s additionally a much less widespread method to the ache of meeting: making meeting
itself much less painful to write down.
My favourite challenge alongside these traces is
Kartik Agaram’s Mu,
which wraps emulation, tracing, and time-travel debugging round a subset of x86
meeting language.
Halfspace takes each paths. It features a (small however rising) normal library,
but in addition makes it straightforward to construct up fashions incrementally: a fancy mannequin can
be cut up into smaller items, which might be parameterized and visualized
individually.
Given that justification, let’s unpack the outline a bit farther.
Solid modeling
First off, “strong modeling” signifies that we’re specializing in objects with a
definitive inside and outdoors; you need to have the ability to decide any level in area and
say whether or not it is inside or outdoors the mannequin.
This appears apparent, however there’s loads of modeling that does not care about that
property: pull up any
video game model viewer
and you will see loads of infinitely-thin textured partitions, constructed from a single
fan of triangles.
Since my background is in
CAD/CAM software
(with an emphasis on 3D printing), I need fashions that may be bodily
realized.

There are a bunch of how to do strong modeling. In most CAD software program, a
boundary-representation
geometry kernel
is liable for stitching a bunch of particular person surfaces collectively right into a
strong physique. This is a tremendously exhausting drawback – for instance, the intersection
of two NURBS
surfaces might not have a closed-form answer!
Dating again to my Master’s thesis, I’ve been engaged on geometry kernels primarily based
on implicit surfaces. These have the benefit that they will conceivably be
written and absolutely understood by a single particular person or small group, so they seem to be a good
match for personal-scale fabrication software program.
This continues in Halfspace: it is a GUI wrapped across the
Fidget geometry kernel. Models might be designed utilizing some
mixture of pre-defined primitives and hand-written scripts, and exported as
both photographs or triangle meshes.
An IDE for distance fields
We might use the Fidget kernel purely on the constructive strong geometry (CSG)
layer, constructing shapes (spheres, cubes, cylinders, and many others) and mixing them with
logical operations (union, intersection, distinction). Halfspace as a substitute make
the choice to place the underlying distance fields within the foreground.
Let me provide you with an instance of why this issues. Here are two distance fields
for a sawtooth wave, which have the identical indicators at each level in area, however
totally different values:


In this visualization, the signal (which defines inside versus outdoors) is
proven by coloration (blue versus orange), with the boundary of the form proven in
white (similar to a price of 0). The subject values are proven by the
fainter traces, that are spaced at common intervals (like a topographic map).
Despite having similar indicators in every single place, the primary subject could be very poorly behaved.
Look on the vertical fringe of the sawtooth: there is a transition from inside
(blue) to outdoors (orange) with out a crossing by zero.
This is a C0 or
“jump” discontinuity,
and it is unhealthy information! Fidget makes use of computerized differentiation to compute normals, so
the normals throughout this boundary do not level within the appropriate course (evaluate
the sector traces between prime and backside photographs). In 3D, the place we use normals for
shading, this produces incorrect shading within the cabin’s shingles:

(If this seems acquainted, it is as a result of it is extracted from
an earlier blog post)
Putting distance fields front-and-center makes it straightforward to diagnose these type of
points. In reality, it suggests an additional enchancment on the sawtooth subject: we
can tweak the gradient in order that it is 1 in every single place, as a substitute of being bunched up on
the diagonals. Here’s a earlier than / after comparability:


Having uniform gradients makes varied algorithms better-behaved; Fidget would not
require it for correctness, however it could (for instance) enhance mesh high quality.
Halfspace is experimental and cross-platform
Right now, it could be a very daring determination to make use of Halfspace in any
load-bearing capability. In the Fidget writeup, here is one among
the challenge objectives:
Finding the “proper” APIs for implicit kernels, with the potential of making
substantial compatibility breaks
Halfspace is comparable; it would not current APIs to end-users, however I’m flexing my
software program structure abilities by constructing a considerable cross-platform
utility, and I’m prepared to aggresively iterate and break issues as we go.
Speaking of cross-platform, I’m making my life more durable by concentrating on each the net
and native platforms. In the period of supply-chain assaults, having the ability to share a
net hyperlink – as a substitute of asking somebody to compile and run your code – is nice for
onboarding and informal utilization.
To that finish, I’ve been gathering the “Halfspace stack”: a set of libraries and
patterns which let me ship a mixed native + net utility with a minimal of
ache. Right now, listed below are the core items:
- Rust for the appliance (and all dependencies)
eguifor the GUIegui_dockfor the core
window-and-tab abstraction
wgpufor each rendering the UI and GPU compute (!)- Rhai for scripting
- Rayon and
wasm-bindgen-rayon,
used for 2 functions:- Speeding up parallel algorithms by distributing work over many employees; this
is a “typical” utilization of the library - A thread pool for short-lived background duties; it is a extra uncommon
utilization, however we will not spawn threads on the internet.
- Speeding up parallel algorithms by distributing work over many employees; this
- …and a protracted tail of different libraries and shenanigans
This all deserves a devoted writeup, and I’ve complaints about each single
layer of the stack, however total, it is unimaginable that every little thing Just Works™.
Driving Fidget enhancements
Another aim of Halfspace is to drive enhancements within the Fidget kernel, by
utilizing it in a non-trivial utility.
The largest victory on this entrance has been ongoing work on
fidget-wgpu. This was
motivated by efficiency on the internet: the native construct was pleasantly quick, however
doing rasterization on the CPU was awfully gradual (“non-interactive speeds”) when
working by a layer of WebAssembly.
After numerous work on the Fidget aspect, each rasterization and
post-processing (e.g. shading) might be run purely on the GPU, with none
roundtrips to the CPU.

This was each a efficiency and architectural win:
- We now have native rendering velocity on each native and net targets
- Rendering logic is now not unfold between Fidget (on the CPU) and Halfspace
(with a mixture of CPU and GPU code):- Fidget implements the canonical rendering logic
- Halfspace has skinny shaders which draw an RGBA texture
(The 2D rendering pipeline can also be now absolutely GPU-accelerated, though it has
barely fancier shaders in Halfspace, for causes)
Wrapping up
Halfspace is a factor that exists!
You ought to attempt it out, and may in all probability not use it for important functions!
If you encounter issues, please file a difficulty or open a dialogue on Github.
Like most of my work, I plan to maintain engaged on it till I’ve run out of
issues to study from the challenge.
Also like most of my work, it is
open-source
below the MPLv2 license.


