This article mainly describes how to use the Three.js + Blender technology stack to realize Meta's cool 3D dynamic logo, including basic model rings, torus knots, pipelines and model generation, model loading, adding animations, adding click events, changing materials, etc. background What is the Metaverse? The term Metaverse comes from Neal Stephenson's The connotation of the metaverse has absorbed the achievements of the information revolution Achieve resultsLet's get to the point and take a look at the implementation effect of the example in this article. Development and Implementation Before development, let’s take a look at Trial 1: THREE.TorusGeometry The basic geometry provided by
Syntax example:
Trial 2: THREE.TorusKnotGeometry
Syntax example:
Trial 3: THREE.TubeGeometry
Code Sample // ... var controls = new function () { //Point coordinates this.deafultpoints = [ [0, 0.4, -0.4], [0.4, 0, 0], [0.4, 0.8, 0.4], [0, 0.4, 0.4], [-0.4, 0, 0], [-0.4, 0.8, -0.4], [0, 0.4, -0.4] ] this.segments = 64; this.radius = 1; this.radiusSegments = 8; this.closed = true; this.points = []; this.newPoints = function () { var points = []; for (var i = 0; i < controls.deafultpoints.length; i++) { var _x = controls.deafultpoints[i][0] * 22; var _y = controls.deafultpoints[i][1] * 22; var _z = controls.deafultpoints[i][2] * 22; points.push(new THREE.Vector3(_x, _y, _z)); } controls.points = points; controls.redraw(); }; this.redraw = function () { redrawGeometryAndUpdateUI(gui, scene, controls, function() { return generatePoints(controls.points, controls.segments, controls.radius, controls.radiusSegments, controls.closed); }); }; }; controls.newPoints(); function generatePoints(points, segments, radius, radiusSegments, closed) { if (spGroup) scene.remove(spGroup); spGroup = new THREE.Object3D(); var material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: false }); points.forEach(function (point) { var spGeom = new THREE.SphereGeometry(0.1); var spMesh = new THREE.Mesh(spGeom, material); spMesh.position.copy(point); spGroup.add(spMesh); }); scene.add(spGroup); return new THREE.TubeGeometry(new THREE.CatmullRomCurve3(points), segments, radius, radiusSegments, closed); } // ... Trial 4: Blender + Three.js Although this can be achieved using
Modeling Tutorial When I was browsing Modeling with Blender Use Loading Dependencies <script src="./assets/libs/three.js"></script> <script src="./assets/libs/loaders/FBXLoader.js"></script> <script src="./assets/libs/inflate.min.js"></script> <script src="./assets/libs/OrbitControls.js"></script> <script src="./assets/libs/stats.js"></script> Scene initialization var container, stats, controls, compose, camera, scene, renderer, light, clickableObjects = [], mixer, mixerArr = [], manMixer; var clock = new THREE.Clock(); init(); animate(); function init() { container = document.createElement('div'); document.body.appendChild(container); // Scene scene = new THREE.Scene(); scene.transparent = true; scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000); // Perspective camera: field of view, aspect ratio, near plane, far plane camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 4, 16); camera.lookAt(new THREE.Vector3(0, 0, 0)); // Hemisphere light source: Create a more natural light source for outdoor effects light = new THREE.HemisphereLight(0xefefef); light.position.set(0, 20, 0); scene.add(light); // Directional light light = new THREE.DirectionalLight(0x2d2d2d); light.position.set(0, 20, 10); light.castShadow = true; scene.add(light); // Ambient light var ambientLight = new THREE.AmbientLight(0xffffff, .5); scene.add(ambientLight); // Grid var grid = new THREE.GridHelper(100, 100, 0xffffff, 0xffffff); grid.position.set(0, -10, 0); grid.material.opacity = 0.3; grid.material.transparent = true; scene.add(grid); renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.outputEncoding = THREE.sRGBEncoding; renderer.setSize(window.innerWidth, window.innerHeight); //Set the background color to transparentrenderer.setClearAlpha(0); // Enable shadowrenderer.shadowMap.enabled = true; container.appendChild(renderer.domElement); // Add lens controller controls = new THREE.OrbitControls(camera, renderer.domElement); controls.target.set(0, 0, 0); controls.update(); window.addEventListener('resize', onWindowResize, false); // Initialize performance plugin stats = new Stats(); container.appendChild(stats.dom); } // Screen zoom function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }
Loading Logo Model Use var loader = new THREE.FBXLoader(); loader.load('assets/models/meta.fbx', function (mesh) { mesh.traverse(function (child) { if (child.isMesh) { child.castShadow = true; child.receiveShadow = true; } }); mesh.rotation.y = Math.PI / 2; mesh.position.set(0, 1, 0); mesh.scale.set(0.05, 0.05, 0.05); scene.add(mesh); }); Adding Materials var texLoader = new THREE.TextureLoader(); loader.load('assets/models/meta.fbx', function (mesh) { mesh.traverse(function (child) { if (child.isMesh) { if (child.name === 'Bezier circle') { child.material = new THREE.MeshPhysicalMaterial({ map: texLoader.load("./assets/images/metal.png"), metalness: .2, roughness: 0.1, exposure: 0.4 }); } } }); }) Add animation
loader.load('assets/models/meta.fbx', function (mesh) { mesh.animations.map(item => { mesh.traverse(child => { // Because there are multiple objects in the model, and each has a different animation, this example only adds animation to the Bezier circle mesh if (child.name === 'Bezier circle') { let mixer = new THREE.AnimationMixer(child); mixerArr.push(mixer); let animationClip = item; animationClip.duration = 8; let clipAction = mixer.clipAction(animationClip).play(); animationClip = clipAction.getClip(); } }) }) }); After adding the animation, don't forget to update the animation in function animate() { renderer.render(scene, camera); // Get the time interval between two executions of this method let time = clock.getDelta(); // Update logo animation mixerArr.map(mixer => { mixer && mixer.update(time); }); // Update character animation manMixer && manMixer.update(time); stats.update(); requestAnimationFrame(animate); } Display loading progress <div class="loading" id="loading"> <p class="text">Loading progress<span id="progress">0%</span></p> <div> var loader = new THREE.FBXLoader(); loader.load('assets/models/meta.fbx', mesh => { }, res => { // Loading progress let progress = (res.loaded / res.total * 100).toFixed(0); document.getElementById('progress').innerText = progress; if (progress === 100) { document.getElementById('loading').style.display = 'none'; } }, err => { // Load failed console.log(err) }); Achieve results Click to change the material Listen to the click event of the page and get the current click object through //Declare raycaster and mouse variables var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); function onMouseClick(event) { // Calculate the position of the point required by the raycaster based on the position of the mouse click, with the center of the screen as the origin, and the value range is -1 to 1. mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // Calculate the raycaster based on the position of the mouse point and the current camera matrix raycaster.setFromCamera(mouse, camera); // Get the array collection where the raycaster line intersects with all models let intersects = raycaster.intersectObjects(clickableObjects); if (intersects.length > 0) { console.log(intersects[0].object) let selectedObj = intersects[0].object; selectedObj.material = new THREE.MeshStandardMaterial({ color: `#${Math.random().toString(16).slice(-6)}`, metalness: Math.random(), roughness: Math.random() }) } } window.addEventListener('click', onMouseClick, false); Loading character model The character model loading process is the same as the loader.load('assets/models/man.fbx', function (mesh) { mesh.traverse(function (child) { if (child.isMesh) { child.castShadow = true; child.receiveShadow = true; } }); mesh.rotation.y = Math.PI / 2; mesh.position.set(-14, -8.4, -3); mesh.scale.set(0.085, 0.085, 0.085); scene.add(mesh); manMixer = new THREE.AnimationMixer(mesh); let animationClip = mesh.animations[0]; let clipAction = manMixer.clipAction(animationClip).play(); animationClip = clipAction.getClip(); }, res => { let progress = (res.loaded / res.total * 100).toFixed(0); document.getElementById('progress').innerText = progress + '%'; if (Number(progress) === 100) { document.getElementById('loading').style.display = 'none'; } }, err => { console.log(err) }); The example character models in this article come from mixamo.com, which has hundreds of characters and thousands of actions that can be freely combined and downloaded SummarizeThe main knowledge points involved in this article include:
References[1]. Using three.js to create a cool acid-style 3D page [2]. Understanding materials in ThreeJs [3]. First impression of Three’s Animation [4]. What is the Metaverse? Author: dragonir Article URL: https://www.cnblogs.com/dragonir/p/15574412.html This is the end of this article about how to implement Facebook Metaverse 3D dynamic logo with Three.js. For more related Three.js 3D dynamic logo content, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: CSS to implement QQ browser functions
>>: Summary of Mysql-connector-java driver version issues
Closure implementation of private variables Priva...
Preface Recently, a Java EE web project that has ...
Detailed example of getting the maximum value of ...
According to the coefficient of pi and the radius...
Overview Prometheus is an open source service mon...
How to obtain SQL statements with performance iss...
Mysql slow query explanation The MySQL slow query...
Goal: Create a square whose side length is equal ...
Table of contents Overview Create a type definiti...
The function to be implemented today is the follo...
How to modify the style of the el-select componen...
Since the network requests initiated by native js...
Table of contents step 1. Configure routing rules...
Let's imitate Taobao's function of displa...
JavaScript - Principles Series In daily developme...