如何用Three.js+Blender打造一个web3D展览馆运营活动新玩法层出不穷,web3D炙手可热,本文将

运营活动新玩法层出不穷,web3D炙手可热,本文将一步步带大家了解如何利用Three.js和Blender来打造一个沉浸式web3D展览馆。

3D展览馆是什么,先来预览下效果:

看起来像个3D冒险类手游,用户可以操纵屏幕中央的虚拟摇杆,以第一人称视角在房间内自由移动、看展览。

首先介绍一个背景,我们的工作内容是做游戏中心的用户运营活动,会做些好玩的活动让用户参与,并get一些福利。

当时的活动背景是我司一年一度的vivo游戏节,并且元宇宙是大热词。所以做它的原因有几个:

用到的组合方案:Three.js+Blender。

开源的3D框架有很多,但最常用的有两种:Three.js、Babylon.js,我们只需要从中二选一。分析后发现两者各有优势:

考虑到3D展览馆的几个基本特性:

Three.js包体更小、有更多参考案例、上手更快,所以虽然Babylon.js有它的优势,但Three.js更适合这个项目。

Blender是一款轻量的开源3D建模软件,有很多好用的免费插件,而且Blender能导出GLTF/GLB模型(后面会对GLTF/GLB模型做简介),匹配Three.js的使用方式,整体更简单好用一些。

所以,就是它了。

在进入开发之前,先简单了解Blender和GLTF/GLB模型。

首先,Blender大概长这样,图中是设计师交付的3D展览馆稿子。简单理解为,左侧是模型的层次结构,中间是模型的预览效果,右侧是模型的属性面板。

GLTF(GraphicsLanguageTransmissionFormat)是一种标准的3D模型文件格式,它以JSON的形式存储3D模型信息,例如模型的层次结构、材质、动画、纹理等。

模型中依赖的静态资源,比如图片,可以通过外部URI的方式来引入,也可以转成base64直接插入在GLTF文件中。

它包含两种形式的后缀,分别是.gltf(JSON/ASCII)和.glb(Binary)。.gltf是以JSON的形式存储信息。.glb则是.gltf的扩展格式,它以二进制的形式存储信息,因此导出的模型体积也更小一些。如果我们不需要通过JSON对.gltf模型进行直接修改,建议使用.glb模型,它更小、加载更快。

在blender中,可以直接将模型导出为GLTF/GLB格式,三种选项的差别不再赘述,我们先简单选择最高效的.glb格式。

有了模型之后,我们可以开始通过Three.js创建场景,并导入这个模型了。

怎么加载一个模型?

(1)创建一个空场景

首先创建一个空场景scene,后续所有的模型或材质都会被添加到这个场景中。

import*asTHREEfrom'three'//1.创建场景constscene=newTHREE.Scene();//2.创建镜头constcamera=newTHREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);//3.创建Rendererconstrenderer=newTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);(2)导入GLTF/GLB模型

通过GLTFLoader导入.glb模型,并添加到场景中。

