首页 > 自考资讯 > 自考知识

脸书改名元宇宙,脸书的元宇宙

头条共创 2024-06-27

背景

Facebook最近宣布正式进军Metaverse领域,将母公司更名为Meta。本文主要是用Three.js + Blender 技术栈在Meta 中实现一个很酷的3D 动态标志。这包括基本模型环面、环面扭结、管道和模型生成、加载模型、添加动画、添加单击事件和更改材质。 不挂断。

%20

什么是元宇宙

%20Metaverse一词来自Neil%20%20Stevenson%20%201992年的《雪崩》。本书描述了虚拟世界,一个与现实世界平行的虚拟世界。维基百科对虚拟宇宙的描述如下:基于未来互联网的3D虚拟空间,通过虚拟增强物理现实实现融合和物理持久性,具有链接感知和共享属性。

%20%20元宇宙的意义是吸收信息革命5G/6G、互联网革命Web3.0、人工智能革命、虚拟现实技术革命的成果,包括VR、AR、MR,尤其是游戏。该引擎揭示了构建与传统物理世界并行的全息数字世界的可能性,引发信息科学、量子科学、数学和生命科学以及传统哲学、社会学和科学的相互作用,促进创新。它包括所有数字技术,包括人文系统。就像电影《头号玩家》中的场景一样,人们可以随时随地切换身份,在物理世界和数字世界之间自由移动,在虚拟时空节点组成的虚拟宇宙中生活和学习。当你可以的时候,未来。

%20

实现效果

%20现在我们开始说正事吧。首先我们看一下本文示例的实现。

%20%20在线预览:https://dragonir.github.io/3d-meta-logo%20%20(由于模型较大,加载进度可能较慢,需要耐心等待)

%20

开发实现

%20注意:上面的示例动画显示了试验4。如果您不想看到试错过程(试验1、试验2、试验3),可以直接跳至试验4段落以获取更多信息。实施过程。失败过程中列出了困难。如果您知道解决方案,请随时在评论部分提出您的建议。

%20在开发之前,我们先看一下元标志。您可以看到,这是通过将环对折并扭转而形成的。如果您正在实施一个,请从实施环开始。

%20

试炼一:THREE.TorusGeometry

%20Three.js%20%20提供的基本几何体THREE.TorusGeometry(环)是一个像甜甜圈一样的简单形状。主要参数:

半径:可选。定义环的半径大小。默认值为1。管:可选。定义环的管半径。默认值为0.4。%20radioSegments:可选。定义沿环长度的段数。默认值为8。管状段:可选。定义沿环宽度的线段数。默认值为6。弧线:可选。定义所绘制圆的长度。值范围为0%20到2%20*%20。默认值为2%20*%20(正圆)。语法示例:

THREE.TorusGeometry(radius,%20tube,%20radiusSegments,%20TubulusSegments,%20arc);%20失败:我找不到扭转圆环的方法。

%20%20

试炼二:THREE.TorusKnotGeometry

%20三.TorusKnotGeometry%20%20可用于创建三维环面结。环面结是一种特殊的结,它使管道看起来绕自身旋转多次。主要参数:

半径:可选。设置完整圆的半径。默认值为1。管:可选。设置管道的半径。默认值为0.4。%20radioSegments:可选。指定支管中的段数。段数越多,管段圆越平滑。默认值为8。管状段:可选。指定管段的数量。段数越多,管道就越光滑。默认值为64。%20p:可选。确定几何体绕旋转对称轴旋转的次数。默认值为2。问:可选。确定几何体绕内环旋转的次数。默认值为3。语法示例:

THREE.TorusKnotGeometry(radius,%20tube,%20radiusSegments,%20tubelessSegments,%20p,%20q);%20失败:找不到控制手动扭曲程度的方法。

%20%20

试炼三:THREE.TubeGeometry

%20THREE.TubeGeometry%20%20沿三次样条拉伸管。您可以定义带有一些固定点的路径并使用THREE.TubeGeometry%20%20创建管。主要参数:

路径:此属性使用THREE.SplineCurve3%20对象指定管道遵循的路径。%20Segments:此属性指定用于构造此管道的段数。默认值为64。路径越长,需要指定的段就越多。%20radius:该属性指定管的半径。默认值为1.radiusSegments:此属性指定管道圆周周围的段数。默认值为8,随着添加更多段,管道会显得更圆。%20Closed:如果此属性设置为true,则管道的起点和终点是连接的。默认值为false。代码示例

