POC: The Potato Optimized Carver

Babylon.js
4 min readMar 9, 2023

--

This weekend, while cooking for my daughter, we decided to whip up some delicious french fries (or, as they should rightly be called, Belgium fries!). As we were cutting them up, I showed her how to carve a face into a potato — and that’s when it hit me. Why not use Babylon.js to create a virtual potato carver? Not only will we save some potatoes for more fries, but we’ll also unleash our creativity in a whole new dimension!

So here we are! To make sure everyone can use the POC, I will insist on the optimized aspect of it. There are several ways we can do a potato carver but I would like to pick a solution that is fast enough so we can use it everywhere even on low end mobile devices. Let’s get ready to slice and dice those virtual spuds with ease!

Setting up the scene

To “simulate” our potato, we will simply set up a deformed sphere with our classic default environment:

Babylon.js Playground (babylonjs.com)

As I want to carve the potato, I would like to mimic what can be found in tools like Blender and use a MatCap material that will help us see the creases more clearly.

Fortunately, my good friend Patrick already did a good video on that topic:

Let’s Talk About MatCaps — YouTube

So I will shamelessly steal his node material and use it in my scene:

Babylon.js Playground (babylonjs.com)

It looks far better!

Now let’s update the node material in NME(nme.babylonjs.com) to add a better potato color.

From this:

Initial Patrick’s shader

We will simply add this at the end to inject our color:

“Potatofication” of the shader

Nothing really fancy, just extract the intensity from the initial color and multiply it with our potato color.

Adding our optimized carver

To carve the potato, I could have chosen to edit the geometry. While it’s doable, it’s not very optimized because all the work is done on the CPU (not to mention the need to recalculate normals after editing the vertices).

Instead, I decided to use a new node that was recently introduced: the HeightToNormal node. This clever little node is capable of updating the normals of a mesh based on a height map. A height map is essentially a black and white texture where the color intensity defines the height of each pixel.

With this node, we can use the MatCap material to introduce the height map, which we can then edit from our app. The carving will be defined by the height map, and it’s pretty fast because all the work is done by the GPU. This makes the process much more efficient and optimized, which means we can carve our virtual potatoes with ease!

So let’s inject our new node in the graph.

Before, the normals were used as is and send to a View transform:

We are going to replace that normal by a modified normal to take in account our height map:

We have to pipe the world position, world normal and world tangent into the node, add the texture and voila!

You can see the final node material here: Babylon.js Node Material Editor (babylonjs.com)

And the beauty of it is that we can use this new node by simply changing one line in our code:

var matCap = await BABYLON.NodeMaterial.ParseFromSnippetAsync("WSJ3VZ#3")
Babylon.js Playground (babylonjs.com)

Controlling the carver

First we need to introduce our own height map:

Babylon.js Playground (babylonjs.com)

That’s a beautiful potato!

To test if our system works well, we can leverage the Inspector and more specifically the Texture Editor:

Painting directly in the texture editor

Ok now we need to capture pointer events to start updating the dynamic texture and we will be good to go:

Babylon.js Playground (babylonjs.com)

Please note that if you maintain SHIFT you can clean your crease.

Now you can unleash your creativity :) Feel free to share your beautiful potatoes on Twitter!

David ‘Deltakosh’ Catuhe
https://www.twitter.com/deltakosh

--

--

Babylon.js

Babylon.js: Powerful, Beautiful, Simple, Open — Web-Based 3D At Its Best. https://www.babylonjs.com/