“This is the 19th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”.

What happens when video games meet Web 2.0? When virtual worlds meet geospatial maps of the earth? When simulation becomes reality, life and business become virtual? When you use virtual Earth to navigate the physical earth, your avatar becomes your online proxy? All of this is happening in the meta-universe.

The meta-universe envisions a future reshaped by the widespread use of virtual worlds and 3D technology. Three.js is a very impressive JavaScript 3D library that also uses WebGL (or 2D Canvas) for rendering. With the improvement of the WebGL API standard and support for WebXR, three.js is a mainstream tool that can be used to create an immersive experience. At the same time, browser support for 3D rendering and WebXR device apis has improved, making the Web an increasingly attractive platform for 3D content.

Three.js

Three.js is a JavaScript library developed by Ricardo Cabello (@mrdoob) in 2010 (it has many contributors on Github today). This incredible tool allows users to process 3D graphics in a browser in a very simple and intuitive way using WebGL technology. WebGL technology is already very popular and widely supported by browsers.

WebGL creates rich interactive experiences across many devices and browsers. Click to see browser support.

start

This article will use Vue as the base to build the sample three.js. Check out GitHub for the code.

First install dependencies:

npm install three --save
Copy the code

build

Now start adding code to the page as follows:

<template> <div id="app"></div> </template> <script> import * as THREE from "three"; export default { name: "App", data() { return {}; }, mounted() { this.init(); }, methods: { init() { const scene = new THREE.Scene(); Const camera = new THREE.PerspectiveCamera(75, window.innerwidth/window.innerheight, 0.1, 1000); camera.position.z = 4; // Create an antialiasing renderer const renderer = new THREE.WebGLRenderer({antialias: true}); // Configure the renderer to clear the color renderer.setClearColor("#000000"); Renderer. setSize(window.innerWidth, window.innerheight); / / add the renderer to DOM document. The body. The appendChild (the renderer. DomElement accordingly); // Create a cube grid const Geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: "#433F81" }); const cube = new THREE.Mesh(geometry, material); // Add the cube to the scene scene.add(cube); const render = function () { requestAnimationFrame(render); Cube. Rotation. X + = 0.01; Cube. Rotation. + y = 0.01; renderer.render(scene, camera); }; render(); ,}}}; </script>Copy the code

Then add a simple style:

body {
    margin: 0;
}
canvas {
    width: 100%;
    height: 100%;
}
Copy the code

Run the yarn serve script. Open the browser and the following information is displayed:

This is a common pattern for every three.js application, including WebGlRenderer, Scene, and Camera, as follows:

  1. Create rendererWebGlRenderer
  2. createScene
  3. createCamera

The renderer is where the scene results are placed. In three.js, you can have multiple scenes, and each scene can have a different object.

In the example, you create the WebGLRenderer, pass it the size of the window as a parameter, and attach it to the DOM.

// Create an antialiasing renderer const renderer = new THREE.WebGLRenderer({antialias: true}); // Configure the renderer to clear the color renderer.setClearColor("#000000"); Renderer. setSize(window.innerWidth, window.innerheight); / / add the renderer to DOM document. The body. The appendChild (the renderer. DomElement accordingly);Copy the code

First we need to create an empty scene to which we will add the cube object we created:

const scene = new THREE.Scene();
Copy the code

Finally create a camera camera and take the field of view, aspect ratio, near plane and far plane as parameters:

Const camera = new THREE.PerspectiveCamera(75, window.innerwidth/window.innerheight, 0.1, 1000);Copy the code

At this point, the Three basic elements of the three.js application are complete.

Geometry, materials and grids

The second common pattern is to add objects to a scene:

  1. Create geometry
  2. Create the material
  3. Create a grid
  4. Add a grid to the scene.

In three.js, mesh is a combination of geometry and materials.

Geometry is a mathematical formula for objects. There is a lot of geometry in three.js, which will be explored in a later chapter. Geometry provides vertices for objects to add to the scene.

A material can be defined as a property of an object and its behavior with the scene light source. As shown in the picture below, there are different types of materials.

Now that you know what the mesh, geometry, and materials are, you’ll add them to the scene. In the example, create a cube using a basic material:

// Create a cube grid const Geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: "#1b55e3" }); const cube = new THREE.Mesh(geometry, material); // Add the cube to the scene scene.add(cube);Copy the code

Request animation frame

The last piece of code is to set up an animation for the scene, using requestAnimationFrame, which allows a function to run at 60 frames per second (maximum).

const render = () => {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
};

render();
Copy the code

Cube animation

To animate the cube in the render loop, you need to change its properties. When creating a grid, you have access to a set of properties that are useful in animation.

// The Rotation (XYZ) is done in a circle. cube.rotation.y; cube.rotation.z; // Position (XYZ) cube.position.x; cube.position.y; cube.position.z; // Scale (XYZ) cube.scale.x; cube.scale.y; cube.scale.z;Copy the code

In the example, animate X and Y rotation for the cube:

Cube. Rotation. X + = 0.01; Cube. Rotation. + y = 0.01;Copy the code

The console

As a front-end, the console is the best debugging tool. The console is an essential tool when working with three.js.

The effect to increase

Now that you understand the logic of the example, more fragments will be added to the scenario with the goal of generating more complex fragments.

/** * Create texture */ const createMesh = (boxOptions, meshOptions) => {const geometry = new THREE.BoxGeometry(... boxOptions); const material = new THREE.MeshBasicMaterial(meshOptions); return new THREE.Mesh(geometry, material); }; const cube01 = createMesh([1, 1, 1], { color: "#A49FEF", wireframe: true, transparent: true, }); scene.add(cube01); const cube01_wireframe = createMesh([3, 3, 3], { color: "#433F81", wireframe: true, transparent: true, }); scene.add(cube01_wireframe); const cube02 = createMesh([1, 1, 1], { color: "#A49FEF", }); scene.add(cube02); const cube02_wireframe = createMesh([3, 3, 3], { color: "#433F81", wireframe: true, transparent: true, }); scene.add(cube02_wireframe); Const bar01 = createMesh([10, 0.05, 0.5], {color: "#00FFBC",}); Bar01. Position. Z = 0.5; scene.add(bar01); Const bar02 = createMesh([10, 0.05, 0.5], {color: "# FFFFFF ",}); Bar02. Position. Z = 0.5; scene.add(bar02); const render = () => { requestAnimationFrame(render); Cube01. Rotation. X + = 0.01; Cube01. Rotation. + y = 0.01; Cube01_wireframe. Rotation. X + = 0.01; Cube01_wireframe. Rotation. + y = 0.01; Cube02. Rotation. X = 0.01; Cube02. Rotation. - y = 0.01; Cube02_wireframe. Rotation. X = 0.01; Cube02_wireframe. Rotation. - y = 0.01; Bar01. Rotation. Z - = 0.01; Bar02. Rotation. + z = 0.01; renderer.render(scene, camera); }; render();Copy the code

After running, the effect is shown as follows: