“This is the second day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.

Disclaimer: This article is only used for personal study, research and appreciation, please do not modify, illegally spread, reprint, publish, commercial use, and other profit behavior.

background

When I visited the SketchFab website, I saw many examples of 2d plane to 3D model, so I copied their examples and used three. js + React technology stack to transform 2D cartoon pictures into 3D visual effects. The content of this paper mainly includes: THREE Group level model, MeshPhongMaterial high-light mesh material, sine and cosine function to create model movement trajectory, etc.

The effect

The realization effect is shown in 👇 below: The page is mainly composed of background picture, cartoon picture main body and 💥 Boom explosion background picture. Press and hold the left mouse button to move the model to obtain different views, so that the picture has 3D depth of field effect visually.

Adaptation:

  • 💻PC
  • 📱The mobile terminal

👀 Online preview: dragonir.github. IO /3d/#/comic

implementation

The realization of this article is relatively simple, and MY previous several articles are basically the same, the process is relatively simple, mainly the material preparation process is more complex. Let’s look at the implementation.

Material production

Prepare an image you like as the original image of the material. The content of the image should be divided into multiple layers to achieve the 3D depth of field effect. In this example, a cartoon image is used, which can be divided into multiple layers.

Open the image in Photoshop, create several layers according to the number of layers you need, copy the map onto each layer, edit each layer according to the depth of field level of the layer, use the Magic wand tool and lasso tool to remove the excess, and export each layer individually as a material. I divided it into 👆, the above 7 layers, plus a border, a total of 8 layers.

Resources to introduce

OrbitControls is used for lens track control and TWEEN for lens TWEEN animation.

import React from 'react';
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
Copy the code

Scene initialization

Initialize render container, scene, camera, light source. The initial camera position is set to left-of-center (-12, 0, 0) so that TWEEN can be used later for the flip animation.

/ / the scene
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
// Add a background image
scene.background = new THREE.TextureLoader().load(background);
/ / camera
camera = new THREE.PerspectiveCamera(60.window.innerWidth / window.innerHeight, 0.1.1000);
camera.position.set(-12.0.0);
camera.lookAt(new THREE.Vector3(0.0.0));
/ / direct light
light = new THREE.DirectionalLight(0xffffff.1);
light.intensity = 2.;
light.position.set(10.10.30);
light.castShadow = true;
light.shadow.mapSize.width = 512 * 12;
light.shadow.mapSize.height = 512 * 12;
light.shadow.camera.top = 100;
light.shadow.camera.bottom = - 50;
light.shadow.camera.left = - 50;
light.shadow.camera.right = 100;
scene.add(light);
/ / the ambient light
ambientLight = new THREE.AmbientLight(0xdddddd);
scene.add(ambientLight);
Copy the code

Create a comic body

First create a Group to add the layer grid, then iterate over the layer background image array, and create a mesh for each face in the loop body using the flat cube PlaneGeometry and the material MeshPhysicalMaterial. Set the same x and Y values and different Z values for each grid position to create a depth of field effect. Finally, add the Group to the Scene.

var layerGroup = new THREE.Group();
let aspect = 18;
for (let i=0; i<layers.length; i++) {
  let mesh = new THREE.Mesh(new THREE.PlaneGeometry(10.41.16), new THREE.MeshPhysicalMaterial({
    map: new THREE.TextureLoader().load(layers[i]),
    transparent: true.side: THREE.DoubleSide
  }));
  mesh.position.set(0.0, i);
  mesh.scale.set(1 - (i / aspect), 1 - (i / aspect), 1 - (i / aspect));
  layerGroup.add(mesh);
  / / text
  if (i === 5) {
    mesh.material.metalness = 6.;
    mesh.material.emissive = new THREE.Color(0x55cfff);
    mesh.material.emissiveIntensity = 1.6;
    mesh.material.opacity = 9.;
  }
  / / dialogue box
  if (i === 6) {
    mesh.scale.set(1.5.1.5.1.5);
    animateLayer = mesh;
  }
}
layerGroup.scale.set(1.2.1.2.1.2);
Copy the code

At this point, the effect is as follows:

💡THREE.Group hierarchy model

Grids with the same body can be grouped together to improve operation efficiency. The base class of the three. js hierarchy model Group is Object3D, which is the base class of most objects in Three.js and provides a series of attributes and methods to manipulate objects in three-dimensional space. If you can combine objects with the.add(object) method, this method adds objects as child objects.

However, it is better to use Group as the parent object because Group is more semantic than Object3D. You can use Group as the parent object of points, lines, grids, and so on to build a hierarchical model.

Create Boom Background

In order to enhance the visual effect, I added a graphic plane of 💥 Boom explosion as the background. When moving with the mouse, as the light changes, you can see that the pattern has a metallic gradient effect. This effect is achieved mainly through the specular and Shininess properties of the specular material MeshPhongMaterial.

