designer/engineer

Wicked good design for wicked problems.

Featured Work

PROJECT FELINES

PROJECT FELINES

The Alzheimer’s field spent billions clearing amyloid plaques from brains that kept declining. FELINES is what happened when I stopped accepting that narrative and started tracing upstream: iron dysregulation, ferroptosis, vascular failure, across six neurodegenerative diseases that enter through different doors but break down the same way.

GOINVO WEBSITE

GOINVO WEBSITE

Migrating a healthcare UX studio off aging Gatsby infrastructure onto Sanity CMS, animated page transitions, and accessibility-first architecture. Nine document types, card-morph transitions, and a content pipeline that lets non-technical editors publish without touching code.

WRITROSPECT

WRITROSPECT

An AI-assisted journaling tool that solves the blank-page problem. Built on neuroscience research about why people abandon commitments to themselves, with a prompt architecture that adapts to what you actually need rather than loading everything at once.

RENDOMAT

RENDOMAT

A programmatic video studio built at GoInvo. Turns structured content into multi-platform video with professional motion design, replacing a manual production pipeline that took a full day per video with an automated system that renders in minutes.

PHYLACTORY

PHYLACTORY

100,000+ concurrent units in a fantasy game that fuses factory management with real-time strategy. Built a custom Entity-Component-Space system from scratch in Godot 4 with C++ and GDExtension, hand-crafted every sprite and tileset in Aseprite, and designed twelve interconnected game systems such as energy grids, trains, pipes, and formation AI.

Tool

Glass that bends
real pixels.

A standalone WebGL2 engine that renders physically-grounded glass distortion in real time. Every pixel inside the shape is refracted, blurred, and chromatic-aberrated based on its distance from the edge.

01

The Idea

When Figma shipped their glass material effect, the design community lit up, and the immediate question from developers was “how are we supposed to build this?” CSS backdrop-filter: blur() is flat. It treats every pixel identically regardless of position, producing a frosted pane with no sense of shape or materiality. Real glass has curvature: light bends more at the edges, chromatic fringes appear where the surface curves steeply, and the interior carries a subtle distortion that signals thickness.

I decided to answer the question. Glacias recreates these optical properties using signed distance fields to determine each pixel's relationship to the glass boundary, then applies physically-motivated displacement, multi-sample blur, and channel-separated chromatic aberration in a single fragment shader pass. It ships as a standalone package that any project can drop in.

The edge is the whole trick.
Without it, glass is just blur.

02

How It Works

The engine renders a fullscreen quad and samples a background texture through a distortion field. For each pixel, it computes the signed distance to the shape boundary (negative inside, positive outside) and then derives the surface normal from the SDF gradient.

The displacement vector is rotated 90° from the normal to run parallel to the nearest edge (the tangent direction), creating the characteristic light-bending of curved glass. A configurable falloff curve attenuates the effect from full strength at the boundary to zero at the center, with the curve exponent controlling how quickly it drops off.

SDF Shape Engine

Five built-in signed-distance-field primitives, plus support for any arbitrary SVG path converted to an SDF texture via Felzenszwalb–Huttenlocher distance transform.

Edge-Tangent Refraction

Displacement vectors run parallel to the nearest edge, not radially from center. The result reads as light bending through curved glass rather than a pinch distortion.

Chromatic Aberration

RGB channels sample at slightly different UV offsets, creating the prismatic fringing that makes the glass feel like a physical lens with dispersive properties.

Falloff Curve Control

Distortion is always zero at center and full at the edge. A single parameter controls the curve steepness between them, from gentle interior spread to sharp edge concentration.

Fill Tint

Shader-level color overlay with configurable opacity, blended after all refraction and blur passes for consistent tinting that respects the glass effect.

Capability Detection

Runtime checks for WebGL2 support, hardware capability, and reduced-motion preferences. Automatic fallback to CSS backdrop-filter blur on unsupported devices.

03

Any Shape

