Joe Gilmore

15 min read

How we made a realtime 3D Text Generator.

Do you like our new 3D Text Generation software? This article explains how we made it using a powerful 3D Library for your browser called Three.js.

How we made a realtime 3D Text Generator.

Part 1 - Enter ThreeJS

How do you generate 3D in a browser - well you can ultimately make use of what is called WebGL, this is the technology that lets your browser talk directly to your graphics card (i.e. the GPU), and allows the millions of pixels to be manipulated by it. However, WebGL is extremely powerful, but also is extremely complicated.

Luckily a guy who goes by the codename mrdoob started writing an amazing JavaScript library called ThreeJS, first launched in April 2010 and has been growing ever since. It is a library that allows you to create and display animated 3D computer graphics in a web browser using the WebGL API.

Lets take a look at the following VanillaJS & ThreeJS code that lets us have a red wireframe cube in the middle of a the screen and a camera that lets us rotate around the cube:

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

// Cursor
const mouse = {
    x:0,y:0
}
window.addEventListener('mousemove', (event) =>{
    mouse.x = (event.clientX / sizes.width - 0.5) 
    mouse.y = -(event.clientY / sizes.height - 0.5)
})

/**
 * Base
 */
// Canvas
const canvas = document.querySelector('canvas.webgl')

// Sizes
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}
window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()
    renderer.setPixelRatio(Math.min(window.devicePixelRatio,2))
})

// Scene
const scene = new THREE.Scene()

// Object
const mesh = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1, 5, 5, 5),
    new THREE.MeshBasicMaterial({ 
        color: 0xff0000,
        wireframe: true
    })
)
scene.add(mesh)

// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
const aspectRatio = sizes.width / sizes.height, AR = aspectRatio;
camera.position.z = 3
camera.lookAt(mesh.position)
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.update(); 
controls.enableDamping = true;

// Renderer
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio,2))


// Animate
const clock = new THREE.Clock()

const tick = () =>
{
    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

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

tick()

...as you can see from the example above, it's a lot of plain vanilla JS. If like me you are used to a framework for your JavaScript (and that framework happens to be React) then you are in for a treat with the next part...

Part 2 - Introducing React Fiber

React Fiber is a layer on top of ThreeJS that allows you to use the power/simplicity of React and JSX to create your 3D scenes. Lets take a look at the same example as above, but this time using React Fiber (Note: We are also using NextJS in this example):

import type { NextPage } from 'next'
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei';

// Make a box function
const Box = () => <mesh position={[0, 0, 0]} scale={20} >
        <boxGeometry args={[1, 1, 1, 5, 5, 5]}  />
        <meshStandardMaterial color={'red'} wireframe={true}/>
</mesh>

// Render the page
const BasicBoxPage: NextPage = (props: any) => <div className="fixed top-0 left-0 right-0 bottom-0 bg-gray-900 text-gray-400 py-40 text-center text-2xl">
    <Canvas camera={{ position: [0, 0, 3] }}>
        <ambientLight intensity={0.5} />
        <Box  />
        <OrbitControls  autoRotate={true} maxDistance={200} minDistance={30} />
    </Canvas>
 </div>

export default BasicBoxPage

You can take a look at the above page here Simple Red Cube using React Three Fiber

...as you can see, by using React Fiber we can now use the power of JSX to create our 3D scene and reduce the amount of code we have to write. Now, it has top be said, that under the hood we are actually using more JavaScript overall that our VanillaJS version, so technically it not as performant as our VanillaJS version, but it is a lot easier to write and maintain.

Coming soon... Check back here soon and I'll be writing about how you can add text to a scene, as well as adding in a simple form to edit the text.