const boom = new THREE.Mesh(new THREE.PlaneGeometry(36.76.27.05), new THREE.MeshPhongMaterial({
  map: new THREE.TextureLoader().load(boomImage),
  transparent: true.shininess: 160.specular: new THREE.Color(0xff6d00),
  opacity: 7.
}));
boom.scale.set(8..8..8.);
boom.position.set(0.0, -3);
layerGroup.add(boom)
scene.add(layerGroup);
Copy the code

Effect after addition:

💡MeshPhongMaterial High light mesh material

MeshPhongMaterial is a material used for glossy surfaces with specular highlights. The material uses a non-physical Blinn-Phong model to calculate reflectivity. Unlike the Lambertian model used in MeshLambertMaterial, this material can simulate glossy surfaces with specular highlights, such as painted wood.

Constructor:

MeshPhongMaterial(parameters: Object)
Copy the code

Parameters: Optional, an object used to define the appearance of a material, with one or more properties. Any properties of a Material can be passed in from here (including any properties inherited from Material).

Special attributes:

  • .emissive[Color]: The radiant color of the material, which is essentially the inherent color unaffected by other illuminations. The default isblack.
  • .emissiveMap[Texture]: Set the glow map. The default value isnull. Radiation map color is adjusted by radiation color and intensity.
  • .emissiveIntensity[Float]: Radiation intensity. Adjust the glow color. The default is1.
  • .envMap[TextureCube]: Environment map. The default value isnull.
  • .isMeshPhongMaterial[Boolean]: checks whether this class or derived class isPhongMesh material. The default value istrue.
  • .lightMap[Texture]: Light map. The default value isnull.
  • .lightMapIntensity[Float]: Intensity of baking light. The default value is1.
  • .reflectivity[Float]: The degree to which the environment map affects the surface. The default value is1, the effective range is between0 (no reflection)1 (Complete reflection)In between.
  • .refractionRatio[Float]: The refractive index of air divided by the refractive index of material. Refractive index should not exceed1. The default value is0.98.
  • .shininess[Float]:.specularThe degree of highlighting, the higher the value, the brighter it is. The default value is30.
  • .skinning[Boolean]: Whether the material is skinned. The default value isfalse.
  • .specular[Color]: Highlights color of the material. The default value is0x111111The color of theColor. This defines the gloss of the material and the color of the sheen.
  • .specularMap[Texture]Specular reflection map values affect the degree to which specular highlights and ambient maps affect the surface. The default value isnull.

📌 calculates shading using the Phong shading model, which calculates the shadow of each pixel, and gives more accurate results than the Gouraud model used by MeshLambertMaterial, but at the cost of some performance.

Camera control, zoom adaptation, animation

Camera tween animation, camera switch to correct position.

Animations.animateCamera(camera, controls, { x: 0.y: 0.z: 20 }, { x: 0.y: 0.z: 0 }, 3600.() = >{});Copy the code

Lens control, in this example, shows the Angle of model translation and horizontal and vertical rotation to achieve the best preview effect.

controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0.0.0);
controls.enableDamping = true;
controls.enablePan = false;
// Vertical rotation Angle limit
controls.minPolarAngle = 1.2;
controls.maxPolarAngle = 1.8;
// Horizontal rotation Angle limit
controls.minAzimuthAngle = -6.;
controls.maxAzimuthAngle = 6.;
Copy the code

Screen zoom adaptation.

window.addEventListener('resize'.() = > {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
Copy the code

For the session block diagram layer grid, I animate it to move left and right on a smooth curve, mainly by modifying its position on the X and y axes.

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  controls && controls.update();
  TWEEN && TWEEN.update();
  // The dialog box swings animation
  step += 0.01;
  animateLayer.position.x = 2.4 + Math.cos(step);
  animateLayer.position.y = 4. + Math.abs(Math.sin(step));
}
Copy the code

💡The sine and cosine function creates the trajectory of the model movement

Using the step variable and with the help of the functions math.cos () and math.sin (), create a smooth trajectory. Step += 0.01 defines the bouncing speed of the ball.

At this point, the full implementation of this example is described. If you are interested, you can try to transform your favorite images into 3D views. Come on, how cool is it to use three.js to show pictures like this? 😂

🔗 Full code: github.com/dragonir/3d…

conclusion

This article mainly contains new knowledge:

  • THREE.GroupThe hierarchy model
  • MeshPhongMaterialHighlights mesh material
  • Sine cosine functionCreate model movement trajectories

To learn more about scene initialization, lighting, shadows, base geometry, meshes, materials, and more about three.js, read my previous articles. Please indicate the original address and author. If you think the article is helpful to you, don’t forget a key three link oh 👍.

The appendix

  • [1].three.js to achieve the 2022 Winter Olympics theme 3D interesting page 🐼
  • [2]. 1000 powder! Create an exclusive 3D medal using three.js 🥇
  • [3].three.js to achieve the Year of the Tiger Spring Festival 3D creative page
  • [4].three.js to implement the 3D dynamic Logo of facebook metasomes
  • [5].three.js to implement 3D panoramic detective game
  • [6].three.js to achieve cool acid style 3D pages
  • [7].3DX model conversion to Blender supported format