大型 3D 互动开发和优化实践

这篇具有很好参考价值的文章主要介绍了大型 3D 互动开发和优化实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开发背景

得益于“元宇宙”概念在前段时间的爆火,各家公司都推出了使用 3D 场景的活动或频道。

大型 3D 互动开发和优化实践

大型 3D 互动开发和优化实践

3D 场景相比传统的 2D 页面优点是多一个维度,同屏展示的内容可以更多,能完整的展示物体、商品的信息。

相应带来的缺点是用户使用方式改变,用户需要额外的学习成本。另外初期需要的开发量、美术资源和生成3D模型的设备也是增加的成本。

在这样的背景下,我们团队接到了食品频道的一个互动项目的开发需求,希望通过 3D 场景的展示和互动方式,作为对未来购物的一种尝试与探索,满足用户对未来美好新奇的一个需求。将购物场景化、娱乐化,给用户带来美好的购物感受。

大型 3D 互动开发和优化实践

前端框架选择

3D项目相比之前的2D项目改变的主要是客户端的表现。在希望不依赖app客户端支持和在尽量多的环境下能运行,我们首先采用的方案是在 Web 端实现 3D 项目实现。

开发套件

首先我们考虑的是成熟的开发套件,如unity/egret等,但这些开发套件都有一些我们不能绕过的问题,例如:

  • 商业化使用需要收费

  • 需要使用其他语言开发(如 C# ),对团队学习成本较大

  • 打包输出的文件大小过大

  • 官方文档不够详细,学习曲线较抖

引擎名称/对比维度 使用价格(权重50% 脚本上手(权重30% 场景搭建(权重20% 支持模型格式(权重10% 社区资料丰富程度(权重30% 支持web端发布(一票否决
Unity 3d 3 7 10 8 10 Y
Laya 4 9 7 7 7 Y
Egret 10 8 7 7 6 Y
Cocos2d-js N
Godot 10 7 7 8 7 Y

由于以上的原因,开发套件里没有令团队很满意的选择,我们从其他方向寻找开发工具。

开源渲染库

另外也比较了 Web 前端使用量较多的两个 3D 渲染库:

◦three.js 提供的组件粒度较小,较基础,能做很高程度的定制化二次开发,但如果需要开发一个互动项目,需要开发的组件比较多

◦babylon.js 既提供了粒度小的基础组件,也封装了接近开箱即用的组件。并自带了性能测量工具,提供了方便的debug方法和优化策略

经过团队内对各个开发套件/渲染库的试用,最后选择了 babylon.js 作为项目的渲染层库,在其提供的组件上二次开发业务逻辑。

项目场景搭建

渲染分层结构

项目渲染层级总体分为两层:3D 场景层和 HUD 层

1.3D 场景层顾名思义渲染 3D 场景,由 人物模型、建筑模型和宝箱这些互动模型组成

2.HUD 层渲染互动按钮、弹窗、业务需要的商品列表等2D UI 内容

本来 babylonjs 是支持 3D 和 2D 内容混合渲染的,但是如果都使用 babylonjs 渲染,在设置两种内容需要使用统一的分辨率,而在现在的移动端设备上,能支持像素分辨率(如iPhone 14的像素分辨率为1170x2532)渲染不卡顿的只占一小部分。在大部分的设备上,最多只能支持在逻辑分辨率(如iPhone 14逻辑分辨率为390x844)下流畅运行,但设置这样的分辨率会使 2D 层渲染模糊,所以使用分层的方法渲染。

由 babylonjs 渲染 3D 场景层,而 HUD 层则通过 react 框架使用传统 DOM 方式渲染。

第二个 3D 渲染层

渲染层分为 3D 场景层和 HUD 层带来了一个问题,,需要在 HUD 层上再渲染 3D 内容时,例如展示 3D 模型,则不得不再增加一层 3D渲染层,而 3D 渲染层不停地在调用渲染方法,以响应用户操作和播放动画,这耗费了大量CPU和GPU的计算资源,还占用了存储模型顶点信息和贴图纹理的内存空间。因此在多个 3D 渲染层共存的情况下,需进行一定的管理以优化性能。我们采用以下策略管理多个 3D 渲染层:

◦在展示另外的 3D 渲染层时再实例化,并暂停原来 3D 渲染层的渲染

◦在不需要展示的时候销毁,恢复原 3D 渲染层的渲染方法调用

以尽量减少资源的占用,提高项目的渲染性能。

大型 3D 互动开发和优化实践

交互组件开发

碰撞检测

babylonjs 自带检测模型间是否碰撞的方法,但使用设计师提供的高精度模型直接去调用碰撞检测方法的话,计算量会很大,虽然未在测试设备上出现较严重的卡顿现象,但是已经使设备发热。

因此需要使用一个包围模型的不可见的、精简面的“空气墙”模型来做碰撞检测。在项目初期,这个“空气墙”模型需要设计师提供,在建模软件里根据原模型制作低精度包围模型。在后续迭代开发中,我们团队开发了“一键生成空气墙”的工具,自动生成低精度模型,减少设计师交付的资源数量,也减少更新模型时出错的机会。

大型 3D 互动开发和优化实践

镜头避障

因为项目用的是第三人称的镜头,镜头离开人物模型有一定的距离,在人物走动或用户控制角度的时候,镜头有可能和建筑模型或场景模型碰撞,造成“镜头穿模”的现象。

babylonjs 自带的镜头没有避开模型的功能,在产品也没有处理经验的时候,我们做了如下两个方案:

  1. 镜头外围用一个不可见模型包围,跟人物一样与建筑、场景模型做碰撞检测,使镜头不会进入到模型中去。

这种方法的优点是可以使用内置的碰撞检测方法,不需要额外的开发量。但是缺点也很明显,用户对镜头和模型的碰撞导致停止没有预期,总会觉得镜头不自然的不受控制。

  1. 镜头和人物之间用棒状的模型连接,同样在棒状模型上调用与建筑、场景模型的碰撞检测,当棒状模型的某个位置发生碰撞时,镜头将移动到人物与碰撞点之间的位置,避免镜头进入模型的同时,也避免模型穿插在人物与镜头中间,造成导致用户找不到人物的问题。

这种方法实现的效果符合一些同样是第三人称视角的 3D 游戏的镜头运动逻辑,用户感受更自然,不会出现失控的现象。而引入的额外开发量也在可控的范围内。

大型 3D 互动开发和优化实践

与设计团队的资源交接

模型格式

在众多的 3D 模型格式中,我们选择了 .gltf 格式。相对于其他模型格式,.gltf 可以减少 3D 格式中与渲染无关的的冗余数据,从而确保文件体积更小。

目前 3D 素材相对来说都比较大,这对于移动端加载体验来说,无疑是致命的。因此拥有更小体积的格式,也拥有了更高的优先选择权重。

除此之外,.gltf 是对近二十年来各种 3D 格式的总结,使用最优的数据结构,从而保证最大的兼容性以及可伸缩性,在拥有大容量的同时,支持更多的拓展,比如支持多贴图、多动画等。

所以 .gltf 成为了我们与视觉约定好的唯一素材格式。

模型输出流程

本来设计师工作流使用的建模软件是 C4D ,但是在资源交接的过程中,我们发现了几个问题:

1.缺少导出 gltf 文件功能。 在某些版本的 C4D 不能导出 gltf 格式的模型;某些版本能导出,但是导出有问题。而又因为设计师使用的一些渲染器支持问题,不能轻易更新 C4D 版本。

2.导出模型大小不统一。 可能因为某些版本的 C4D 导出的问题,或是 C4D 里的一些设置没能导出到 gltf 文件,设计师几次导出的模型大小并不统一,例如人物模型比建筑模型还要大上好几倍。

3.导出材质信息丢失。 设计师在建模时,因为模型可能会在多个渠道使用,例如渲染宣传图片,大部分情况会使用第三方的渲染器做渲染,这时候可能模型里会使用这些渲染器独有的材质。而这些材质导出到 gltf 文件时,会丢失这些独有材质的信息。再导入到页面的场景中时,设计师会发现展示的效果跟他们在建模软件里看到的相差甚远。

在和设计师多次沟通后,我们之间定立了一个导出模型的工作流:

在 C4D 建模完成后,导出 FBX 格式的文件,再导入到对 gltf 支持较好的 blender 软件中,设计师可以预览他们的材质在中转过程中有没有丢失效果,blender 导出的 gltf 文件中的模型也能保持一致的大小。

预设光影

在默认的渲染设置中,我们把设计侧输出的模型放进场景中,加上光源,也只有明暗的变化,没有影子,缺少了一些立体感。

在我们尝试加入影子的过程中,发现性能受到严重影响。在查阅了渲染原理后,发现当每在一个平面上增加影子,相当于多渲染一次场景,渲染的压力成倍增加。

跟设计侧交流后,决定在地板的贴图纹理上预先加上建筑的投影。这种方法对大部分是固定模型的场景能有较好的效果,而人物的阴影可以用静态图片跟随模型移动模拟。

大型 3D 互动开发和优化实践

渲染优化

压缩纹理

在开发期间发现在型号旧一点的iPhone设备上很容易出现闪退的现象,应该是页面使用的内存超过了上限。

在项目中使用的资源体积最大的是模型 gltf 文件,检查文件的内容,占体积很大一部分的是纹理贴图,解析资源发现很多贴图的大小是3K(3072x3072的图片),根据 WebGL 渲染原理,无论贴图的资源原来是什么格式,最后在渲染前需要解压,相当于一张贴图需要在内存中占 3072 x 3072 x 3Byte = 27MB,解压后还需要传到 GPU,在多张贴图同时渲染时很可能占用大量的内存。

经过和设计侧的沟通,同意在一些展示距离不可能很近的模型上替换较低分辨率的贴图。

另外通常 2D 项目中使用的 png/jpg 格式图片,并不适合 3D 渲染,他们需要经过上述的解压过程,才能被 GPU 读取。

在 3D 渲染领域,有其他适合 GPU 读取的格式,如安卓支持的 ETC ,iOS 支持的 PVRTC,新一代的标准压缩纹理格式 ASTC ,他们都不需要解压就可以被 GPU 读取,可以大大减少中间解压占用的内存容量。

在项目中,我们使用 gltf-transform 工具做缩小贴图分辨率,和转换格式的工作。

模型减面

模型在 WebGL 中渲染的流程是先用模型的顶点信息确定三角面,再在每个三角面上计算需要展示的颜色。所以如果能减少模型面的数量,能减少每次渲染的计算量,减少每帧需要的渲染时间。

而如上面所说的,设计师建模的时候,可能面对的需求是输出渲染图,而不会对实时渲染做优化,所以在某些地方可能使用了过多的面。

参考了团队内其他同学的优化经验1,使用 gltf-transform 工具对模型进行自动化减面。在和设计测反复沟通后,我们确定了减面的参数 ratio = 0, error = 0.0001

合批渲染

在 3D 渲染中有一个 draw call 的概念,一次 draw call 就是 CPU 向 GPU 下的一次画图指令。在一次指令中,CPU 会向 GPU 传递需要画的三角形信息,和三角形上颜色怎么计算的方法,这个方法用人类明白的语言称作材质。所以一次 draw call 只能画相同材质的面。

大型 3D 互动开发和优化实践

因为每次 draw call 有这些准备的动作,所以通常两次 draw call 会比一次花的时间多。

在模型文件中,相同材质的面,可能不是定义在同一个模型中,这样 CPU 会把这些面拆分成不同的画图指令,令 draw call 数量增加。

有一种对这种情况的优化方法叫合批,可以对这些相同材质的面合并,使他们可以在一次 draw call 中完成绘制。

这工作没有工具帮助我们处理模型文件,但是在前端加载模型文件时,可以遍历模型中的网格 mesh ,把使用相同材质的做合并。

需要注意的是带动画的网格不能这样处理,因为合并后的物体中心会变化,例如两个自转的球合并之后会围绕两个球的中点公转。

后续迭代

模型懒加载和分级加载

虽然暂时的项目展示的场景还不是很大,同时加载和渲染对设备的压力不算很大,但在场景增长到一定程度的时候,需要引入模型的懒加载和分级加载。

◦懒加载策略:在镜头移动到足够靠近时再加载并插入模型到场景,销毁离镜头足够远的模型。

◦分级加载策略:在镜头较远时,加载较低精度的模型,较近时再切换成精度高的模型。

以上两个策略都是现在较大型的 3D 游戏会使用的加载策略,能减少同一屏幕中绘制的面数量,减轻渲染压力。

分级渲染

现时访问 3D 项目的设备性能差距非常大,有加上特效也能流畅运行的,也有只能在设备分辨率下基本运行的。

babylonjs 自带一个分级渲染的功能,能实时检测运行帧率决定是否降级,在之后的迭代中,可以增加从像素分辨率加上特效到设备分辨率基本渲染的分级渲染策略。

实时光影

在使用以上的分级渲染策略后,可以在性能较好的设备上加上实时光影的特效,动态替换预烘焙贴图

场景搭建工具

在之前的项目开发过程中,设计师和产品、运营都需要通过前端输出demo才能大概体验到 3D 场景的效果,决定下一步如何调整。为解决这个痛点,我们团队开发了一个 3D 场景的搭建工具,用户可通过上传 gltf 文件搭建 3D 场景,实时预览渲染效果。

并加入了在项目中沉淀的互动组件,快速生成 3D 场景项目。

参考来源:

  1. 说一说 glTF 文件压缩 https://jelly.jd.com/article/61057292df18aa019e8a2967

作者:京东零售 胡俊文

来源:京东云开发者社区文章来源地址https://www.toymoban.com/news/detail-472899.html

到了这里,关于大型 3D 互动开发和优化实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 3 华为鲲鹏HCIP-性能优化23+开发实践7

    5 鲲鹏应用性能优化:23 6 鲲鹏应用开发实践:7 NUMA : Non Uniform Memory Access 非统一内存访问架构(NUMA) 是一种计算机内存设计,用于多重处理,其中内存访问时间取决于内存相对于处理器的位置。处理器可以利用NUMA的优势, 优先访问本地内存(速度更快) ,而不是访问非本

    2024年02月03日
    浏览(38)
  • 指挥通信车360度3d虚拟互动展示系统的优势及特点

    通信车是装有通信装备,用于保障通信联络的专用车辆,用于偏僻/特殊环境下的机动通信。并且机动通信局装备通常分为应急综合通信车、网络管理车、程控电话车、自适应跳频电台车、数字扩频接力车、散射通信车、卫星通信车、光缆引接车、线缆收放车和通信电源车等,

    2024年02月06日
    浏览(44)
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-游戏逻辑框架全解

    Cocos Cyberpunk 是 Cocos 引擎官方团队以展示引擎重度 3D 游戏制作能力,提升社区学习动力而推出的完整开源 TPS 3D游戏,支持 Web, IOS, Android 多端发布。 本系列文章将从各个方面对源码进行解读,提升大家的学习效率。希望能够帮助大家在 3D 游戏开发的路上更进一步。 工程源码

    2024年02月08日
    浏览(52)
  • 3D开发工具HOOPS助力CAM软件优化制造流程

    在现代制造业中,计算机辅助制造(CAM)软件的发展已成为提高生产效率和产品质量的关键。为了满足不断增长的需求和日益复杂的制造流程,CAM软件需要具备高效的CAD数据导入、云端协作、移动应用支持以及丰富的文档生成能力。 Tech Soft 3D的HOOPS软件开发工具包(SDK)为尖

    2024年04月26日
    浏览(51)
  • 云边协同的 RTC 如何助力即构全球实时互动业务实践

    作者:即构科技 由 51 CTO 主办的“WOT 全球技术创新大会 2023·深圳站”于 11 月 24 日 - 25 日召开, 即构科技后台技术总监肖潇以“边缘容器在全球音视频场景的探索与实践”为主题进行分享。 边缘计算作为中心云计算的补充,通过边缘容器架构和云边协同,为音视频、云游戏

    2024年01月21日
    浏览(41)
  • 大型、超大型数据中心园区设计如何审查与优化

    (一). 设计的优劣如何评价? 设计一般是指数据中心非IT部分的基础设施的方案设计、扩初设计、施工图设计,一般仅涉及结构、建筑、装饰装修、消防、暖通、给排水、电气、智能化等专业。随着大型超大型数据中心及园区的兴起,也会部分涉及输配电、市政及土木工程专业

    2023年04月08日
    浏览(66)
  • matlab 大型矩阵运算效率优化

    最近遇到1500*1500*1500*1500量级的运算。用matlab来计算的话运算效率极低。因此需要对matlab代码进行优化: 原始代码(其中UAt,XA, XB,YA, YB是1500*1500的矩阵): 原始运算效率(window笔记本,2080ti显卡,i710750h cpu):  思路一,原始的代码里头用了循环套循环的方法来做,但是这

    2024年02月09日
    浏览(48)
  • 惊爆了!这款AR智能教育APP可以“面对面”与3D虚拟诗人互动对诗

    “大鹏一日同风起,扶摇直上九万里” “莫愁前路无知己,天下谁人不识君” “古来圣贤皆寂寞,惟有饮者留其名” ...... 图源《长安三万里》 唐朝只是一个时代的缩影,是千年中华文化长卷中的一小部分。 在浩瀚如烟的文学典籍里,诗词是最具时代代表性的璀璨明珠,古

    2024年02月03日
    浏览(57)
  • 前端工程化实战:React 模块化开发、性能优化和组件化实践

    前端工程化实战是指通过组织工作流程、使用工具和技术来提高前端开发效率和质量的一种方法。常见的前端工程化实践包括模块化开发、自动化构建、代码检查和测试、性能优化等。下面将简要介绍模块化开发、性能优化和组件化实践。 模块化开发 在 React 中实现模块化开

    2023年04月10日
    浏览(72)
  • 【Unity】实用功能开发(一)实现在UI中用RawImage实时展示3D模型(背景透明,并通过UI防止3D场景遮挡)并可以通过分层完成:游戏中的人物状态展示界面,小地图,人物实时头像状态等功能

    有时由于项目效果需要,部分功能的实现受到阻碍,这里收集一些已实现的思路和方法,每次会记录大致需求和遇到的问题,如果有更好的想法,欢迎评论区讨论!!! 目录 功能描述: 需求描述: 实现步骤: ①为需要展示的内容区分层级: ②在场景中添加一个摄像机,并

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包