Beyond the five built-in SDF primitives, Glacias accepts any SVG path and converts it to a distance field texture at runtime. The conversion uses the Felzenszwalb–Huttenlocher distance transform, an O(n) algorithm that computes exact Euclidean distances for every pixel in the texture.

The resulting SDF texture is uploaded to the GPU, where the shader samples it for distance and derives normals via central differences. This means cloud shapes, organic blobs, text outlines, or any closed path can become a refractive glass surface with the same physically-motivated distortion as the built-in shapes.

On this site, the project cards use cloud-shaped clip paths converted to SDF textures, giving each label a unique organic glass silhouette.

04

Try It

Drag the sliders to see how each parameter shapes the glass effect in real time.

Shape

One shader. Zero dependencies.

Glacias is a standalone package with no runtime dependencies beyond an optional React peer dependency. The core engine is pure TypeScript and WebGL2: no Three.js, no post-processing libraries, no build-time shader compilation.

Built with

WebGL2GLSLTypeScriptReactSDFDistance Transform

About

Someone didn't give up on me.
That's why I build.

There is no definitive formulation of a wicked problem.

When I was three months old, I had intestinal volvulus. I wouldn’t stop crying, every doctor had a different explanation, and my parents kept looking until they found one who could see what the others missed.

The choice of explanation determines the resolution.

That persistence saved my life. It also gave me something I’ve carried ever since: the recognition that how you frame a problem determines whether you can solve it at all.

Every wicked problem can be considered a symptom of another problem.

I don’t just say “wicked” because I’m from Massachusetts. In 1973, Horst Rittel and Melvin Webber described wicked problems: the kind where the crying is a symptom of something deeper, and treating the surface never reaches the root.

Every wicked problem is essentially unique.

I started where a lot of CS grads start: writing Perl scripts for an escalation engineering team at Dell EMC, then two jobs in the gaming industry building things that were complex, fast, and fun. But games ship patches. The problems I kept gravitating toward were the ones where you don’t get to patch. I earned a Master’s in bioinformatics because I wanted to bring engineering somewhere the problems don’t repeat: healthcare, government, regulated systems where every deployment is its own context and every patient is their own case.

Wicked problems do not have an enumerable set of potential solutions.

I joined a small studio designing for healthcare and government because the solution space is never closed. There’s no dropdown menu of correct answers. You design, ship, learn, and revise, knowing the next version will be different, not because the last one failed, but because the problem shifted underneath you.

Every solution is a “one-shot operation”; every trial counts.

In regulated environments, every release matters. There are no sandbox deployments when someone’s care depends on the system working. That weight is something I chose, not something I stumbled into.

The planner has no right to be wrong.

When you build software for medical contexts, you carry a specific accountability. The system you ship becomes part of someone’s care, and “move fast and break things” is not an option when the things that break are people.

Wicked problems have no stopping rule.

Over the past several years, that same instinct has pulled me toward problems with no finish line. I started researching neurodegenerative disease on my own, not because I expected to solve it, but because I couldn’t stop looking once I started seeing what others were missing. That’s how I work on everything: once I care about a problem, there is no clean stopping point, only the next question.

There is no immediate and no ultimate test of a solution.

I’ve learned to be comfortable building things I can’t fully validate yet. Whether it’s a healthcare prototype shipping to users whose feedback won’t arrive for months, or a research framework whose predictions won’t be tested for years, the work has to be good enough to act on before you know if it’s right. That uncertainty isn’t a flaw in the process. It is the process.

Solutions are not true-or-false, but good-or-bad.

That’s the lens I bring to everything I build. Not “is this correct” but “is this better.” Better communication, better questions, better tools for the people using them. My independent research on neurodegeneration, Project FELINES, follows the same principle: it doesn’t claim to be the right answer, just a framework that generates better questions than the ones we’ve been asking.

I build software. I design systems. But what drives me is the same thing that’s driven me since before I could talk: someone needs to keep looking until they find what the others missed.

Contact

Let's build something together.

Interested in working together, have a question, or just want to say hello? I'd love to hear from you.