如何在Unity WebGL上实现一套全流程简易的TextureStreaming方案

项目介绍

《云境》是一款使用Unity引擎开发的WebGL产品,有展厅,剧本,Avatar换装,画展,语音聊天等功能,运行在微信小程序和PC,移动端网页,即开即用。
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

当前问题和现状

当前项目面临的问题和场景现状

  1. 首次场景包体大,首次下载时间长,用户首次进入到场景耗时较长。
  2. 项目场景本身偏展厅风格,非大世界,非大型游戏场景,云境的场景元素整体比较集中,当前项目场景多数多数是室内场景或者小场景,拆分出去的内容有限,美术人力资源有限,对场景做更细致的拆分处理和分块加载成本较高。

我们需要一套简单适用的方案,降低场景包体大小。为了优化场景资源包大小,我们首先需要分析资源包里面的不同类型的资源占比,看哪些资源可以做优化和拆分

场景资源包分析

AssetBundle使用LZ4压缩,下面是针对三个原始场景资源包的分析
公园场景park_001.bundle,8.63MB,Mesh(6.5MB)+Texture2D(5.7MB)
请添加图片描述

剧本场景scenes_bxzf.bundle,11.3MB,Mesh(8.9MB),Texture2D(8.0MB)
请添加图片描述

某个展馆scenes_jttd.bundle,5.3MB,Mesh(439.3KB),Texture2D(8.0MB)
请添加图片描述

通过针对多个场景的资源包分析,会看到Mesh+Texture2D是一个场景资源包占比最高的两种资源类型,Texture2D基本占比在50%以上,而且针对个别场景Texture2D的资源占比会超过80%

方案确定

根据场景资源包的分析,可以得出的结论,针对云境目前的场景特点,多数场景Texture纹理贴图占比在50%~80%,如果采用Texture的处理能够很大程度上降低场景资源包的大小,收益比较明显,同时TextureStreaming的实现,相对MeshStreaming相对简单,投入产出比高,TextureStreaming不会改变场景原有的结构,可以降低美术人员的参与成本。

第一期设计一套简单,易实现,工作流完善的TextureStreaming方案,降低场景资源包中Texture的占比。

Unity引擎自身基于MipMapLevel实现的TextureStreaming,在WebGL平台该功能无法使用 所以需要自己开发一套简化版本并和平台无关的TextureStreaming功能。和Unity的TextureStreaming方案相比,解决的问题有相似的地方,比如控制Texture在运行时的内存占用,将纹理内存维持在一个范围内。但是我们设计的TextureStreaming方案需要关注场景资源包大小同时能够在运行时降低Texture内存的占用。

什么是TextureStreaming

定义的轻量级TextureStreaming功能:将使用高清纹理的场景,离线处理成极低分辨率的场景叫做Lod Scene,在运行时加载Lod Scene,根据规则,从外部加载相应的高清纹理,对低分辨率的纹理做替换。原理简单容易理解。

整体设计目标-TextureStreaming

核心目标:实现简单,工作流程清晰,全自动化

方案需要达成的目标

  1. 非侵入式,做材质和纹理贴图的全量拷贝,降低复杂度和资源引用维护成本
    • 不改变原场景
    • 不修改原场景引用的材质,避免造成材质混乱,错误修改
    • 不修改原场景引用的纹理贴图
    • 不修改打包规则和之前的加载逻辑
    • 保留原始场景光照贴图和渲染设置,忽略对光照贴图的Lod处理
  2. 一键式处理,通过EditorSceneDescriptionConfig文件控制生成的Lod Scene内容,避免人工处理,节省人力
  3. EditorSceneDescriptionConfig需要支持的动态配置
    • 控制单个贴图LOD分辨率,提供x16,x32,x64,x128和原始贴图尺寸
  4. Editor离线和运行时配置分开,运行时配置数据结构简单
  5. Texture AssetBundle包大小,根据配置自动分割AB包
    • 最小化更新,Texture AssetBundle打包更新不会造成,整个Lod Scene也被更新
    • 需要HD Texture AssetBundle和Lod Scene AssetBundle无依赖关系
  6. 运行时,支持Texture Streaming功能分场景动态开关,加载HD Scene还是Lod Scene
  7. 运行时,支持Streaming流式加载(分Grid,分帧加载TextureCell)
  8. 运行时,支持Texture Bundle分帧请求加载,降低可能带来的卡顿
  9. 运行时,支持Material分帧修改,降低可能带来的卡顿(经过测试,暂时未发现该部分的耗时情况)
  10. 运行时,Grid直接选择九宫格方式,当前Grid索引+外部8个Grid的内容
  11. 运行时,使用最简单的加载规则,玩家在场景中的世界坐标作为整体输入参数
  12. 运行时,场景切换HD Texture加载和卸载正常
  13. 运行时,纹理切换不会卡顿

