< Back to all blog posts

How we built an interactive 3D Christmas card

Autor: Michal, 23. 12. 2023

Our dear CEO Anna came with a clear goal: create a Christmas card that will be hard to forget.

Did we deliver on that goal? Try it out yourself! https://pf2024.spectoda.com/


The Littlest Tokyo 3D model in threejs left an impression on us. It was simple, it was cute and - most importantly - super fun.

So we’re doing an interactive 3D thing. But since we do light control, it can’t be just any 3D thing. Its going to be a scene with animated lights, controlled from our Spectoda App.

How we’re going to do that?

The plan is:

  • Find a relevant 3D object
  • Add a Spectoda logo and a christmas-themed text
  • Place lights in the scene
  • Control the lights using Spectoda’s C++ firmware
  • All within a browser so that we can send a Christmas wish to our clients

Modelling the scene

Since Spectoda App is built in React, we decided to use React Three Fiber - a React version of the popular library threejs. The scene needed four things:

1. Christmas tree

2. Lights

To add lights on the tree, we placed small spheres randomly on a cone with a similar size as the tree. Which included revisiting some high school geometry textbooks.

while (angle < 360) {
    const x = radius * Math.cos(angle) * Math.random();
    const z = radius * Math.sin(angle) * Math.random();
    const distance = Math.sqrt(x ** 2 + z ** 2);
    const y = -((treeHeight - lightStartY) / radius) * distance + treeHeight;

    leds.push(<Led position={[x, y, z]} color={color} />);

    angle += angleStep;

3. Text

The text is saying “Merry Christmas from Spectoda” in Czech 😛

Adding the light control

Now we need to pair this scene with the interface of our Spectoda App. The goal is to show a QR code above the scene so that the user can access the light controls from his/her phone.

We built Spectoda App for interaction with local devices through Bluetooth. To build our Christmas card, we will need to instead send the commands through WebSockets to a remote client - a feature we call Remote Control and which we’ve been developing for the last 6 months.

The lights will be then rendered with the same code which is running in our hardware installations thanks to the magical power of WebAssembly.

WebAss… What?

WebAssembly (WASM in short) is a technology that allows to run C++ code (or C, Rust, any transpiled code) in your browser. This allows us to run the firmware that normally runs in our controllers in any users browser.

Animation definition starts, as all installations, in Spectoda Studio. This is a workspace we’ve built for light animations definitions and event handling logic. There, we define all the virtual devices in the scene (tree, logo, text) and a logic which handles interactions with toggle button and brightness slider in app, as well as all the animation definitions. The output we get from here is a .tngl file.

Interacting with WASM

With WASM loaded, all thats needed is to load the previously generated code. Then on every frame we ask the WASM generated object what is the current color and rerender the lights.

const updateLedColors = () => {
    const pixelBuffer = controller?.getPort(TREE_TAG);

    if (pixelBuffer) {
      const updatedLeds = leds.map((led, index) => {
        const newLed = new SpectodaLed(led.position);
        newLed.color = new Color(pixelBuffer[index]);
        return newLed;

  useFrame(() => {

  return (
      {leds.map((led, i) => (
        <Led key={i} position={led.position} color={led.color} />

The final result

Try it yourself at https://pf2024.spectoda.com/

I think for a two days work in a two-man team we delivered an incredibly fun demo. Which has many flaws, but is a fun demo nevertheless. And our clients loved it. Or at least those who managed to opened the email and scan the QR.

The flaws include

  • The remote control communication is sometimes slow and unpredictable
  • The loading times are huge, because the 3D model is uncompressed 🤦‍♂️

Why is this demo important for us?

Most importantly, this project connects core technologies we’ve worked on in Spectoda during 2023 and shows a glimpse to where are we headed now.

  • App for light control with dead-simple simple controls for all types of devices
  • Virtual WebAssembly preview that gives us the power to simulate whole light installations, before their… installation. Helping us troubleshoot on-site problems before they even occur.
  • Remote control, which gives our customers total control over their installation, no matter where they are, and gives us the power to assist them in expanding and updating their installations all remotely.

Going into the next year, we're excited to perfect these technologies and eagerly anticipate the new challenges our development team will tackle. A heartfelt thank you to everyone who has been a part of our journey. Happy New Year to all!

linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram