当前位置:网站首页>what the fuck! If you can't grab it, write it yourself. Use code to realize a Bing Dwen Dwen. It's so beautiful ~!
what the fuck! If you can't grab it, write it yourself. Use code to realize a Bing Dwen Dwen. It's so beautiful ~!
2022-06-23 01:55:00 【Java technology stack】
author :dragonir
source :https://segmentfault.com/a/1190000041363089
background
Welcome the Winter Olympics , Together to the future !2022 The Winter Olympics It's about to start , This article USES the Three.js + React Technology stack , Realize winter and Olympic elements , Made a Winter Olympic theme full of fun and commemorative significance 3D page .
The knowledge points involved in this paper mainly include :TorusGeometry Torus 、MeshLambertMaterial Non gloss surface material 、MeshDepthMaterial Depth mesh material 、custromMaterial Custom materials 、Points The particle 、PointsMaterial Point material, etc .
effect
The effect is as follows: The diagram shows , The page is mainly composed of 2022 The mascot of the Winter Olympics Ice mound 、 Olympic rings 、 Dancing flag 、 tree And the effect of snow ️ Other components . Press and hold the left mouse button to move to change the camera position , Get different views .

The online preview :https://dragonir.github.io/3d/#/olympic( Deployed in
GitHub, The loading speed may be a little slow)
Realization
Introduce resources
First, introduce the library and external resources needed to develop the page ,OrbitControls For lens track control 、TWEEN It is used to realize the animation of making up room 、GLTFLoader Used for loading glb or gltf Format 3D Model 、 And some other models 、 Map and other resources .
import React from 'react';import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";import bingdundunModel from './models/bingdundun.glb';// ...page DOM structure
page DOM The structure is very simple , Only rendering 3D Elemental #container Container and display of loading progress .olympic_loading Elements .
<div> <div id="container"></div> {this.state.loadingProcess === 100 ? '' : ( <div className="olympic_loading"> <div className="box">{this.state.loadingProcess} %</div> </div> )}</div>Scene initialization
Initialize render container 、 scene 、 The camera . Detailed knowledge points about this part , You can refer to my previous articles , It will not be repeated in this article .
container = document.getElementById('container');renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;container.appendChild(renderer.domElement);scene = new THREE.Scene();scene.background = new THREE.TextureLoader().load(skyTexture);camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.set(0, 30, 100);camera.lookAt(new THREE.Vector3(0, 0, 0));Add light source
In this example, two kinds of light sources are mainly added :DirectionalLight Used to produce shadows , Adjust page brightness 、AmbientLight Used to render the environment atmosphere .
// Direct light const light = new THREE.DirectionalLight(0xffffff, 1);light.intensity = 1;light.position.set(16, 16, 8);light.castShadow = true;light.shadow.mapSize.width = 512 * 12;light.shadow.mapSize.height = 512 * 12;light.shadow.camera.top = 40;light.shadow.camera.bottom = -40;light.shadow.camera.left = -40;light.shadow.camera.right = 40;scene.add(light);// The ambient light const ambientLight = new THREE.AmbientLight(0xcfffff);ambientLight.intensity = 1;scene.add(ambientLight);Loading schedule management
Use THREE.LoadingManager Manage page model loading progress , Execute some methods related to the loading progress in its callback function . The page loading progress in this example is onProgress Done in , When the page loading progress is 100% when , perform TWEEN Camera room animation .
const manager = new THREE.LoadingManager();manager.onStart = (url, loaded, total) => {};manager.onLoad = () => { console.log('Loading complete!')};manager.onProgress = (url, loaded, total) => { if (Math.floor(loaded / total * 100) === 100) { this.setState({ loadingProcess: Math.floor(loaded / total * 100) }); // Camera room animation Animations.animateCamera(camera, controls, { x: 0, y: -1, z: 20 }, { x: 0, y: 0, z: 0 }, 3600, () => {}); } else { this.setState({ loadingProcess: Math.floor(loaded / total * 100) }); }};Create the ground
In this example, the uneven ground is used Blender Build the model , Then export glb Format load created . Of course, you can just use Three.js A similar effect can be achieved with its own plane mesh and bump map . Use Blender The advantage of self built model is that it can freely and visually adjust the fluctuation effect of the ground .
var loader = new THREE.GLTFLoader(manager);loader.load(landModel, function (mesh) { mesh.scene.traverse(function (child) { if (child.isMesh) { child.material.metalness = .1; child.material.roughness = .8; // ground if (child.name === 'Mesh_2') { child.material.metalness = .5; child.receiveShadow = true; } }); mesh.scene.rotation.y = Math.PI / 4; mesh.scene.position.set(15, -20, 0); mesh.scene.scale.set(.9, .9, .9); land = mesh.scene; scene.add(land);});
Bing dwen dwen Winter Olympic mascot
Now add the lovely Winter Olympic mascot, panda ice pier. , Bing dwen dwen is also used. glb Format model loaded . Its original model comes from here , Free from this website now after the model , The original model is using 3D max I found that it can not be directly used in web pages , Need to be in Blender Convert model format in , You also need to adjust the map normals of the model , To restore the render effect .
The original model :

Map of ice pier pier :

convert to Blender Supported models , And in Blender Adjust model map normals 、 And add a map :

export glb Format :

Observe carefully Ice mound You can find , It has a floor outside Transparent plastic or glass shell , This effect can be achieved by modifying the transparency of the model 、 Metallicity 、 Realization of material parameters such as roughness , Finally, you can render such as banner chart The effect shown , The details are shown in the following code .
loader.load(bingdundunModel, mesh => { mesh.scene.traverse(child => { if (child.isMesh) { // Inside if (child.name === 'oldtiger001') { child.material.metalness = .5 child.material.roughness = .8 } // Translucent shell if (child.name === 'oldtiger002') { child.material.transparent = true; child.material.opacity = .5 child.material.metalness = .2 child.material.roughness = 0 child.material.refractionRatio = 1 child.castShadow = true; } } }); mesh.scene.rotation.y = Math.PI / 24; mesh.scene.position.set(-8, -12, 0); mesh.scene.scale.set(24, 24, 24); scene.add(mesh.scene);});Create the Olympic rings
The Olympic rings consist of a circular torus with a basic geometric model TorusGeometry To achieve , Create five torus , And adjust their material color and position to form Blue black red yellow green Sequential five ring structure . The five rings are made of MeshLambertMaterial.
const fiveCycles = [ { key: 'cycle_0', color: 0x0885c2, position: { x: -250, y: 0, z: 0 }}, { key: 'cycle_1', color: 0x000000, position: { x: -10, y: 0, z: 5 }}, { key: 'cycle_2', color: 0xed334e, position: { x: 230, y: 0, z: 0 }}, { key: 'cycle_3', color: 0xfbb132, position: { x: -125, y: -100, z: -5 }}, { key: 'cycle_4', color: 0x1c8b3c, position: { x: 115, y: -100, z: 10 }}];fiveCycles.map(item => { let cycleMesh = new THREE.Mesh(new THREE.TorusGeometry(100, 10, 10, 50), new THREE.MeshLambertMaterial({ color: new THREE.Color(item.color), side: THREE.DoubleSide })); cycleMesh.castShadow = true; cycleMesh.position.set(item.position.x, item.position.y, item.position.z); meshes.push(cycleMesh); fiveCyclesGroup.add(cycleMesh);});fiveCyclesGroup.scale.set(.036, .036, .036);fiveCyclesGroup.position.set(0, 10, -8);scene.add(fiveCyclesGroup); TorusGeometry Torus
TorusGeometry A class for generating torus geometry .
Constructors :
TorusGeometry(radius: Float, tube: Float, radialSegments: Integer, tubularSegments: Integer, arc: Float)radius: The radius of the ring , From the center of the ring to the pipe ( cross section ) Center of . The default value is1.tube: The radius of the pipe , The default value is0.4.radialSegments: Number of segments of the ring , The default value is8.tubularSegments: The number of segments of the pipe , The default value is6.arc: The central angle of the ring ( The unit is radians ), The default value isMath.PI * 2.
MeshLambertMaterial Non gloss surface material
A material with a non glossy surface , No specular highlights . The material uses non physical based Lambertian Model to calculate reflectivity . This can simulate some surfaces very well ( For example, untreated wood or stone ), But it cannot simulate a glossy surface with specular highlights ( For example, painted wood ).
Constructors :
MeshLambertMaterial(parameters : Object)parameters:( Optional ) The object that defines the appearance of the material , Having one or more properties . Any property of the material can be passed in from here .
Create flag
The flag model is from sketchfab Download the , And a flagpole , Can be in Blender A cylindrical cube is added to the , And adjust the appropriate length, width and height to combine with the flag surface .

Flag map :

The flag surface has been animated , Animation frame playback needs to be performed in the code .
loader.load(flagModel, mesh => { mesh.scene.traverse(child => { if (child.isMesh) { child.castShadow = true; // The flag if (child.name === 'mesh_0001') { child.material.metalness = .1; child.material.roughness = .1; child.material.map = new THREE.TextureLoader().load(flagTexture); } // flagpole if (child.name === ' Cylinder ') { child.material.metalness = .6; child.material.roughness = 0; child.material.refractionRatio = 1; child.material.color = new THREE.Color(0xeeeeee); } } }); mesh.scene.rotation.y = Math.PI / 24; mesh.scene.position.set(2, -7, -1); mesh.scene.scale.set(4, 4, 4); // Animation let meshAnimation = mesh.animations[0]; mixer = new THREE.AnimationMixer(mesh.scene); let animationClip = meshAnimation; let clipAction = mixer.clipAction(animationClip).play(); animationClip = clipAction.getClip(); scene.add(mesh.scene);});Create trees
To enrich the picture , Create a winter atmosphere , So a few pine trees were added As a decoration . It is very important to use a technique when adding pine trees : We know because the tree model is very complex , There are a lot of faces , Too many faces will reduce page performance , Create a Caton . Two are used in this article, as shown in the figure below The two intersecting faces shown are used as the base of the tree , In this case, the tree has only two faces , Using this technique can greatly optimize page performance , And trees It looks like 3D Sensible .

Texture mapping :

To make the tree Transparent only in the transparent part of the map 、 Opaque elsewhere , And you can Produces tree shadows instead of box shadows , You need to add the following to the tree model MeshPhysicalMaterial、MeshDepthMaterial Two materials , Both materials use the same texture map , among MeshDepthMaterial Model added to custromMaterial Attribute .
let treeMaterial = new THREE.MeshPhysicalMaterial({ map: new THREE.TextureLoader().load(treeTexture), transparent: true, side: THREE.DoubleSide, metalness: .2, roughness: .8, depthTest: true, depthWrite: false, skinning: false, fog: false, reflectivity: 0.1, refractionRatio: 0,});let treeCustomDepthMaterial = new THREE.MeshDepthMaterial({ depthPacking: THREE.RGBADepthPacking, map: new THREE.TextureLoader().load(treeTexture), alphaTest: 0.5});loader.load(treeModel, mesh => { mesh.scene.traverse(child =>{ if (child.isMesh) { child.material = treeMaterial; child.custromMaterial = treeCustomDepthMaterial; } }); mesh.scene.position.set(14, -9, 0); mesh.scene.scale.set(16, 16, 16); scene.add(mesh.scene); // Clone the other two trees let tree2 = mesh.scene.clone(); tree2.position.set(10, -8, -15); tree2.scale.set(18, 18, 18); scene.add(tree2) // ...}); The effect can also be achieved from above Banner You can see that in the picture , For a better picture , I canceled the shadow display of the tree .
stay3DFunction development in progress , Some unimportant decoration models can adopt this strategy to optimize .
MeshDepthMaterial Depth mesh material
A material that draws geometry by depth . The depth is based on the near far plane of the camera , White recently , Black farthest .
Constructors :
MeshDepthMaterial(parameters: Object)parameters:( Optional ) The object that defines the appearance of the material , Having one or more properties . Any property of the material can be passed in from here .
Special properties :
.depthPacking[Constant]:depth packingThe coding . The default isBasicDepthPacking..displacementMap[Texture]: Displacement mapping affects the position of mesh vertices , Unlike other maps that affect only the material's lighting and shadows , Shifted vertices can cast shadows , Block other objects , And act as real geometry ..displacementScale[Float]: How much the displacement map affects the mesh ( Black is no displacement , White is the maximum displacement ). If no displacement map is set , This value is not applied . The default value is1..displacementBias[Float]: The offset of the displacement map on the mesh vertices . If no displacement map is set , This value is not applied . The default value is0.
custromMaterial Custom materials
Add to grid custromMaterial Custom material properties , Transparent peripherals can be achieved png Content area shadow of picture map .
Create snowflakes
Create snowflakes ️, You use Particle knowledge .THREE.Points Is a class used to create points , It's also used to batch manage particles . In this example, a 1500 Snowflake particles , The random coordinates defining the three-dimensional space and the horizontal and vertical random moving speeds are set for them .
// Snowflake map let texture = new THREE.TextureLoader().load(snowTexture);let geometry = new THREE.Geometry();let range = 100;let pointsMaterial = new THREE.PointsMaterial({ size: 1, transparent: true, opacity: 0.8, map: texture, // Background fusion blending: THREE.AdditiveBlending, // Depth of field attenuation sizeAttenuation: true, depthTest: false});for (let i = 0; i < 1500; i++) { let vertice = new THREE.Vector3(Math.random() * range - range / 2, Math.random() * range * 1.5, Math.random() * range - range / 2); // Longitudinal velocity vertice.velocityY = 0.1 + Math.random() / 3; // Lateral velocity vertice.velocityX = (Math.random() - 0.5) / 3; // Add to geometry geometry.vertices.push(vertice);}geometry.center();points = new THREE.Points(geometry, pointsMaterial);points.position.y = -30;scene.add(points); Points The particle
Three.js in , rain ️、 snow ️、 cloud ️、 Stars And other common particles in life can be used Points To simulate the implementation .
Constructors :
new THREE.Points(geometry, material);- The constructor can accept two parameters , A geometry and a material , Geometry parameters are used to determine the position coordinates of particles , Material parameters are used to format particles ;
- Can be based on simple geometry objects such as
BoxGeometry、SphereGeometryAnd so on as the parameters of the particle system ; - In general , You need to assign vertices yourself to determine the position of particles .
PointsMaterial Point material
adopt THREE.PointsMaterial You can set the attribute parameters of particles , yes Points Default material used .
Constructors :
PointsMaterial(parameters : Object)parameters:( Optional ) The object that defines the appearance of the material , Having one or more properties . Any property of the material can be passed in from here .
Material properties .blending
The material .blending Attribute mainly controls the superposition mode of texture fusion ,.blending The values of the property include :
THREE.NormalBlending: The default value isTHREE.AdditiveBlending: Additive fusion modeTHREE.SubtractiveBlending: Subtraction fusion modeTHREE.MultiplyBlending: Multiplicative fusion modeTHREE.CustomBlending: Custom fusion mode , And.blendSrc,.blendDstor.blendEquationAttribute combination
Material properties .sizeAttenuation
Is the depth of the particles attenuated by the camera , The default is true( Perspective cameras only ).
Three.js vector
A few dimensional vector has several components , Two dimensional vector Vector2 Yes x and y Two components , Three dimensional vector Vector3 Yes x、y、z The three components , four-dimensional vector Vector4 Yes x、y、z、w Four components .
relevant API:
Vector2: Two dimensional vectorVector3: Three dimensional vectorVector4: four-dimensional vector
Lens control 、 Zoom fit 、 Animation
controls = new OrbitControls(camera, renderer.domElement);controls.target.set(0, 0, 0);controls.enableDamping = true;// Disable translation controls.enablePan = false;// Disable scaling controls.enableZoom = false;// Vertical rotation angle limit controls.minPolarAngle = 1.4;controls.maxPolarAngle = 1.8;// Horizontal rotation angle limit controls.minAzimuthAngle = -.6;controls.maxAzimuthAngle = .6;window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight);}, false);function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); controls && controls.update(); // Flag animation update mixer && mixer.update(new THREE.Clock().getDelta()); // Lens animation TWEEN && TWEEN.update(); // Five ring rotation fiveCyclesGroup && (fiveCyclesGroup.rotation.y += .01); // The vertex needs to be updated after it changes , Otherwise, the raindrop effect cannot be realized points.geometry.verticesNeedUpdate = true; // Snowflake animation update let vertices = points.geometry.vertices; vertices.forEach(function (v) { v.y = v.y - (v.velocityY); v.x = v.x - (v.velocityX); if (v.y <= 0) v.y = 60; if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1; });}
Complete code :https://github.com/dragonir/3d/tree/master/src/containers/Olympic
summary
The new knowledge points mainly included in this paper include :
TorusGeometryTorusMeshLambertMaterialNon gloss surface materialMeshDepthMaterialDepth mesh materialcustromMaterialCustom materialsPointsThe particlePointsMaterialPoint material- Material properties
.blending、.sizeAttenuation Three.jsvector
Space for further optimization :
- Add more interactive features 、 The interface style is further optimized ;
- Mascot adds bone animation to ice pier pier. , And its movement and interaction can be controlled by mouse and keyboard .
Recent hot article recommends :
1.1,000+ Avenue Java Arrangement of interview questions and answers (2022 The latest version )
2. Explode !Java Xie Cheng is coming ...
3.Spring Boot 2.x course , It's too complete !
4.20w Programmer red envelope cover , Get it quickly ...
5.《Java Development Manual ( Song Mountain version )》 The latest release , Download it quickly !
I think it's good , Don't forget to like it + Forward !
边栏推荐
- A blog allows you to understand the use of material design
- 1. Mx6u bare metal program (4) - GPIO module
- Thread local storage understanding
- Data skew analysis of redis slice cluster
- Day260: the number III that appears only once
- Debian10 create users, user groups, switch users
- [cmake command notes]find_ path
- Autumn move script B
- Function part
- Bc113 small leloding alarm clock
猜你喜欢

9. class and object practice and initialization list

Do you know the memory components of MySQL InnoDB?

Binary String

MySQL -- how to access the database of a computer in the same LAN (prenatal education level teaching)

Module 8 job

Browser independent way to detect when image has been loaded

Rebirth -- millimeter wave radar and some things I have to say

Express framework installation and start service

1. Mx6u image burning principle (no specific process)

JS prototype and prototype chain Paramecium can understand
随机推荐
Garbled code of SecureCRT, double lines, double characters, unable to input (personal detection)
Dynamic address book in C language (add, delete, modify, check (duplicate), delete, sort and export)
Rebirth -- C language and the story I have to tell (text)
Arm assembly syntax
SQL programming task04 job - set operation
[learning notes] roll back Mo team
How are pub and sub connected in ros1?
1. Mx6u bare metal program (5) - external interrupt
//1.13 auto increment and auto decrement operators (+ +, --)
How to type Redux actions and Redux reducers in TypeScript?
//1.14 comma operator and comma expression
Primary pointer part
1. Mx6u bare metal program (4) - GPIO module
SQL programming task03 job - more complex query
1. Mx6u bare metal program (1) - Lighting master
Vs Code inadvertently disable error waveform curve
2D prefix and
[hdu] p1466 calculate the number of intersections of straight lines
278. digital combination
Muduo simple usage