3D Glowsion Ball with Three.js
Published: 2023-07-09 04:53:51


## Introduction
We are going to make a `Glowsion Ball` in [three.js](https://threejs.org/). What is glowsion ball, you may ask? Well, I just came up with this name just because it sounded cool.

## TLDR;
{% codepen https://codepen.io/dinesh-gdk/pen/bGQoQrP %}

## What?
**three.js** is an open-source graphics library in javascript. It uses WebGL API to render graphics and can also utilize GPU. It is used to build 2D and 3D graphic animation on websites. It is not a drop-in replacement for the game engines, but just a simple one that helps us to build beautiful websites.

We are not going to see the basics of computer graphics, we are going to see the basic building blocks just to stitch a cool ball.

## Basics
We need just simple HTML and CSS to get started. We need a `canvas` element in our `body` and some simple CSS to take care of silly stuff like background color, overflow, ...

## Build
Import all the necessary modules. Get the HTML canvas element. Also, store the window sizes in an object, so it makes our life a bit easy.
```js
// Sizes
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight
}

// Canvas
const canvas = document.querySelector('#canvas');
```
### Main Components
There are four main components to render graphics
- Scene
- Camera
- Light source
- Renderer

Here we are not going to use a light source, because we are creating a glowing ball.
```js
// Setup
const scene = new THREE.Scene();

// Camera
// https://threejs.org/docs/#api/en/cameras/PerspectiveCamera
const camera = new THREE.PerspectiveCamera(
    75,
    sizes.width / sizes.height,
    0.1,
    100
);
camera.position.set(0, 10, 0); // place the camera at this position
camera.lookAt(0, 0, 0); // point the camera to this position

// Renderer
const renderer = new THREE.WebGLRenderer({canvas: canvas})
renderer.setSize(sizes.width, sizes.height); // size of the canvas
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // pixel ratio
```
Now we are going to create the glowsion ball. We need to create a mesh. A mesh is an object you render on the canvas. We need to define two things to create a mesh
- Geometry
- Material

For the geometry, we are going with sphere, for the material we going to create custom shaders.

### Shady
We need two shaders
- Vertex Shader (modifies the shape of the geometry)
- Fragment Shader (modifies the pixel value, color on the geometry)

Both of them are written in GLSL (OpenGL Shading Language). This is where things get complicated. Learning GLSL is a full-time job on its own. To keep things simple we are skipping this part and voila we have our custom shaders.

```js
// Objects
const glowsion = new THREE.Mesh(
  new THREE.SphereGeometry(1, 64, 64),
  new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader,
    side: THREE.DoubleSide,
    uniforms: {
      uTime: { value: 0 },
      uResolution: { value: new THREE.Vector2() },
      uDisplace: { value: 2 },
      uSpread: { value: 1.2 },
      uNoise: { value: 16 },
    },
  })
);
```
You can view the vertex shaper [here](https://codepen.io/dinesh-gdk/pen/KKrXjQd) and fragment shader [here](https://codepen.io/dinesh-gdk/pen/yLQzdvO)

Now add the object and camera to the scene
```js
scene.add(glowsion);
scene.add(camera);
```
### Post Processing
Right now the glowsion ball is bland. To add a wow factor we are going to do some post-processing by adding **Bloom Pass**.
```js
// Post Processing
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));

// Bloom Pass
const bloomPass = new UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
  1.4,
  0.0001,
  0.01
);
composer.addPass(bloomPass);
```
### Final Loop
Add things in the loop and we get **Glowsion Ball**.
```js
// Animate
const clock = new THREE.Clock()
const tick = () => {

    // Update objects
    // You can use any function to move the object
    glowsion.rotation.x = 5 * Math.tan(clock.getElapsedTime() + 0.25);
    glowsion.rotation.y = Math.tan(clock.getElapsedTime() + 1.0);
    glowsion.rotation.z = 5 * Math.tan(clock.getElapsedTime());

    // Render
    renderer.render(scene, camera);
    composer.render();

    // Call tick again on the next frame
    window.requestAnimationFrame(tick);
}

tick();
```
## Conclusion
I hope this article gave you a fun introduction to [three.js](https://threejs.org/). There is so much you can do with this library. You can check out the website and see the cool projects. Also, I have created a cool three.js animation of some planets, check it out [here](https://dinesh-gdk.github.io/planets_3D/). Happy learning!