//.var%20%20control=new%20%20function%20%20()%20{%20//点位置坐标this.defaultpoints=[%20[0,%200.4,%20-0.4],%20[0.4,%200,%200],%20[0.4,%200.8,%200.4],%20[%20this%20%20.segments=64;%20this.radiusSegments=8;%20this.points=[];%20this.newPoints=function%20%20()%20{%20for%20%20(var%20%20i=0;%20i%20%20control.defaultpoints.长度;%20i++)%20{%20var%20%20_x=control.deafultpoints[i]%20[0]%20*%2022;%20var%20%20_y=control.defaultpoints[i][1]%20*%2022;%20var%20%20_z=control.deafultpoints[i][2]%20*%2022;%20_x,%20_y,%20_z));%20}%20control.point=point%20%20;%20this.redraw=function%20%20()%20{%20redrawGeometryAndUpdateUI(gui,%20control,%20return%20%20function())%20control.segment,%20control.radius,%20control.radius%20%20段,%20control.close%20%20);%20};};control.newPoints%20%20();%20函数generatePoints(点,%20线段,%20半径,%20半径线段,%20闭合)%20{%20if%20%20(spGroup)%20场景;删除(spGroup);%20spGroup=新THREE.Object3D();%20var材质=新THREE.MeshBasicmaterial({%20color:0xff0000,透明:%20false%20%20});%20var%20%20spGeom=new%20%20THREE.SphereGeometry(0.1);%20(spGeom,材质);%20spGroup.add(spGroup);%20return%20%20new%20%20THREE.TubeGeometry(new%20%20THREE.CatmullRomCurve3);(点),段,半径,radiusSegments,关闭);}%20//.%20勉强成功,管子形成的环需要精确的坐标才能达到完整的圆弧。我还没有找到计算坐标的方法。

%20

试炼四:Blender%20%20+%20Three.js

%20使用THREE.TubeGeometry勉强可以实现,但是效果不是很好。要实现平滑的环,需要为管道添加精确的扭曲环曲线路径功能。由于数学能力有限,目前还没有办法计算扭曲弧的路径。因此,我决定从建模层面来解决这个问题。

成功:然而,由于我的障碍,我花了很多时间在Blender%20%20中建模。

建模教程

%20在看bilibili的时候,发现了这位大佬发的一个宝藏视频,问题就解决了。

%20%20传送门:【动态设计教程】如何玩转AE+blender%20%20Facebook%20%20Metaverse%20%20Metadynamic%20%20Logo%20%20全面剖析,百分百学会

%20

用Blender建模

%20使用Blender%20%20进行建模并导出为fbx%20%20格式,您可以在其中保存动画。导出时,记得打开烘焙动画选项。

%20%20

加载依赖

%20脚本src='./assets/libs/Three.js'/scriptscript%20%20src='./assets/libs/loaders/FBXLoader.js'/scriptscript%20%20src='./assets/libs/inflate。%20min.js'/scriptscript%20%20src='./assets/libs/OrbitControls.js'/scriptscript%20%20src='./assets/libs/stats.js'/script%20%20

场景初始化

