Blog /

Creating 3D scans for the web

image-alt

This is a super simplified process. Each step a marvel of modern software and each potentially a whole workflow unto itself. But this is how I got a 3D render of myself onto my homepage.

Step 1: Scan your face (or whatever) with Polycam

Using Polycam feels like magic. Simply wave your phone around an object for a couple minutes and you'll have a 3D model of it on your computer. What's more, they offer a free tier that lets you try out its capabilities without spending money.

You can use lidar but photo mode will give you better results when capturing smaller objects. Complete your capture and wait until Polycam is done processing your data. And here's the magic, a 3D render of your object will be presented to you in about 10 minutes.

3D render of myself in Polycam
3D render of myself in Polycam

For my purposes, this render did not need to be perfect. One scan attempt with 80 images was good enough for me. You can quickly export your model as a gltf file and literally just airdrop the model (complete with textures) to your computer.

Step 2: Clean up your object.

From here you could skip straight to step three but cleaning up your gltf file is worth the effort. Import the model into Blender and you'll see something like this.

gltf file imported into Blender
gltf file imported into Blender

My scan resulted in some background being unintentionally included within the model. I simply deleted those vertices in Blender's edit mode and textures remain in tact throughout this process.

After removing the excess nodes, I was still left with a model containing ~48,000 triangles. This is a heavy object to use in browser so additional refinements should be made.

screenshot of Blenders edit mode highlighting high number of triangles
screenshot of Blenders decimate modifier

Using Blender's decimate modifier will quickly lower the number of tris. On my model, I easily halved the number of triangles supplied by Polycam before noticing any change in quality.

There were some random portions in my model that didn't feel right (a giant hole in my hat for example) that required some additional work but the bulk of the adjustments were handled automatically by Blender.

After the model is cleaned up delete any other objects from the blender scene and export it as a glb.

Step 3: Load the model into your Three.JS scene

This article doesn't delve into the complexities of development and I don't consider myself a developer. However, Three.JS is one of the most widely adopted tools used to create 3d scenes in the browser and its basic execution is really simple. With just a little bit of finessing you can have your model live in browser quick.

Code from threejs docs outlining the basic implementation of a scene containing a single block
The basic THREE.JS rotating green cube

The secret is the GLTFloader addon which let's you load the scene you exported from Blender into Threejs. Once the scene is loaded you will almost certainly need to adjust the scale of the scene. (Aside — if you're having trouble the Three.js chrome extension might be helpful. Initially, my scene was so small I didn't realize it was loading. Using the extension helped me identify what loaded.)

Add a few lights and maybe some rough orbit controls and you're done!

Javascript code to load the model into the Three.JS scene
Javascript glb loader code

Optional Step 4: Style your model

The models loaded here have a kinda plastic quality. A semblance of real life without feeling real. Maybe that's the uncanny valley you're aiming for but probably not. Adding materials or post processing effects will do wonders to align it to the overall aesthetic of your site.

In my case I wanted a sort of digital aesthetic inline with the modern dithering/shader effects that seems so popular. The ascii effect included with three.js isn't super performant so I opted to use Sladjan Ilic's shader. After zhuzhing the properties a bit, I had the result I wanted.

Final 3D render
Final 3D render

Author's note: The actual implementation of this model has room for improvement. Actual dithering might be more effective than ascii.