Canvas 2D is familiar to everyone, but THE 3D world is much cooler. Let’s start with three.js directly. Let’s start at zero and explore the 3D world
1. Basic concepts
In THREEjs, the necessary elements to render a 3D world are the scene, camera, and renderer. After rendering a 3D world, you can add various objects, lights, etc to it to create a 3D world:
Scene: right hand coordinate system, all elements are in the scene, equivalent to the “world”, including various material and physical changes
// Create a scene
const scene = new THREE.Scene();
Copy the code
Camera: the camera is equivalent to the human eye. Only with a camera can you see all objects and light sources in the scene. Orthogonal camera and perspective camera are commonly used
An orthogonal camera is a rectangular viewable area in which objects are visible and rendered to the same size regardless of distance or proximity to the camera. General application scenarios are 2.5D games such as Jump jump, mechanical models
// Create an orthogonal camera
const camera = new THREE.OrthographicCamera(
-window.innerWidth / 200.window.innerWidth /200 ,
window.innerHeight/ 200,
-window.innerHeight/ 200.1.1000
);
Copy the code
We can see the effect of the figure above. One cube has gone far but remains the same size. In addition, it can be seen that a cube in the corner has been partially truncated, because the orthogonal camera only shows the scene in a space, so there will be truncation effect.
Perspective cameras are the most common type of camera that simulate the vision of the human eye, large near and small (perspective). Fov stands for perspective, and the bigger the Fov, the bigger your eyes open, and the farther away you are, the more you see. If you need to simulate reality, you use this camera
// Create perspective camera
const camera = new THREE.PerspectiveCamera(
90.window.innerWidth / window.innerHeight,
1.10000
);
Copy the code
Near big far small effect came out, more in line with reality
The renderer
Finally, we need to render everything onto the page. We need a renderer:
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); / / canvas size
document.body.appendChild(renderer.domElement);
Copy the code
2. Add content to the screen
It does draw the 3D world, but it doesn’t have anything. In three.js, we need to add a light source and mesh
mesh
A mesh is a mesh. In a computer, the 3D world is made up of points, innumerable surfaces spliced together into objects of various shapes. This model is called a grid model. A line is made up of two points, a surface is made up of three points, and an object is made up of multiple surfaces with three points:
The mesh is composed of geometry and material
geometry
const geometry = new THREE.BoxBufferGeometry( 1.1.1 );
Copy the code
When created, it generally defines the basic data needed to render a 3D object: Face, Vertex, etc. THREE. XxxGeometry refers to the inherent geometry of the frame, which requires different parameters, such as width, height, RADIUS, depth, segment, detail, Angle and other attributes
More Geometry related apis
What is the difference between BufferGeometry and Geometry? They are all the same in terms of implementation, but BufferGeometry has more vertex attributes and better performance. For developers, Geometry object attributes less experience better. When THREE parse the Geometry object, if it is Geometry, it will convert the object into ufferGeometry object, and then proceed to the next rendering
material
const material = new THREE.MeshLambertMaterial();
Copy the code
Whether an object has lens face feeling, bright dark, color, transparent, whether glance etc. property, depend on what material to use. THREE. XxxMaterial refers to the material that comes with the frame, and parameters required by different materials are also different
More Material related apis
With Geometry and Material, we can create a mesh and append it to the scene:
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Copy the code
The light source
If a 3D world needs to be more realistic, it needs light. There are many kinds of light, common ones are parallel light (Figure 2), point light (Figure 3), ambient light (ambient light fills all geometric surfaces), and spot light (Figure 1).
Among them, only parallel light, point light source can produce shadow. And some material is affected by illuminant, do not have light is black. And some materials are not affected by light. The creation of a light source, such as direct light:
const light = new THREE.DirectionalLight(0xffffff.0.9)
Copy the code
XxxLight refers to the built-in light source constructor of the frame. Generally, the parameters required for instantiation are color, Intensity, distance and other configurations. And, of course, a 3D world is not made of light, so light can be superimposed, and the resulting superimposed on objects.
Also, the shadow of an object is not free, it requires some support for shadow light plus developer configuration:
// Light makes shadows
light.castShadow = true;
// The ground accepts shadows
ground.receiveShadow = true;
// Objects create shadows
mesh.castShadow = true;
Copy the code
More light source related apis
More shadow related apis
3. Debug tools
Track controller
OrbitControls are not a constructor.OrbitControls are not a constructor.OrbitControls are not a constructor. The first line to add a window: Windows. THREE. OrbitControls =…
The way to use it is to new a controller, listen for changes, and trigger Render
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
controls.minDistance = 1;
controls.maxDistance = 2000;
controls.enablePan = false;
Copy the code
Performance monitoring
The source code. You can copy it and hang it on the window
Most of the official examples use a stat plugin that displays a performance curve in the upper left corner for debugging. Usage:
const stat = new Stats();
document.body.appendChild(stat.dom);
// Modify the render function
function render() {
renderer.render(scene, camera);
stat.update();
}
Copy the code
4. let’s coding
First get the scene, camera, renderer out and then add a red ball
function init() {
const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
/ / the scene
const scene = new THREE.Scene();
/ / camera
const camera = new THREE.PerspectiveCamera(
90.window.innerWidth / window.innerHeight,
0.1.100
);
camera.position.set(10.0.0);
// Track controller
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", render);
controls.minDistance = 1;
controls.maxDistance = 200;
controls.enablePan = false;
// Add a new red ball
const geometry = new THREE.SphereGeometry(1.10.10);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Coordinate axis auxiliary lines
scene.add(new THREE.AxisHelper(1000));
controls.update(); // The controller needs to
controls.target.copy(mesh.position);
function render() {
renderer.render(scene, camera);
}
function r() {
render();
requestAnimationFrame(r)
}
r()
}
init();
Copy the code
At this point, you can see that there is a sphere at the origin. In fact, a geometry texture can use images, even video, this can not double click to open the HTML, you need to open a local server. Let’s modify the mesh:
function addImg(url, scene, n = 1) {
const texture = THREE.ImageUtils.loadTexture(url);
const material = new THREE.MeshBasicMaterial({ map: texture });
const geometry = new THREE.SphereGeometry(1.10.10);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
return mesh;
}
// const geometry = new THREE.SphereGeometry(1, 10, 10);
// const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// const mesh = new THREE.Mesh(geometry, material);
// Go to kukuai to find a map
const mesh = addImg("https://qhyxpicoss.kujiale.com/r/2019/07/01/L3D137S8ENDIADDWAYUI5L7GLUF3P3WS888_3000x4000.jpg?x-oss-process=image/resiz e,m_fill,w_1600,h_920/format,webp", scene, 1);
scene.add(mesh);
Copy the code
The origin shows a map as the texture of the ball
Basically ok, how to achieve a panoramic house? Now that we have everything we need to do, the last things we need to do are: place the camera in the center of the sphere, set the orbit controller to Max and min to 1 and 2, and render the inner surface of the mesh
/ / adjust the Max
controls.minDistance = 1;
// controls.maxDistance = 200;
controls.maxDistance = 2;
// Resize the ball
// const geometry = new THREE.SphereGeometry(1, 10, 10);
const geometry = new THREE.SphereGeometry(50.256.256);
// Put the camera in the center of the sphere
// camera.position.set(10, 0, 0);
camera.position.set(0.3.0.0);
// Render both sides of the sphere
const material = new THREE.MeshLambertMaterial({ map: texture });
material.side = THREE.DoubleSide;
Copy the code
A panoramic view of the house will appear, then just drag to adjust the Angle. Introduction is a general planar graph, so there is a bit of a problem with the beginning and end of the graph.
This is just an idea to achieve, there are many methods to achieve, such as column, cube, the picture may be a fan-shaped panorama may also be a plurality of pictures pieced together. The details are tailored to the business
The entire code is as follows, with the introduction of three.js and OrbitControl
All the code
function init() { const renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const scene = new THREE.Scene(); Const camera = new THREE.PerspectiveCamera(90, window.innerwidth/window.innerheight, 0.1, 100); // camera.position.set(10, 0, 0); Camera. The position. The set (0.3, 0, 0); const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.addEventListener("change", render);
controls.minDistance = 1;
// controls.maxDistance = 200;
controls.maxDistance = 2;
controls.enablePan = false;
// const geometry = new THREE.SphereGeometry(1, 10, 10);
// const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// const mesh = new THREE.Mesh(geometry, material);
const mesh = addImg("https://qhyxpicoss.kujiale.com/r/2019/07/01/L3D137S8ENDIADDWAYUI5L7GLUF3P3WS888_3000x4000.jpg?x-oss-process=image/resiz e,m_fill,w_1600,h_920/format,webp", scene, 1);
scene.add(mesh);
controls.update();
controls.target.copy(mesh.position);
function render() {
renderer.render(scene, camera);
}
function r() {
render();
requestAnimationFrame(r)
}
scene.add(new THREE.AxisHelper(1000));
r()
}
function addImg(url, scene, n = 1) {
const texture = THREE.ImageUtils.loadTexture(url);
const material = new THREE.MeshBasicMaterial({ map: texture });
// const geometry = new THREE.SphereGeometry(1, 10, 10);
const geometry = new THREE.SphereGeometry(50, 256, 256);
const mesh = new THREE.Mesh(geometry, material);
material.side = THREE.DoubleSide;
scene.add(mesh);
return mesh;
}
init();
Copy the code
Pay attention to the public account “Different front-end”, learn front-end from a different perspective, grow fast, play with the latest technology, explore all kinds of black technology