%20var%20%20容器、统计、控件、创建、相机、场景、渲染器、灯光、clickableObjects=[]、混合器、mixerArr=[]、manMixer;var%20%20Clock=new%20%20THREE.Clock();init();animate();function%20%20init()%20{container=document.createElement('%20div');%20//场景scene=new%20%20THREE.scene();%20scene.fog=new%20%20THREE.Fog(0xa0a0a0,%20200,%201000);相机:视野、宽高比、近面、远面camera=new%20%20THREE.PerspectiveCamera(60,%20window.innerWidth/window.innerHeight,%200.1,%201000);lookAt(new%20%20THREE.Vector3(0,%200,%200));%20//半球光源:室外创建更自然的光源light=new%20%20THREE.HemisphereLight(0xefefef);%20scene.add(light);%20//直接光light=new%20%20THREE.directiveLight(0x2d2d2d);//环境光varambientLight=new%20%20THREE.AmbientLight(0xffffff,5);%20//网格var%20%20Grid=new%20%20THREE.GridHelper(100,%20100,0xffffff,0xffffff);%20set(%200,%20-10,%200);opacity=true;%20scene.add(grid);setPixelRatio%20%20(window.devicePixelRatio);%20renderer.setSize(window.innerWidth,%20window.innerHeight);%20Shadow%20%20renderer.shadowMap.enabled=true;container.appendChild(renderer.domElement);%20//添加相机控制器controls=new%20%20THREE.OrbitControls(camera,%20renderer.domElement);%20window.addEventListener(%20'resize'%20,%20onWindowResize,%20false);%20//性能插件初始化stats=new%20%20Stats(stats.dom);}//屏幕缩放函数onWindowResize(%20)%20{%20Camera.aspect=window%20%20.innerWidth/window.innerHeight();setSize(window.innerWidth,%20window.innerHeight);}%20如果你想了解场景初始化的详细过程,请阅读我的文章。其他文章《使用three.js实现炫酷的酸性风格3D页面》。

%20

加载Logo模型

%20使用FBXLoader%20%20加载模型并对模型进行定位和调整大小。

varloader=new%20%20THREE.FBXLoader();loader.load('assets/models/meta.fbx',%20function%20%20(mesh)%20{%20mesh

.traverse(function%20(child)%20{%20%20%20%20if%20(child.isMesh)%20{%20%20%20%20%20%20child.castShadow%20=%20true;%20%20%20%20%20%20child.receiveShadow%20=%20true;%20%20%20%20}%20%20});%20%20mesh.rotation.y%20=%20Math.PI%20/%202;%20%20mesh.position.set(0,%201,%200);%20%20mesh.scale.set(0.05,%200.05,%200.05);%20%20scene.add(mesh);});

添加材质

本文%20Logo%20使用的是%20MeshPhysicalMaterial材质,它是一种%20PBR%20物理材质,可以更好的模拟光照计算,相比较高光网格材质%20MeshPhongMaterial%20渲染效果更逼真。使用%20THREE.TextureLoader%20为材质添加%20map%20属性来加载模型贴图。下图是金属质感的纹理贴图。 var%20texLoader%20=%20new%20THREE.TextureLoader();loader.load('assets/models/meta.fbx',%20function%20(mesh)%20{%20%20mesh.traverse(function%20(child)%20{%20%20%20%20if%20(child.isMesh)%20{%20%20%20%20%20%20if%20(child.name%20===%20'贝塞尔圆')%20{%20%20%20%20%20%20%20%20child.material%20=%20new%20THREE.MeshPhysicalMaterial({%20%20%20%20%20%20%20%20%20%20map:%20texLoader.load("./assets/images/metal.png"), metalness: .2, roughness: 0.1, exposure: 0.4 }); } } });})

添加动画

AnimationMixer 对象是场景中特定对象的动画播放器。当场景中的多个对象独立动画时,可以为每个对象使用一个 AnimationMixer。AnimationMixer 对象的 clipAction 方法生成可以控制执行动画的实例。loader.load('assets/models/meta.fbx', function (mesh) { mesh.animations.map(item => { mesh.traverse(child => { // 因为模型中有多个物体,并且各自有不同动画,示例中只为贝塞尔圆这个网格添加动画 if (child.name === '贝塞尔圆') { let mixer = new THREE.AnimationMixer(child); mixerArr.push(mixer); let animationClip = item; animationClip.duration = 8; let clipAction = mixer.clipAction(animationClip).play(); animationClip = clipAction.getClip(); } }) })});添加动画之后,不要忘了要在 requestAnimationFrame 中更新动画。 function animate() { renderer.render(scene, camera); // 获得前后两次执行该方法的时间间隔 let time = clock.getDelta(); // 更新logo动画 mixerArr.map(mixer => { mixer && mixer.update(time); }); // 更新人物动画 manMixer && manMixer.update(time); stats.update(); requestAnimationFrame(animate);}

展示加载进度

FBXLoader 同时返回两个回调函数,可以像下面这样使用,用来展示模型加载进程展示以及加载失败的逻辑实现。 <div class="loading" id="loading"> <p class="text">加载进度<span id="progress">0%</span></p><div>var loader = new THREE.FBXLoader();loader.load('assets/models/meta.fbx', mesh => {}, res => { // 加载进程 let progress = (res.loaded / res.total * 100).toFixed(0); document.getElementById('progress').innerText = progress; if (progress === 100) { document.getElementById('loading').style.display = 'none'; }}, err => { // 加载失败 console.log(err)});实现效果 e89cd21c049c499891fd40a92d66ba08~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720030474&x-signature=YxggEw24flkO8YaWjIJqfhe8UqQ%3D

点击更换材质

监听页面的点击事件,通过 HREE.Raycaster 拿到当前点击对象,为了展示例子,我为点击对象更换了一种材质 THREE.MeshStandardMaterial,并赋予它随机的 color 颜色、metalness 金属质感以及 roughness 粗糙程度。 //声明raycaster和mouse变量var raycaster = new THREE.Raycaster();var mouse = new THREE.Vector2();function onMouseClick(event) { // 通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1. mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // 通过鼠标点的位置和当前相机的矩阵计算出raycaster raycaster.setFromCamera(mouse, camera); // 获取raycaster直线和所有模型相交的数组集合 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);22ad40ab7ac14e7d9a61290305d21a66~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720030474&x-signature=IjplO2WxhFFmYIEngo%2BfErx%2BCcI%3D 更多关于网格材质的知识,可参考文章末尾的链接。

加载人物模型

人物模型的加载流程和 Logo 模型加载流程是一样的。我添加了一个正在施展龟派气功的人物,没想到与 Logo 模型的旋转动画非常契合 。 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)});本文示例人物模型来源于mixamo.com,该网站有有上百种人物和上千种动作可自由组合,免费 下载。大家可以挑选自己喜欢的人物和动画动作来练习 Three.js。 c4918b1f24fa4304ab4fdbf39c2ecc03~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720030474&x-signature=Fvnv7qIHJtPNetD9TnEwN5XvUtE%3D

总结

本文中涉及到的主要知识点包括: THREE.TorusGeometry:圆环。THREE.TorusKnotGeometry:环面扭结。THREE.TubeGeometry:管道。Blender: 建模。FBXLoader: 加载模型,显示加载进度。TextureLoader:加载材质。THREE.AnimationMixer:加载动画。THREE.Raycaster:捕获点击模型。如果你对源码感兴趣,请点赞+转发+关注+私信【logo】。 欢迎点赞+转发+关注!大家的支持是我分享最大的动力!!! 版权声明:本文转载于今日头条,版权归作者所有,如果侵权,请联系本站编辑删除

猜你喜欢