← Projects
Yellow gold solitaire diamond ring with inner-band engraving

Ring Configurator

Date2026-01-18
AuthorAnand Magaji

An embeddable 3D ring player with a postMessage API, built at Morpheus+ so any host UI can drive metal, stone, and engraving live.

Problem
People struggle to picture customizations on physical products until they can see the change happen in front of them.
Contribution
As CTO of Morpheus Plus I designed and built the Houdini-to-WebGL ring player and the host API so jewellery (and later other) UIs could stay thin iframes of the same scene.
Impact
The same player powered luxury product pages and developer demos; the pattern later scaled into larger configurators for cars and materials.
Demo access

Open live demo — Player and UI demos are public; the interactive sections below embed the live player.

This project is from May 2024. I am publishing the write-up here in January 2026 so it sits with the rest of the Magaji.dev case studies. I designed it for Morpheus+ as a demo for a jewellery client, while I was CTO of Morpheus Plus.

It is easier for customers to visualize customizations they are making on physical objects when they can see those changes live. That is the whole pitch. Jewellery is the example here, but the same idea applies to almost anything you would rather not order blind.

We kept the 3D piece intentionally dumb from the host’s point of view: a transparent iframe, like a YouTube embed, that listens for JSON messages. The host owns the brand, the cart, and the copy. The player owns the ring, the lighting, and the camera.

Same scene, different chrome. The interesting part is how thin you can make the UI once the player is honest about its API.

One text field, three rings

Each frame below is its own instance of the player. Metals, stones, camera poses, and fonts start different. The text box at the bottom only updates the engraving normal map, and each ring keeps its own font.

Gold diamond, cursive engraving
Platinum ruby, serif engraving
Gold topaz, monospace engraving

One text field, three fonts: cursive, serif, and monospace. Drag any ring to orbit; each starts from a slightly different band angle.

Same player, two UIs

The prototype UI dump at Morpheus+ was never meant to be the product. The product is whatever skin you put around the iframe. Here are two made-up brands on the same API: Vespera as a quiet retail panel, and Sparkkit as a louder product demo.

Vespera

Possible to engrave

Solitaire


A quiet band and a single stone. Change the metal and watch the same player update without reloading.

Yellow gold

A guided shop (dummy checkout)

Vespera again, this time as a short flow: metal, shape, gem, engraving, review, then a fake place-order step with additive demo pricing. Nothing is charged. You can reset and walk it again.

Demo boutique

Vespera

$3,775

Vespera Solitaire

Configure metal, cut, stone, and engraving. Prices are demo-only; nothing is charged.

  1. Metal
  2. Shape
  3. Gem
  4. Engrave
  5. Review
  6. Done

Choose a metal

How the player is put together

The geometry is a Houdini GLTF export. Node names matter: Body for the band metal, BodyText for the engraveable strip (UVs and tangents for normal maps), and gem1 / gem2 / gem3 for alternate cuts. Materials are not baked into the file; the Svelte / Threlte app applies metal and refraction in code.

Engraving is a canvas texture pipeline. Text is drawn as a height field, converted to a normal map, and paired with a darker diffuse so the band can pick up metalness variation on BodyText only. That is why a host can change copy and font without shipping a new mesh.

Camera poses are bookmarked on the player side. Hosts send a pose payload, then ask the player to tween to it. Shadows and render quality (canvas DPR) are the same message channel. Orbit can be locked or left free depending on the demo.

Host API (postMessage)

Embed the player at https://demo-01-re.morpheus.plus/ (same origin used as the postMessage target). There are no URL params and no npm package: the host owns brand, cart, and copy; the iframe owns the scene.

iframe.contentWindow.postMessage(
  JSON.stringify({ metal: 'gold', shape: 1, gem: 'diamond' }),
  'https://demo-01-re.morpheus.plus/',
);
Field Type Role
metal 'gold' | 'platinum' Band material
shape 1 | 2 | 3 Cut: Round / Emerald / Oval
gem 'diamond' | 'ruby' | 'topaz' Stone type
text string Engraving copy
textSize number Engraving glyph scale
font 'sans-serif' | 'serif' | 'monospace' | 'cursive' Engraving typeface
quality number Canvas DPR / render quality
shadow boolean Shadow pass on/off
autoPose boolean Ask the player to tween after a change
poseDefault number Bookmark index on the player
poseCurrentValues CamPose Explicit camera (see below)
poseCurrentSet number Apply / tween when set (e.g. 1)
debug boolean Player-side debug aids

CamPose shape:

Key Role
position { x, y, z } camera position
lookat { x, y, z } orbit target
toggles.enableZoom / toggles.enablePan Free orbit vs locked framing
limits.zoomMax / limits.zoomMin Optional zoom clamp

The player can reply with camera telemetry when asked. Partial payloads are fine: send only the fields you want to change.

I built this first as a jewellery proof, then we used the same configurator idea on larger, messier products. The parent case study for that Saddles-era work is Saddles International. Two public cousins of the embed pattern are car.saddles.studio and the material configurator. Different domains, same habit: keep the viewer embeddable, push product logic into the host.

Live demos

If you are building a customizer and want the viewer to stay a black box with a clear message surface, this is the shape I still reach for.

NORMAL
Made with in Bengaluru, IN
↑ Top
Made with in Bengaluru, IN
© 2026 by Anand Magaji <magaji.dev>

Commands & shortcuts