67 lines
4 KiB
Markdown
67 lines
4 KiB
Markdown
---
|
|
title: Tile-Based Optimization for 2D SDF Ray Tracing
|
|
description: How SDF-2D used signed distance fields, dynamic shaders, and tile-based rendering ideas to make 2D ray tracing run well in the browser.
|
|
date: 2026-05-08
|
|
projectPeriod: 'Autumn-Winter 2020'
|
|
thumbnail:
|
|
src: ./_assets/sdf2d.jpg
|
|
alt: SDF-2D browser demo with soft lighting effects.
|
|
tags: ['graphics', 'web', 'systems']
|
|
featuredOrder: 3
|
|
role: Library author
|
|
stack: ['TypeScript', 'WebGL', 'WebGL2', 'Signed distance fields']
|
|
scale: Browser library with mobile-oriented real-time rendering and reusable demos
|
|
outcome: Reusable NPM package and thesis project for efficient 2D SDF rendering
|
|
audience: recruiter-relevant
|
|
links:
|
|
- label: NPM package
|
|
url: https://www.npmjs.com/package/sdf-2d
|
|
- label: Video
|
|
url: https://www.youtube.com/watch?v=K3cEtnZUNR0
|
|
- label: BSc thesis
|
|
url: /media/downloads/sdf2d-andras-schmelczer.pdf
|
|
download: true
|
|
media:
|
|
- type: image
|
|
src: ./_assets/sdf2d.jpg
|
|
alt: Browser demo page showing SDF-2D scenes rendered with soft lighting effects.
|
|
caption: SDF-2D was built as a reusable TypeScript library rather than a single demo.
|
|
---
|
|
|
|
SDF-2D was my attempt to make a small, reusable browser library for 2D scenes rendered with ray-tracing techniques. The rendering is based on signed distance fields, where geometry can be represented as functions that return the distance to the nearest surface.
|
|
|
|
The interesting part was not the basic idea. Signed distance fields are a known technique. The interesting part was making the approach fast and reusable enough for browser demos, including on mobile devices.
|
|
|
|
The project became one half of my BSc thesis, together with the multiplayer game `decla.red`, which used the rendering library in a real interactive setting.
|
|
|
|
## The Problem
|
|
|
|
Ray tracing and distance-field rendering can produce appealing 2D lighting and reflections, but a straightforward implementation spends too much work per pixel. A browser library also has to deal with device variation: WebGL capabilities, shader limits, mobile GPUs, and the overhead of generating scenes dynamically.
|
|
|
|
The goal was not to render one hand-tuned scene. The goal was a library with a simple API, reusable scene definitions, and real-time behavior.
|
|
|
|
## Constraints
|
|
|
|
The library had to support both WebGL and WebGL2. It had to run acceptably on phones. It had to avoid shipping scene-specific shader code by hand. And it had to expose an API that felt like a rendering library rather than a shader experiment.
|
|
|
|
Those constraints pushed the implementation toward generated shaders and capability-aware rendering paths.
|
|
|
|
## Design
|
|
|
|
The main optimization was inspired by tiled renderers. Instead of treating the entire screen uniformly, the renderer could reason about groups of pixels and avoid unnecessary work where possible.
|
|
|
|
That was paired with deferred shading and dynamic shader generation. Dynamic generation mattered because scenes and devices differ. If a feature or operation was not needed for a given scene or device, the generated shader could avoid carrying that cost.
|
|
|
|
The API was deliberately kept in TypeScript. That made the library easier to package, document, and reuse in projects that were already browser-first.
|
|
|
|
## What Worked
|
|
|
|
The project worked best when the library boundary was respected. A good demo can hide a messy implementation. A reusable package cannot. The API had to explain the rendering model without making every user think like a shader compiler.
|
|
|
|
The mobile constraint also improved the design. It forced performance work to be structural rather than cosmetic. When a technique works only on a powerful desktop GPU, it is easy to mistake headroom for good architecture.
|
|
|
|
## What I Would Change
|
|
|
|
Today I would write more instrumentation around shader variants and device behavior. The project had many optimizations, but stronger profiling output would have made tradeoffs easier to explain and compare.
|
|
|
|
I would also document the rendering pipeline with diagrams. The ideas are visual, and the explanation should be too.
|