What is Satin?

Satin is a 3D graphics framework (inspired by Three.js) that helps designers and developers work with Apple’s Metal API more easily and effectively. It provides a set of helpful abstractions and classes for creating meshes, materials, buffers, uniforms, geometries, pipelines (shaders), compute kernels, and more.

Satin is primarily written in Swift, but when it comes to performance-heavy CPU operations, it uses SatinCore — a C-based library —for tasks like geometry generation, triangulation, bounds calculations, and other computational geometry processes. This keeps things fast and efficient.

👉 Check out the code: https://github.com/Hi-Rez/Satin

What Can Satin Do for You?

Satin makes simple graphics tasks fun and fast, and it makes complex tasks easier to manage — without drowning in boilerplate. By providing structure, clear design opinions, and powerful abstractions on top of Metal, Satin saves you from rewriting the same low-level code over and over.

You can focus on the creative stuff — composing scenes, manipulating objects, writing shaders and compute kernels, designing visual effects, and building dynamic, reactive interfaces.

Modern graphics APIs like Metal are powerful but complex. They differ significantly from the simplicity of old-school OpenGL. You need to understand a lot — matrices, shaders, command queues, buffers, pipeline states, vertex descriptors, memory layouts, and more — just to get started.

Metal is the most elegant of these APIs, but it still requires deep knowledge to be productive. For many, that’s overwhelming.

Satin provides a playful abstraction layer so you can focus on the what — what are we rendering, how is it shaded, how does it respond to input — rather than the how. It introduces a simple interface via the MetalViewRenderer class. If you’ve used Processing or openFrameworks, you’ll recognize familiar lifecycle functions like setup, update, and resize. (Swift gives us init too, but let’s not get into that…)

Once you’ve created a scene object (Object3D, similar to Three.js), you can add other objects, like meshes. The Mesh class is a subclass of Object and conforms to the Renderable protocol — meaning Satin’s renderer knows how to draw it. A mesh is composed of a Geometry and a Material, just like in Three.js. Satin also includes a complete scene graph with transformation support and Combine-based publishers so you can easily react to changes like position, rotation, or scale updates.

One of Satin’s standout features is live shader coding. This is a game-changer when iterating on both visual design and performance. Satin handles the nitty-gritty: Metal file compilation, file watching, dynamic uniform parameters, and shader caching. You can write a line like material.set("Time", currentTime) and Satin handles everything under the hood — even dynamically reconstructing structs in Swift.

If you’ve ever done low-level memory manipulation in Swift for Metal, you know how messy it can get. Satin abstracts those details so you can focus on creativity, not memory layout. Curious how this works? Check out the ParameterGroup and UniformBuffer classes in the repo.

This post isn’t a full Satin tutorial, but if you’re interested in learning more, the Example app on GitHub shows how to use the API to build interactive scenes, effects, and compute-based systems.

Why Did I Make Satin?

There were lots of reasons, but in hindsight, here’s what really motivated me:

  • I wanted a live coding environment for Metal shaders—something inspired by new media art, creative coding, and the installations I worked on in my 20s.

  • In 2019, I wanted to learn Swift. Having a concrete project helped me stay focused.

  • I wanted to reinvent the wheel—not as a productivity hack, but as a way to deeply understand the math and mechanics behind real-time rendering (e.g., matrix math, shadow mapping, PBR, path tracing).

  • I hoped it could become a calling card for client work. Open source had helped raise my profile in the past, and I saw Satin as another way to connect with interesting collaborators.

  • I didn’t want to just use Unity—I wanted to make my own Unity.

  • I was excited about procedural and generative art (this was pre-generative-AI) and wanted a lightweight, expressive environment for GPU compute and rendering. You can see some of what I made on my Instagram.

  • I wanted a toolset that integrated smoothly into Apple’s ecosystem, which is where I felt most at home.

What Can You Create with Satin?

Just about anything that requires custom rendering: games, design tools, novel interfaces, interactive art, shader experiments, AR effects, real-time visuals, path tracing, etc. 

Skeptical? After browsing my Instagram, check out Valence 3D, a full 3D modeling app that uses Satin under the hood for all rendering and Metal integration. Valence builds on Satin by extending its Object class and Renderable protocol to support custom scene management and complex rendering.

Below you’ll find a gallery for random experiments, interfaces, path traced images and more. Satin was used to render these images.

Want to Get Involved?

There’s an active fork where development is ongoing. Anton Marini (aka Vade), a longtime friend and creative tech legend, has taken the reins. He’s building awesome new features and refining the API to make it more powerful and more fun.

Credits

Satin was primarily developed by me, but it wouldn’t be what it is without support from others.

My brother Haris Ali — an incredible software engineer and architect — helped shape the early structure of the project. He set it up for adoption via CocoaPods and later Swift Package Manager, and taught me the powers of CMake and how to compile Satin into an XCFramework. He’s fearless in the face of any codebase, and I’m lucky to be his brother.

Big thanks to Taylor Holliday, creator of Audulus and Sculptura, who inspired me to build my own engine and offered feedback on several key patterns in Satin. Taylor is one of the indie app developers I most admire.

Finally, eternal gratitude to the open source communities behind Three.js, Processing, openFrameworks, and Cinder. These frameworks taught me to explore the world through code and to use computation as a creative medium. They gave me the tools to deeply learn math, geometry, physics, color, form, simulation — and to play with it all.

I hope Satin finds a new community to evolve it into whatever it wants to become next. Whether you’re building something big or just learning Metal, I hope it inspires you — or at the very least, saves you from writing a bunch of boilerplate code.