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