方案设计和实现

资源管理

目前使用Unity Addressable进行资源运行时管理和资源打包

Texture Streaming美术处理管线

完整的处理流程图如下:
请添加图片描述

场景处理管线具体介绍

创建SceneDescriptionConfig配置

请添加图片描述

采集场景资源:材质,纹理

获取场景中,所有引用的材质球和关联的纹理贴图,为后续生成LodScene做数据准备
忽略的部分:

  • 光照贴图
  • TMP Shader相关的材质球和纹理

拷贝Material,生成LodTexture,LodScene

生成LodScene

  1. 将依赖的材质拷贝一份,生成Lod Materials
  2. 将材质球依赖的所有Textures拷贝一份,生成HD Textures
  3. 根据设定的HD Texture 分辨率执行Texture缩放,生成Lod Textures
  4. 拷贝原始场景,生成Lod Scene
  5. Lod Materials引用的Texture更换为Lod Textures
  6. Lod Scene关联的Material替换为拷贝的Lod Materials

经过上述的处理,完成了Lod Scene的生成,保证对原始场景的资源无侵入处理,会带来一定的资源冗余比如Lod Textures,不过牺牲一小部分的内存,能够简化流程和实现方式,在当前项目目前是可以接受的

设置Grid参数,按照规则Grid分割场景

请添加图片描述

目前只支持规则的Grid切分,Grid的可调整的参数如下:

  • Grids起始位置
  • Grids,行列大小
  • 每个Grid大小的大小
    请添加图片描述

获取每个Grid包含的Renders

遍历场景中的所有Renders,确定所在的Grid,确定每个Grid依赖的Renders,通过Renders确定当前Grid依赖的Lod Materials,根据Lod Materials确定当前Grid需要加载的HD Textures

创建运行时Config,建立Grid,材质和贴图的映射关系配置

建立Grid-HD Texture-Materials之间的映射关联配置

运行时配置文件

请添加图片描述

Grid配置,一个Grid关联到多个Texture Cells

请添加图片描述

Texture Cells配置

  1. 资源Addressable Key(GUID),用于Addressable通过Key执行加载
  2. 对应的Lod texture引用
  3. 当前HD Texture关联的材质球和纹理槽位,如果当前HD Texture加载完毕,更新关联的Material对应的纹理槽位即可
    请添加图片描述

自动化资源分组

Lod Scene:Lod场景

  • Lod Scene Material + Runtime Config:Lod场景引用的材质球和运行时配置
  • Lod Scene HD Textures:Lod场景引用的HD Textures,按照Texture单个包体指定的大小,自动生成对应的Label做分包处理,Group使用Pack Together By Label模式打包

最终管线输出产物

自动化生成的工程产物

请添加图片描述

  • HDTextures:存放拷贝出来的原始纹理资源
  • LodTextures:存放处理过后的低分辨率的纹理资源
  • Mats:存放Lod Scenes引用的材质球资源
  • outdoors_001_gen_lod.scene:Lod 场景文件
  • outdoors_001_gen_lod_runtime.asset:TextureStreaming运行时配置文件

Addressable资源打包分组

Lod Scene-单独Group分组

  • Lod Materials+Runtime Config-单独的Group分组
  • Lod Textures-同一个Group分组,但是打包的采用Packed Together By Label方式打包成多个AssetBundle包
    请添加图片描述
    请添加图片描述
    请添加图片描述
    请添加图片描述

运行时逻辑

运行时的逻辑比较简单直接

接收角色位置输入->确定Gird->确定关联的TextureCells->使用Key加载->加载完毕,更新TextureCell关联的Materials
最终实现Lod Texture到HD Texture的动态更新
为了防止Grids关联的TextureCells过多,导致请求数量多,加载多,做了简单的“分帧”处理

  1. 玩家位置设定更新间隔,一定间隔检查Grid是否变换,有变换执行Grid管理资源加载
  2. 增加最大加载TextureCells数量限制,超过当前加载的数量,放入到等待队列中
  3. 等待队列检测增加轮询间隔
  4. HD Textures加载完毕放入队列,增加间隔去设置SetTexture,经过测试SetTexture并不会造成卡顿,所以取消对SetTexture的分帧处理

