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.
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.