importGLTFLoaderfrom'GLTFLoader'constloader=newGLTFLoader()loader.load('path/to/gallery.glb',gltf=>{scene.add(gltf.scene)//添加到场景中}}(3)开始渲染

通过requestAnimationFrame来调用renderer.render方法,开始实时渲染场景。

functionanimate(){requestAnimationFrame(animate);renderer.render(scene,camera);}animate();ok,这样我们就完成了3D模型的导入,但是发现整个场景一片漆黑。

试试加个环境光。

ok,亮起来了,但是效果依然很差,很劣质。

原因是模型中的材质效果、光源、阴影、环境纹理,这些全都丢失了,所以当我们导入模型时,看到的就是一堆简陋的纯色形状。

所以我们要一步步将这些丢失东西找回,还原设计稿。

接下来一步步还原设计稿。

(1)加上光源

查看Blender模型,看到设计稿中添加了一堆点光源、平行光源。

点光源可以理解为房间中的灯泡,光线强弱随着距离衰减;

平行光源可以理解为太阳的直射光,它和点光源不同,光线强弱不随着距离衰减。

于是我们也增加一些光源:

//一些灯光选项//如果是平行光则没有distance、decay选项constlightOptions=[{type:'point',//灯光类型:1.point点光源、2.directional平行光源color:0xfff0bf,//灯光颜色intensity:0.4,//灯光强度distance:30,//光照距离decay:2,//衰减速度position:{//光源位置x:2,y:6,z:0}},...]functioncreateLights(){pointLightOptions.forEach(option=>{constlight=option.type==='point'newTHREE.PointLight(option.color,option.intensity,option.distance,option.decay):newTHREE.DirectionalLight(option.color,option.intensity)constposition=option.positionlight.position.set(position.x,position.y,position.z)scene.add(light)})}createLights()可以看到场景比之前好了一些,有了光源后,模型变得立体和真实了,多了一些反色的光泽。

但是我们注意到,画面中的logo、长椅的两侧都是黑色的,并且旁边的球体、椅子等都显得不够真实。

所以,我们需要进行下一步调整:调整模型材质、增加环境纹理。

(2)调整模型材质,增加环境纹理

先简单了解一下材质和环境纹理。

材质就像物体的皮肤,我们可以调整皮肤的光泽、金属度、粗糙度、透明与否等属性,让物体有不同的视觉效果。

一般从blender导出的模型中,已经包含了一些材质属性,但是Three.js中的材质属性和Blender中的属性并非完全的映射关系,模型在导入到Three.js后,效果和设计稿会有差异。这时候我们需要手动调整材质的属性,来达到和设计稿近似的效果。

环境纹理就是让模型映射周围的环境,让场景或物体更真实。例如我们要渲染一个立方体,把立方体放进一个屋子里,这个屋子的环境就会影响立方体的渲染效果。

比如镜面的物体被贴上环境纹理后,就可以实时反射周围的环境镜像,看起来很real。

设计稿中也是将一个大厅作为了环境纹理,让场景更真实。

环境纹理分为:球形纹理和立方体形纹理。两者都可以,这里我们采用一张大厅的球形纹理作为环境贴图。

以画面中的vivo游戏节logo为例,我们通过调整它的材质和环境纹理,让它变得更真实。

constloader=newGLTFLoader()loader.load('path/to/gallery.glb',gltf=>{//1.根据Blender中物体的名字,找到logo模型gltf.scene.traverse(child=>{if(isLogo(child)){initLogo(child)//2.调整材质setEnvMap(child)//3.设置环境纹理}})scene.add(gltf.scene)}}//判断是否为LogoconstisLogo=object.name==='logo'functioninitLogo(object){object.material.roughness=0//调整表面粗糙度object.material.metalness=1//调整金属度}//加载环境纹理letenvMapconstenvmaploader=newTHREE.PMREMGenerator(renderer)constsetEnvMap=(object)=>{if(envMap){object.material.envMap=envMap.texture}else{textureLoader.load('path/to/envMap.jpg',texture=>{texture.encoding=THREE.sRGBEncodingenvMap=envmaploader.fromCubemap(texture)object.material.envMap=envMap.texture})}}经过上面的处理后,可以看到原先黑色的logo有了金属光泽,并且会反射周围的环境纹理。

其它物体经过类似的处理后,也变得更真实一些。

现在整个场景更接近了设计稿一些,但场景中少了阴影,显得很干瘪。

加上阴影。

(3)增加阴影

增加阴影分四步:

添加阴影后,有质的提升,发现整个场景立体了很多,此时还原度已经很高。

如果不考虑性能损耗,这个场景的样式已经可以投入使用了。(后续会提到性能优化)

小结一下,刚刚做的几件事:

现在3D展览馆场景已经还原的差不多了,接下来要构造一个虚拟移动摇杆,控制第一人称镜头的移动和转向,实现沉浸式逛展的效果。

要实现通过虚拟移动摇杆控制镜头的移动和转向,我们需要三个东西:

有人会问为什么需要一个player,通过摇杆直接控制镜头不就行了吗?其实player的作用是用于做碰撞检测,当player遇到凳子、墙壁等障碍物时,需要停止镜头移动。直接控制镜头,是无法做碰撞检测的。

所以,实际上镜头移动的逻辑是:

用户操纵摇杆→更新player位置和朝向→从而同步更新camera位置和朝向

(1)创建移动摇杆

移动摇杆的实现原理很简单,这里仅做简述。

核心在于创建一个圆盘,监听触摸手势,并根据手势的方向来实时更新move参数,控制镜头的移动和转向。

constspeed=8//移动速度constturnSpeed=3//转向速度//moveoption,用于调整第一人称镜头的移动和转向constmove={turn:0,//旋转角度forward:0//前进距离}//创建一个handler,并监听手势,调整moveoptionconsthandler=newHandler()handler.onTouchMove=()=>{//updatemoveoption}(2)创建player

首先创建一个player对象,它是一个1.2*2*1的透明长方体。

每次渲染(render)时,更新player的位置和朝向,并同步更新镜头的位置和朝向。

完成上述步骤后,我们就可以通过控制虚拟移动摇杆,来让镜头移动和转向了。

接下来加入碰撞检测,对镜头移动加点限制。

碰撞检测的步骤也很简单:

(1)收集障碍物

模型加载完成后,遍历所有的child,如果child是一个物体(mesh),则把它加入到障碍物队列(colliders)中。

constcolliders=[]loader.load('path/to/gallery.glb',gltf=>{gltf.scene.traverse(child=>{//收集障碍物if(isMesh(child)){colliders.push(child)}})}})(2)检测碰撞

调整刚刚的updatePlayer方法,在其中插入检测碰撞的逻辑。

碰撞检测逻辑基于THREE.Raycaster来实现,racaster可以理解为一个射线,当射线穿过了某个物体,我们就认为射线和物体相交了。

当我们移动到椅子、墙壁等障碍物附近时,镜头会停止移动。镜头的移动范围也被我们限制在房间里,不会穿到房间外部。

3D展览馆的基本功能已经完成了,但还没有做任何的性能调优。当我们把项目运行在手机上,会发现设备发热发烫,帧率很低,低端机型甚至无法运行。

经过分析,实时的光影渲染是罪魁祸首。

页面中有10+个光源,每个光源都在实时投射阴影(尤其是点光源十分消耗资源,引起卡顿)。但实际,场景中的光源和物体位置都没有发生改变,这意味着我们不需要计算实时阴影,只需要固定的阴影。

这点可以通过纹理烘焙来实现。并且在移动端,经过纹理烘焙的光影效果实际上要优于设备计算的实时光影效果。

纹理烘焙,是指通过将场景效果预渲染到指定纹理上,生成一个模型贴图。在Blender中,我们可以选中任意对象进行烘焙。

以3D展览馆的地板为例,我们可以通过纹理烘焙,将光影效果直接渲染到贴图上。

左图是原本的棋盘格纹理,右图是结合了光影效果的烘焙贴图。烘焙完成后,地板上的光影效果就被固定下来了,我们也不需要再做实时的光影渲染。

用同样的方式,将地板、墙壁、天花板等物体,一一进行烘焙处理,导出一个新的模型。由于光影效果已经被渲染到贴图上,我们可以将大部分光源去掉,只保留2-3个必要的点、平行光源和全局光。再次运行后,发现卡顿、发烫的问题已经不再明显。并且效果其实比实时渲染更精细一些。

这里没有对烘焙做过多介绍,要生成精致的烘焙结果还需要依赖对UVMap、烘焙参数的了解,虽然这些偏向于设计同学的工作,一般由他们来输出烘焙纹理。但是作为开发者,了解了这些后才能和UI更好地沟通和配合。

模型大小约为23M,首次加载模型需要9s左右。(尤其是在做完纹理烘焙后,由于贴图变得复杂,模型更大了)

以下是几个优化模型大小的建议:

(左图为优化前,右图为优化后)

现在,我们基本完成了整个3D展览馆的开发。虽然有一些细节没有在文中涉及到,但开发过程大致如此。

THE END
1.展厅讲解稿范文5篇(全文)好,到这里我们**公司的产品体系就给大家介绍完了,相信大家对**已经有了一个相对完整的认识,非常感谢大家莅临***参观、指导,欢迎再次光临,谢谢! 展厅讲解稿 第2篇 欢迎大家来到振东文化展厅! 序言:振东创建于1993年。1993年4月5日,清明节当天,董事长李安平在他的家乡东和村边的一片墓地开土动工。这片墓地当时https://www.99xueshu.com/w/filehqlyvsgf.html
2.博物馆解说词(精选10篇)下面简要介绍一下进馆参观路线及注意事项。进入馆门右转逆时针走,参观矿石和生物化石标本及展板说明,绕一周后观看展厅中间的金山地质公园电子沙盘演示,然后上二楼操控室,参观金山省级地质公园网站和数据库演示,最后在二楼影视厅观看金山省级地质公园影视片及地学科普教育片。进馆后希望大家不要喧哗、不要抽烟。下面请大https://www.jy135.com/jieshuoci/2036089.html
3.渡江战役展厅介绍稿件展馆特色 渡江战役展厅在设计上独具匠心,采用了大量先进的科技手段,使游客不再是被动地欣赏陈列品,而是能够与展品互动、参与其中。例如,在“南京保卫战”展区中,游客可以通过虚拟现实技术穿越时空,以高清晰度的画面感受当时保卫南京的惊心动魄场景;在“中国人民解放军光辉历程”展区中,则有一座全息投影雕塑像呈现出毛https://www.sthyzt.com/gs/42074.html
4.校园模拟招聘大赛策划方案(通用13篇)(1)主持人宣布活动开始,介绍到场嘉宾及评委,简要介绍决赛相关内容及规则(可加入嘉宾致辞)。 (5)比赛:模拟招聘内容由两部分组成,选手自我介绍(不得超过两分钟,若超过两分钟,由在场工作人员提醒),评委提问(可加入评委点评)个人总时间尽量控制在5分钟内(若有评委点评,可控制在8分钟内)。 https://www.yjbys.com/hr/zhaopin/3007135.html
5.如何用Three.js+Blender打造一个web3D展览馆blenderthreejs本文介绍了如何利用Three.js和Blender创建一个沉浸式的3D展览馆。首先,文章解释了项目背景和技术选型,选择Three.js和Blender的原因。接着,详细讲述了从加载GLTF/GLB模型到调整材质、添加光源、环境纹理、阴影以及实现虚拟移动摇杆的过程。最后,讨论了性能优化,包括纹理烘焙和模型大小的优化,以提高加载速度和运行效率。 https://blog.csdn.net/vivo_tech/article/details/131717174
6.红领巾讲解员演讲稿南京市规划建设展览馆大家好! 我是XX学校X年级的学生XXX. 我是南京市规划建设展览馆的红领巾讲解员,今天非常荣幸能够站在这里,向大家介绍我们美丽的家乡——南京。南京,这座历史悠久的文化名城,自古以来就是华夏儿女心中的骄傲。今天,我将带领大家领略南京市https://m.dianping.com/ugcdetail/251004393?sceneType=0&bizType=29&msource=baiduappugc
7.216期展协通讯新会员介绍(共24家) 安徽玺文展览服务有限公司 北京东方迅腾建筑装饰工程有限公司 北京浩维广告有限公司 北京黑马一点红技术服务有限公司 北京华尊天时文化发展有限责任公司 北京辉腾睿达展览展示有限公司 广东鸿基伟业科技工程有限公司 广东松立传媒科技有限公司 https://caec.org.cn/web/40/197001/7247.html
8.木心美术馆基本介绍 展厅展馆 序厅 画作 文学 展厅展馆 序厅 画作 文学 实用信息 交通详细介绍 PROFILE + 基本介绍 木心美术馆是在桐乡市民政局注册登记的民办非企业单位,该馆致力于纪念和展示画家、文学家、诗人木心先生(1927-2011)的毕生心血与美学遗产。这不仅是一座收藏过去时的美术馆,而且是向未来开放的精神指向和学术空间https://www.maigoo.com/citiao/248241.html
9.青岛海右博物馆开馆庆典暨馆藏书画精品展开展仪式2019年5月18日上午9:38,青岛海右博物馆隆重举行开馆庆典及馆藏书画精品展览。 5月18日是世界博物馆日,青岛海右博物馆在今天正式开馆迎客,为满足人民群众不断增长的精神文化需求提供了一个好去处,也为青岛加快建设博物馆之城再下一城。海右博物馆位于青岛CBD中央商务区核心位置,展馆面积2100多平方米,展线长260米,是https://www.meipian.cn/24els2zx
10.展览馆事迹材料讲解稿(共17篇)据烟台公安边防支队宣传科干事方毅介绍,“烟台雷锋事迹展览馆”总面积约300平方米,现场近500份历史资料记录了雷锋自幼年到离世的点点滴滴,也有张峻家人提供的“独家展品”,包括雷锋的几件物品、绶带以及张峻与家人探讨雷锋和雷锋精神的书信。 篇3:雷锋事迹展览馆 https://www.hrrsj.com/wendang/qitafanwen/832475.html
11.纪念明代大儒戴良先生诞辰700周年柳氏新闻戴良对医家情有独钟,《九灵山房集》中就有四个医家的传记,这些文章中,不但有人物礼赞,事迹介绍,还有大量生动奇特的医案实录,甚至有验方偏方,成为后学研究金华医史的不可多得的历史资料。[3] 戴良对医家的推崇同他的家学渊源、济世情怀和浙中一带的医学发达不无关系。在戴良看来,医本之于儒,医儒本是一家。http://www.txljr.com/newsinfo.asp?id=623&big=1
12.名师工作室主持人发言稿介绍名师主持人的发言稿在这个充满机遇和挑战的时代,名师工作室主持人非常荣幸能够向大家介绍这个崭新的平台。名师工作室是一个旨在提高教学质量和教育成果的平台,致力于帮助教师们提升教学技能和教育方法。今天,小编整理了有关名师工作室主持人发言稿的内容,一起来看下吧。 名师工作室主持人发言稿1 https://www.puchedu.cn/ziyuan/39772.html
13.浙江闰土股份有限公司科技展览馆工作人员向客户介绍前沿染料和染料中间体今年上半年,该区化工产业实现产值255亿元、利润35.5亿元,同比分别增长18.1%、65.1%。图为落户该区的浙江闰土股份有限公司科技展览馆工作人员向客户介绍前沿染料和染料中间体产品。 翁忻旸 摄 《中国质量报》https://www.cqn.com.cn/zgzlb/content/2018-08/07/content_6129843.htm
14.CIMT2023新闻发布稿今天的新闻发布会上,我们将主要介绍以下三个方面的情况,一是展馆、展商和展品情况;二是展会期间的国际交流和行业活动;三是展会各项保障和服务工作。 一、展馆、展商和展品情况 CIMT2023将使用北京 中国国际展览中心(顺义馆)全部8个室内展馆(E1、E2、E3、E4、W1、W2、W3、W4),以及4个临时展馆(E5、E6、E7、E8http://www.cimtshow.com/level3.jsp?id=5932
15.《几和第几》说课稿(通用9篇)作为一名教师,有必要进行细致的说课稿准备工作,借助说课稿可以有效提高教学效率。说课稿应该怎么写呢?以下是小编帮大家整理的《几和第几》说课稿,欢迎阅读与收藏。 《几和第几》说课稿 篇1 教学目标: 1.在具体的情境图中,理解几个和第几的不同。 2.初步https://xiaoxue.ruiwen.com/shuokegao/152788.html
16.学校副主任竞聘演讲稿(通用17篇)学校副主任竞聘演讲稿(通用17篇) 演讲稿可以起到整理演讲者的思路、提示演讲的内容、限定演讲的速度的作用。在当今社会生活中,演讲稿与我们的生活息息相关,大家知道演讲稿的格式吗?下面是小编精心整理的学校副主任竞聘演讲稿,欢迎阅读,希望大家能够喜欢。 https://www.unjs.com/fanwenwang/yanjianggao/20220310105056_4869394.html
17.西博会的总体方案,靳东个人资料及简历关于靳东的简介首届国家网络安全宣传周启动仪式2014年。第一届网络安全宣传周以“共建网络安全,共享网络文明“为主题,营造网络安全人人有责、人人参与的良好氛围。会议介绍了首届国家网络安全宣传周体验展的总体筹备情况和体验展的主要亮点。法律依据:《中华人民共和国网络安全法》:第二十一条 国家实行网络安全等级保护 http://9qm.net/dzzx/56912.html
18.第六届中国投资贸易洽谈会成果新闻发布稿大会期间,来自阿拉伯、非洲和大洋洲岛国等30多个国家先后举办了一系列投资环境和政策说明会,各国政府官员分别在上述说明会中介绍了当地投资环境和市场情况。此外,世界投资促进机构协会(WAIPA)、经济合作与发展组织等国际组织和中国贸促会,就如何促进国际投资和提高某些领域外国投资质量、促进国际贸易等问题进行研讨和培训,为https://www.mofcom.gov.cn/article/bi/200209/20020900040118.shtml
19.设计演讲稿演讲稿以发表意见,表达观点为主,是为演讲而事先准备好的文稿。在社会发展不断提速的今天,演讲稿的使用越来越广泛,怎么写演讲稿才能避免踩雷呢?以下是小编帮大家整理的设计演讲稿,仅供参考,希望能够帮助到大家。 设计演讲稿 篇1 平面设计师是在二度空间的平面材质上,运用各种视觉元素的组合及编排来表现其设计理念及https://www.gdyjs.com/shiyongwen/yanjianggao/565972.html