Threejs+Blender打造3D全景VR画展「1」

最近有一个项目需要搭建一个在线的3D全景VR画展,经过几天的摸索走通了整个流程,完成了一个简单的DEMO原型,我会将这几天的踩过的坑总结成一个教程系列分享给大家,希望你也会从中学到东西,少走一些弯路。

全景VR画廊

技术和工具选择

首先是webGL框架的选择,three.js免费开源,有活跃的社区和大量的学习案例,自然是我们不二的选择。其次是建模工具的选择,同样是开源免费的blender,相比其他的建模工具更小巧更轻量,上手更容易,在B站和油管上都可以找到免费的视频教程,最终我们锁定three.js+blender这对最佳CP。

用Blender创建画展模型

因为建模不是我们教程的重点,这里也不会用到复杂的模型,有兴趣的同学可以在B站和油管上找免费的bleneder教程来学习,由于最终要将模型导出到three.js中使用,这里简单介绍下blender建模中需要注意的地方,有不清楚的地方可以给行歌留言。

将相同类型的元素放在各自的集合中,方便模型的管理和导出,比如我们可以将不需要导出的摄像机和灯光等元素放在一个分组中,在导出时将该分组设置为不可选。

元素命名上建议使用类型+数字序列的方式,比如这里的画展图片,后面我们可以在three.js中方便的遍历这些名称带数字的元素,动态地给它们加载材质图片。

模型导出我们选择gltf二进制模式;只导出选择的元素;不导出素材,因为我们会在three.js中动态设置材质和贴图;因为我们的模型比较简单,所以这里选择不压缩模型,如果你的模型比较复杂需要压缩,在three.js中需要使用draco插件来加载压缩后的模型。

导出的模型大概100多k,如果采用压缩模式,导出的模型会下降到30几k,大家可以根据自己的情况自行选择,我们的模型比较简单,这里就偷个懒。

在threejs中渲染模型

首先我们要用gltfLoader来加载之前导出的glb文件,然后循环遍历模型并根据元素名设置不同元素的材质和贴图。

const loader = new THREE.GLTFLoader() loader.load( model/gallery.glb, gltf => { gltf.scene.traverse(child => { switch(child.name) { case walls: initWalls(child) break case stairs: initStairs(child) break } //设置展画边框贴图 if(child.name.includes(paint)) { initFrames(child) } //设置展画图片贴图 if(child.name.includes(draw)) { initDraws(child) } }) scene.add(gltf.scene) } )

修正材质贴图错误

在设置展画贴图后,我发现展画的颜色不对,材质的也是颠倒的。

经过一番踩坑,我们要这样设置材质的encoding和flipY值才能得到正确的结果。

texture.encoding = THREE.sRGBEncoding texture.flipY = false

第一人称摄像机跟踪

为了实现第一人称摄像机效果,我首先用一个box代表被跟踪对象,让场景中的摄像机始终同步跟踪这个box中的一个坐标,我们只需要根据键盘事件来移动旋转box就能达到第一人称摄像机的效果。

//用插值函数来过渡摄像机 camera.position.lerp( activeCamera.getWorldPosition( new THREE.Vector3() ), 0.05 ) const pos = player.position.clone() camera.lookAt(pos)

总结

目前为止我们已经完成了搭建3D画展的第一步,我们接下来会加入简单的碰撞检测功能,并学习如何在手机等移动设备上的添加导航功能。

源码地址:https://github.com/imokya/3dvr-gallery

更多教程关于码语派公众号

    THE END
    喜欢就支持一下吧
    点赞10 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容