Pointcloud effect in Three.js
Tags: javascript, threejs, pointcloud, 3d
Published: 2019-05-25 23:58:49

---
title: Pointcloud effect in Three.js
published: true
description: Create a basic pointcloud effect in threejs! 
tags: js, threejs, pointcloud, 3D
cover_image: http://assets.imanidap.nl/dev/pointcloud.jpg
---

Not too long ago I built a site that served as a submission for a small competition. To spice it up, I decided to add some Three.js. An effect that has been on my mind for a pretty long time was the pointcloud. Austin Mayer has implemented a really cool one with effects on his website and I've been thinking about since I've seen it on his site.

{% twitter 1098662776929693706 %} 

Since the site had a little more to it, I decided to implement a super basic version of a pointcloud. Three.js provides a few functions that enable you to create a pointcloud pretty quickly.


# Points instead of Mesh

A mesh (3d object) in Three.js consists of geometry and material.  But instead of showing an entire mesh you just want to show the vertices. The [`Points`](https://threejs.org/docs/index.html#api/en/objects/Points) class in Three.js can take a geometry and display points instead of the 'full' object. With [`PointsMaterial`](https://threejs.org/docs/index.html#api/en/materials/PointsMaterial) you are able to control the size of your points. The code for a 'pointcloud mesh' looks something like:

```javascript
  let geometry = new THREE.TorusGeometry(10, 3, 16, 100)
  let material = new THREE.PointsMaterial({ color: 0xFFFFFF, size: 0.25 })
  mesh = new THREE.Points(geometry, material)
  
  scene.add(mesh)
```


For the full code, click/press on the example and check out `main.js` in the code tab!
{% glitch three-pointcloud-1 app %}


# Using 3D models 

It's possible to load 3D models in Three.js but you have to put in a little extra work. Depending on the format of the 3D model you have to load a loader in addition to the main library. I love to use .obj models myself so I personally need the `OBJLoader`.

If you load the library through an HTML tag you have to add an extra tag that loads a seperate script that comes with the Three.js download. This script can be found in `examples/js/loaders/OBJLoader.js`. 

If you have included the entire folder loading it will be kind of like: 
```
<script src="three/examples/js/loaders/OBJLoader.js"></script>
``` 

If you use npm, you can import the loader through the jsm folder. Keep using the js folder if you prefer the require syntax though! The import statements look something like this: 
```javascript
//import syntax
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'

//require syntax, require adds OBJLoader directly to THREE
require('three/examples/js/loaders/OBJLoader.js')

```

Loaders work a bit like an extend 'fetch' without promises. You insert a url of the file containing the model, the loader will execute a http request. You provide callbacks for a successful request, a request that is still in progress and an unsuccessful request. 

You can get the geometry of the object you loaded by selecting the first child's geometry of the result.   

```javascript
const loader = new THREE.OBJLoader()
loader.load('https://cdn.glitch.com/fcf3c007-b4eb-4250-ba6b-653fdab94ce3%2Fjapanese_temple.obj?1558792651869',
(obj) => {
    // the request was successfull
    let material = new THREE.PointsMaterial({ color: 0xFFFFFF, size: 0.25 })
    mesh = new THREE.Points(obj.children[0].geometry, material)
    mesh.position.y = -15 //this model is not exactly in the middle by default so I moved it myself
    scene.add(mesh)
},
(xhr) => {
    // the request is in progress
    console.log(xhr)
},
(err) => {
    // something went wrong
    console.error("loading .obj went wrong, ", err)
})
```

{% glitch three-pointcloud-2 app %}

Small disclaimer: 3D models can be build in 3D modeling software like Autodesk Maya3D and Blender with geometry and 'modifiers'. If a very big part of the model is created with modifiers the points won't show up in a way you can 'see' the object when you apply the pointcloud. That's why it's very important that you always test 3D models you want to use specifically for this purpose. 

# A little control 
Interactivity will always make something a lot more fun. Hover and morph effects like on Austin Mayer's site definitely take effort and time to create. But three has functionality you can quickly add to at least give users the ability to move the camera around with `OrbitControls`. Like 3D model loaders the controls are an extension you have to load. Orbit controls are located in `examples/js/controls/OrbitControls.js` (or `examples/jsm/controls/OrbitControls.js` using the import syntax). The code looks a little like this: 

```javascript
 camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.z = 40
  
  const controls = new THREE.OrbitControls(camera)
  controls.enableZoom = false //zoom happens on scroll which can be quite annoying
```

{% glitch three-pointcloud-3 app %} 

I hope this helps as a 'getting started' on creating pointclouds in Three.js!

# Credits 
I got a lot of moral support from my best friend Sven, who also submitted a website to compete. I had a lot of doubt and wasn't sure wether I should submit anything at all. I'm glad he convinced me, because we are both be in Shanghai this winter 🎉. In case you want to know a little more, he wrote an article a while ago:

{% link https://dev.to/sven/why-i-struggled-with-creating-an-account-here-and-why-i-did-it-5ah %}