Animating scenes with WebGL + three.js
3D graphics, technology, product creation, and the Internet: these are just a few of my hobbies.
Now, thanks to the advent of WebGL-a new JAVASCRIPTAPI, it can render 3D images in the browser without relying on any plug-in-which makes the 3D rendering operation incredibly simple.
With the development of virtual reality and augmented reality applications, large manufacturers are turning to digital tactile experience, which is an exciting technology.
Or, at least those who have already invested in the year are hopeful-$ 1.1 billion into the VR and AR fields.
From the Abbey Road Studios's Google Interactive tour to the fleet that captures deadliest catch, all products, services and environments are better matched by the immersive experience of the audience in the non-real world.
As people get to know more about experiential technology, 2D starts to get a little monotonous. That's the truth.
Let's be realistic. At present, many applications dedicated to creating experiences are still in the technology exploration stage, and the outlook for most business areas is not clear.
Or did they really create an exciting experience?
Go to WebGL: A practical and flexible technology that creates stronger immersive 3D content. Whether it's Porsche showcasing a new 911 detail, or what NASA highlights as Mars, or J Dlla's favorite Donut album celebration, WebGL can be used in many areas to represent various types of stories.
To familiarize you with this powerful technology, I'm going to do a brief summary of how it works, and a quick tutorial that uses three.js, a JavaScript library based on the WebGL API, to create a simple 3D environment step-by-step.
First, what is WebGL?
WebGL is a web technology that showcases hardware-accelerated 3D images in a browser without the need to install additional plugins or download redundant software.
As a result, many audiences have more convenient access to WEBGL. Browser support is also very good (currently widely used), Chrome,firefox,ie,opera and Safari and other mainstream mobile and desktop browsers are providing good support.
Many computers and smartphones have advanced image rendering units (GPUS), and until recently, most Web pages and mobile sites were unable to use GPUS. This results in slow loading of the device, low image quality, and low support for 3D content.
WebGL spent a lot of time trying to solve this problem. Based on the well-known OpenGL 3D image Standard, WebGL gives JavaScript plug-in free access, connects a device's image hardware via the HTML5 element, and applies 3D technology directly to the browser. The result is a 360-degree 3D content that is easier to create-eliminating interference with standalone apps or plugins-and making it easier for users to have a high-definition experience on the web.
What is Three.js?
There is little difference between OpenGL and WebGL complexity.
Three.js is an open source grammar library that simplifies the creation of WEBGL tools and environments. It supports most GPU-accelerated low-code 3D animations.
Talk about it, let's write the code.
The example uses the Three.js library to show more complex effects. To practice, I'll try to write as simple as possible, using a low-complexity environment to show what the basics of understanding can achieve.
I'm going to build an example that we've used.
Let's start by doing something basic knowledge.
A renderer, a scene, and a camera
Code Link First Step
Contributor Matt Agar (@agar)
The code is published in Codepen.
Click and drag this example to do something
The example on Codepen is equivalent to getting started, and now we're starting with three.js.
Firstly we need a Scene -a group or stage containing all the objects we want to render. Scenes allow you to set the up and where are going to being rendered by three.js. This is the where you place objects, lights, and cameras.
First we need a scene -a group that contains all the objects we want to render. The scene allows you to set the object and render location to be rendered by the three.js, and how to render it. This scene refers to the place where you place objects, lights, and cameras.
`var scene = new THREE.Scene();`
-Create a scene in a good way
Next we add a camera to this example. I'm adding a perspective camera , but there are other options available. The first two parameters indicate the camera's field of view and aspect ratio respectively. The last two parameters represent the cutoff distance for the camera render object.
var camera = new THREE.PerspectiveCamera( 75, // Field of view window.innerWidth/window.innerHeight, // Aspect ratio 0.1, // Near clipping pane 1000 // Far clipping pane);// Reposition the cameracamera.position.set(5,5,0);// Point the camera at a given coordinatecamera.lookAt(new THREE.Vector3(0,0,0));
-Add camera, field of view, aspect ratio and cutoff distance
The final critical part is the renderer itself, which holds a rendering from a given camera perspective scene. Three.js offers a variety of renderers to choose from, but I decided to use the standard WebGL renderer in this exercise.
var renderer = new THREE.WebGLRenderer({ antialias: true });// Size should be the same as the windowrenderer.setSize( window.innerWidth, window.innerHeight );// Set a near white clear color (default is black)renderer.setClearColor( 0xeeeeee );// Append to the documentdocument.body.appendChild( renderer.domElement );// Render the scene/camera combinationrenderer.render(scene, camera);
-Add renderer
This example also includes some basic geometric structures-here is a flat plane-we can see some features being rendered in depth form. Without it, we could only see the empty screen. I will briefly describe the geometry (geometry), materials (material) and meshes (mesh).
// A mesh is created from the geometry and material, then added to the scenevar plane = new THREE.Mesh( new THREE.PlaneGeometry( 5, 5, 5, 5 ), new THREE.MeshBasicMaterial( { color: 0x222222, wireframe: true } ));plane.rotateX(Math.PI/2);scene.add( plane );
-Add a flat flat surface
A little tips on controlling the camera
You may have realized that I used an external module in this example. This is one of the many available modules that can be found in Three.js's GitHub repo.
In this case is the orbital control,
It allows us to capture the mouse events on the canvas element to reposition the camera around the scene.
var controls = new THREE.OrbitControls( camera, renderer.domElement );controls.addEventListener( ‘change‘, function() { renderer.render(scene, camera); } );
-Achieve track control
In the Codepen example, track control is checked from actions, clicks, and drag-and-drop or scrolling of the mouse wheel. In this example, because we didn't set the action loop (once I started decorating my Christmas tree, I introduced the action Loop), we also needed to re-render the scene when the control was updated.
Preparing for rendering
Well, the previous example may look a little silly now, but you can't build a better house or Christmas tree without the hardware foundation.
It's time to add something to our scene, and now there are three things we need to explore: geometries,materials, and meshes.
Code Link Step Two
Contributor Matt Agar (@agar)
From Codepen.
-Jingle bells ringing. Yes, they're going to ring.
Whether it's a click or a drag, just try it.
Use a planar shadow to add some simple polygons
First we need some Geometry. It can be any cubic shape that contains points and lines.
Three.js simplifies a series of achievable building base polygon operations. There are a number of file loaders suitable for 3D format. You can also choose to create your own geometric structure by specifying vertices and surfaces.
Now, we'll start with a basic eight-faceted body.
`var geometry = new THREE.OctahedronGeometry(10,1);`
-Add geometry
materials depicts the appearance of an object. Their definition is not affected by the renderer (in most cases), so you don't have to rewrite it when you decide to use a different renderer.
This is a variety of materials that can be implemented, and all materials use an object containing various properties that are applied to these materials.
The following example implements a flat shaded material, which shows our polygon objects, rather than the intention to smooth them.
var material = new THREE.MeshStandardMaterial( { color: 0xff0051, shading: THREE.FlatShading, // default is THREE.SmoothShading metalness: 0, roughness: 1} );
-Use materials to determine the texture of an object
The third one we need is mesh(GRID). A mesh is an object that gets a multipatch and applies material to it, and we can insert the mesh into our scene and move it freely.
Here's how to merge geometry and material and put in a mesh and add it to the scene. It should be noted that after the mesh is added to the scene, we are free to reposition or rotate it.
var shapeOne = new THREE.Mesh(geometry, material);shapeOne.position.y += 10;scene.add(shapeOne);
-merge geometry and material into a mesh and add mesh to the scene
Add Light
Once we have objects in the scene, we need to illuminate them. To achieve this, we add two different types of light: ambient light and Point light.
The color of the ambient light is applied globally to all objects in the scene.
var ambientLight = new THREE.AmbientLight( 0xffffff, 0.2 );scene.add( ambientLight );
-Add ambient light to the scene
Point Light creates light in a particular position in the scene. Light flashes in any direction, presumably similar to the effect of a light bulb.
var pointLight = new THREE.PointLight( 0xffffff, 1 );pointLight.position.set( 25, 50, 25 );scene.add( pointLight );
-Add point light to the scene
If these do not meet your needs, there are other types of light that can be selected, including directional and spotted light. Check out the Three.js light Manual for more information.
Create and receive shadows
Shadows are not used by default, but are useful for creating visual depths-so we need to enable them on the renderer.
renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;
-Enable shadows in the renderer
The next step is to specify which rays can form a shadow and how much shadow range to render.
pointLight.castShadow = true;pointLight.shadow.mapSize.width = 1024;pointLight.shadow.mapSize.height = 1024;
-Enable light. Accordingly, Shadows also appear
Finally, we specify which meshes should receive shadows. It is necessary to indicate that any grid can produce and receive shadows without relying on the scene.
shapeOne.castShadow = true;shapeOne.receiveShadow = true;
-Use shadows to highlight mesh
In this scenario, we used a special shadow material. It allows a mesh to show only shadows, not the object itself.
var shadowMaterial = new THREE.ShadowMaterial( { color: 0xeeeeee } );shadowMaterial.opacity = 0.5;
-Achieve shadow Effect
Building complex objects with simple features
Some of the simple examples we've done so far are good, but it's easier if we can implement element multiplexing.
Code Link Step Three
Code contributor (@agar)
From Codepen.
-To be sure, these flattened polygons become smaller.
Click and drag in the Codepen to get a clearer effect.
By merging and layering polygon objects, we can begin to create more complex shapes.
The following action expands the Three.group object to create a complex shape in the constructor.
var decoration = function () {//Run the Group constructor with the given arguments three. Group.apply (this, arguments); A random color assignment var colors = [' #ff0051 ', ' #f56762 ', ' #a53c6c ', ' #f19fa0 ', ' #72bdbf ', ' #47689b ']; The main bauble is a octahedron var bauble = new three. Mesh (Addnoise (new three. Octahedrongeometry (12,1), 2), new three. Meshstandardmaterial ({Color:colors[math.floor (Math.random () *colors.length)], Shading:three. Flatshading, metalness:0, roughness:1}); Bauble.castshadow = true; Bauble.receiveshadow = true; Bauble.rotatez (Math.random () *math.pi*2); Bauble.rotatey (Math.random () *math.pi*2); This.add (bauble); A cylinder to represent the top attachment var shapeone = new three. Mesh (Addnoise (new three. Cylindergeometry (4, 6, 6, 1), 0.5), new three. Meshstandardmaterial ({color:0xf8db08, shading:three. Flatshading , metalness:0, roughness:1})); SHAPEONE.POSITION.Y + = 8; Shapeone.castshadow = true; Shapeone.receiveshadow = true; This.add (Shapeone);};D Ecoration.prototype = Object.create (three. Group.prototype);D ecoration.prototype.constructor = decoration;
-Create complex shapes in the constructor
We can now reuse the resulting polygons to add multiple distances to our scene, making the trees more realistic with less effort than creating each element individually.
var decoration = new Decoration();decoration.position.y += 10;scene.add(decoration);
-Decorative Trunks
Another suggestion is to add a random element to the created object.
Move vertices within the geometry of an object to add a randomly organized element to reduce the complexity of the shape. Without these minor flaws, the objects made will feel a little synthetic. I used an auxiliary function to randomly add noise to the vertices of the geometry.
function addNoise(geometry, noiseX, noiseY, noiseZ) { var noiseX = noiseX || 2; var noiseY = noiseY || noiseX; var noiseZ = noiseZ || noiseY; for(var i = 0; i < geometry.vertices.length; i++){ var v = geometry.vertices[i]; v.x += -noiseX / 2 + Math.random() * noiseX; v.y += -noiseY / 2 + Math.random() * noiseY; v.z += -noiseZ / 2 + Math.random() * noiseZ; } return geometry;}
-Add noise to make the object more realistic
Implement actions
So far we've only implemented a separate render call for Webglrender. In order to add some action to our scene, we need to make some updates.
Code Link Fourth Step
Code contributor (@agar)
From Codepen.
-Observe the slow rotation of the multi-body hypnotic type
Render Loops
To make the browser adapt to our update speed, we are using the Browser Action Request framework API to invoke a new render function.
requestAnimationFrame(render);function render() { // Update camera position based on the controls controls.update(); // Re-render the scene renderer.render(scene, camera); // Loop requestAnimationFrame(render);}
-Create a render loop using the motion request framework
Timeout update element
Now I'll make some changes to the complex object, initializing a random rotation speed for the decorations each time I create a distance.
this.rotationSpeed = Math.random() * 0.02 + 0.005;this.rotationPosition = Math.random();
-Into the rotation
We also set up a new function that can be called to rotate around the Y axis based on the current value value. It is important to note that the speed of rotation is based on the frame rate obtained by the browser, but fortunately for this simple example. You will certainly use mathematical functions for handling this process.
Decoration.prototype.updatePosition = function() { this.rotationPosition += this.rotationSpeed; this.rotation.y = (Math.sin(this.rotationPosition));};
-Observe the rotation of decorative objects
With the definition of an update function, each time we run we can recalculate the location of each element being created by updating the render loop.
function render() { // Update camera position based on the controls controls.update(); // Loop through items in the scene and update their position for(var d = 0; d < decorations.length; d++) { decorations[d].updatePosition(); } // Re-render the scene renderer.render(scene, camera); // Loop requestAnimationFrame(render);}
-Recalculate element position
Combine some of the above examples
Code Link Fifth Step
Code contributor (@agar)
From Codepen.
-3d Christmas tree: Fully molded, beautifully decorated
The final product finally came out. Using only the basic functionality, we have built an interactive 3D Christmas tree and built a planar two-dimensional scene.
But this is just the beginning of using WebGL. As this technology develops rapidly, there are many resources to choose from, as well as tutorials that will guide you correctly. Here are the resource links:
The Github repo for three.js, full of examples and endless learning opportunities.
Assorted built-in helpers for cameras, lights, axes etc.
Datgui:create an interface The can use to modify variables.
STATS.JS:A Handy JavaScript Performance Monitor (for framerate).
An excellent and very detailed tutorial in creating a three.js mini game, the Aviator, from the very talented guys at Codr Ops.
Plus heaps of great low poly examples on Codepen from Karim Maaloul.
What are you waiting for? Try WebGL and Three.js, and start creating your own 3D effects. If you have done something interesting, please let me know. I'd love to see it.
Share
Facebook
Twitter
Linkedin
Google Plus
About the author
With over 15 years of engineering experience, Matt is one of the founding members of August, and has united the world's best front and back developers. As a problem-solving person who can adapt to any situation, Matt looks at the technical aspects of the project from a practical perspective and a general direction. When he is not solving the problem, he must be building a fictional animal kingdom and exploring the outdoors with his young family.
Contact information
Linkedin
This article is reproduced from: Zhongcheng translation
Translator: Vicsusi
Links: http://www.zcfy.cc/article/4705
Original: Https://www.august.com.au/blog/animating-scenes-with-webgl-three-js
Animating scenes with WebGL + three.js