场景切换之后需要调用Addressables.Release(tc.Value);释放Texture2D资源

TextureStreaming方案收益

场景资源包大小在使用TextureStreaming之后的大小优化对比,目前已有的18个场景,场景包体大小都控制在5.5MB以下,首次加载时间优化,按照4G网络情况理论测算缩短3~5s,贴图资源量越大,包体减小越大,收益会比较明显
请添加图片描述

基础场景实现效果

streaming展示

总结和展望

本文介绍了适用于WebGL平台的场景包体大小优化的TextureStreaming方案,相对大世界流式加载复杂完善的方案,当前的TextureStreaming方案在一定程度上解决项目的痛点,优化了WebGL应用的场景包体大小,缩短下载时间,但是该方案还有很多需要继续细化和完善的地方,比如Grid粒度“粗糙”,加载逻辑更细致的控制,后续也会持续改进。

TextureStreaming后续完善的方向

  1. 场景处理管线,细化分割粒度和规则
  2. 运行时,细化加载规则,更精准的优先级,支持更多参数的输入视角,朝向
  3. 运行时,根据规则预加载Grid,降低延迟
  4. 运行时,支持动态卸载Grid,降低内存占用
  5. 打包资源,更精确化的Texture分包,目前采用Editor模式获取纹理大小,某些情况下获取的纹理大小和实际打包压缩之后的AB包大小差别比较大,导致Texture,AB分包并不均匀
  6. 针对LOD的纹理图片可以直接关闭MipMap,更快的加载速度和更小的内存,开启MipMap会带来33%的内存增大

场景资源包优化其他思路

  1. 支持Mesh Streaming
  2. 支持场景物件的拆分,将物件拆分出去,降低包体大小和场景对象数量
  3. LightMap的处理,进一步减少Texture2D的占用

TextureStreaming方案从问题分析,方案设计,到工具开发,运行时实现,整体比较简单易理解。
只有适合项目并解决项目痛点的方案才是合理的方案。当前的方案还有许多可以继续优化和扩展的地方,后续会持续优化。

希望能够提供一些思路和帮助,欢迎交流和指正~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1548782.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【质优价廉】GAP9 AI算力处理器赋能智能可听耳机,超低功耗畅享未来音频体验!

当今世界,智能可听设备已经成为了流行趋势。随后耳机市场的不断成长起来,消费者又对AI-ANC,AI-ENC(环境噪音消除)降噪的需求逐年增加,但是,用户对于产品体验的需求也从简单的需求,升…

mbedtls错误记录

0x2180 证书格式无效,可以检查证书的格式是否正确,或传入的证书长度是否正确 mbedtls_x509_crt_parse-》mbedtls_x509_crt_parse_der-》x509_crt_parse_der_core-》mbedtls_x509_get_sig_alg-》return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ret ); 所以26…

LampSecurityCTF7 靶机渗透 (sql 注入, 文件上传, 密码喷射)

靶机介绍 LampSecurityCTF7,vulnhub 靶机 主机发现 由于靶机配置问题,扫不到 ip 这里需要特别注意一下,在第一次启动打开靶机的时候,vmware会跳出一个提示框,让你选择我已复制该虚拟机/我已移动该虚拟机&#xff0c…

GIS专业在课余应该学计算机还是遥感?

有网友提问: 绝大数人给出了,强有力的建议,就是冲计算机 1、从学习条件上看本科阶段,学计算机编程,你只需要有台电脑,装一些编程软件,上git上找一些代码,b站找一些教程就可以大学特…

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序…

AI产品经理面试题详细整理【已拿offer】

面试题整理 以下是我面试过的AI产品经理岗位的精选面试题,供各位同仁参考: 💼 公司概览: 字节跳动、百度、昆仑天工、minimax、彩云、蕞右、粉笔、作业帮、火花、好未来等知名企业。 📍 方向分类: 模型…

【移植】小型系统平台驱动移植

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 平台驱动移植 在这一步,我们会在源码目录 //device/ve…

【Python】Flask-Admin:构建强大、灵活的后台管理界面

在 Web 应用开发中,构建一个直观且功能丰富的后台管理系统对于处理数据和维护应用至关重要。虽然构建一个完全自定义的管理后台界面非常耗时,但 Flask-Admin 提供了一个简洁、灵活的解决方案,可以让开发者快速集成一个功能齐全的后台管理系统…

防盗智能电子锁的使用

一、防盗智能电子锁的介绍 以宏泰HONGTAI的DJ08产品为例。 功能: 自动补锁、开锁并智能纠正人为错误操作行为;开启方式有门禁电控、钥匙、旋钮等;开门方向,左右、内外通用;带信号反馈,开锁声光提示&#…

数据结构:树的定义及其性质

树的定义 树是一种重要的非线性数据结构,树作为一种逻辑结构,同时也是一种分层结构。具有以下两个特点: 1.树的根结点没有前驱,除根结点意外的节点只有一个前驱 2.树中所有结点都可以有0个或多个后继 树结构在多个领域都有广泛…

【Python】字典 文件操作 生成二维码 多媒体操作

目录 字典 创建字典 查找key 新增键值对 修改键值对 删除键值对 遍历键值对 keys() values() items() 合法的key类型 文件 文件是什么 打开文件 关闭文件 写文件 读文件 *上下文管理器 实现文件查找工具 pip包管理器 生成二维码 安装第三方库 生成二维…

MySql在更新操作时引入“两阶段提交”的必要性

日志模块有两个redo log和binlog,redo log 是引擎层的日志(负责存储相关的事),binlog是在Server层,主要做MySQL共嗯那个层面的事情。redo log就像一个缓冲区,可以让当更新操作的时候先放redo log中&#xf…

2024.9.24 作业

My_string类中的所有能重载的运算符全部进行重载、[] 、>、、>) 仿照stack类实现my_stack,实现一个栈的操作 #include <iostream> #include <cstring>using namespace std;class My_string{ private:char *ptr;int size;int len;public://无参构造My_strin…

Miniforge详细安装教程(macOs和Windows)

(注&#xff1a;主要是解决商业应用anaconda收费问题&#xff0c;这是轻量级的代替&#xff0c;个人完全可以使用anaconda和miniconda) Miniforge 是一个轻量级的包管理器&#xff0c;类似于 Anaconda 和 Miniconda。它主要用于安装基于 conda 的 Python 环境&#xff0c;专注于…

IPEmotion 2024 R2现支持Amazon S3和Windows SMB服务器

新版IPEmotion 2024 R2软件推出了许多新功能&#xff0c;其中的一大功能是支持Amazon S3、Windows SMB服务器以及新的IPE-CAM-007 USB摄像头。IPEmotion 2024 R2还支持直接写入TEDS数据和配置可装载电池的新款IPE833记录仪。 — 创新成果一览 — ■ 支持Amazon S3、Windows SM…

IDEA 系列产品 下载

准备工作 下载 下载链接&#xff1a;https://www.123865.com/ps/EF7OTd-mbHnH 仅供参考 环境 演示环境&#xff1a; 操作系统&#xff1a;windows10 产品&#xff1a;IntelliJ IDEA 版本&#xff1a;2024.1.2 注意&#xff1a;如果需要其他产品或者版本可以自行下载&#xff0…

虚幻引擎UE5如何云渲染,教程来了

​步骤一&#xff1a;获取云渲染权限 访问渲染101官网&#xff0c;使用云渲码6666进行注册。 下载并安装渲染客户端。 步骤二&#xff1a;设置渲染环境 确保云渲染环境与您的本地环境一致&#xff0c;避免出错。 步骤三&#xff1a;任务提交 完成环境配置后&#xff0c;解析…

【LeetCode】每日一题 2024_9_27 每种字符至少取 K 个(双指针)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;每种字符至少取 K 个 代码与解题思路 func takeCharacters(s string, k int) int {// 核心思路&#xff1a;// 题目要求字符串 s 中&#xff0c;每种字符都取至少 k 个// 而且可以从头取…

腾讯一面-LRU缓存

为了设计一个满足LRU&#xff08;最近最少使用&#xff09;缓存约束的数据结构&#xff0c;我们可以使用哈希表&#xff08;HashMap&#xff09;来存储键值对&#xff0c;以便在O(1)时间复杂度内访问任意键。同时&#xff0c;我们还需要一个双向链表&#xff08;Doubly Linked …

excel统计分析(3): 一元线性回归分析

简介 用途&#xff1a;研究两个具有线性关系的变量之间的关系。 一元线性回归分析模型&#xff1a; ab参数由公式可得&#xff1a; 判定系数R2&#xff1a;评估回归模型的拟合效果。值越接近1&#xff0c;说明拟合效果越好&#xff1b;值越接近0&#xff0c;说明拟合效果越…