WebGL压缩纹理实践
0x01
本文将讲述压缩纹理在实际项目中的使用的案例。最近的一个项目是这样的:项目由于涉及到的建筑物特别多,大概有近40栋的建筑,而每一栋建筑物,又有10层楼,每层楼里面又有很多的设备。这就导致我们需要使用到大量的贴图。在实际的项目过程中,我们的客户的电脑会经常遇到webgl崩溃的情况。这就需要我们想办法来减少该项目下贴图显存和内存的占用。
下面是园区和楼层的部分截图,数据已脱敏:
首先我们可能会想到的是减少图片的尺寸。但是减少图片尺寸也是有限度的,因为图片尺寸太小的话,会影响我们最终的呈现效果。因此我们就需要想新的办法来减少这种资源的占用。
另外一种思路就是 不使用generateMipmap。 Mipmap会生成金字塔式的图片结果。生成Mipmap会多占有大概1/3的内存空间,因此不使用Mipmap会减少啊,大概1/3的内存空间。但是Mipmap是为了模型在缩小的时候能够有很好的呈现效果,因此不使用Mipmap呢,就会导致呈现质量的下降。
最终我们使用压缩纹理。
0x01 压缩纹理简介
相信对于webgl比较熟悉的同学都知道压缩纹理。
我们常用的的纹理图片,都是jpeg,png等图片格式。 这些图片本事是压缩的图片,基于压缩算法,对于文件进行了压缩,减小了文件的大小,这对于网络上的大量的图片的传输是有利的。
不过jpeg png的图片在作为贴图使用的时候,首先会转换成位图,这里所说的位图是指没有使用任何压缩算法的原始图片数据。以1024×1024为例,如果图像中每个像素需要RGB三个通道,每个通道需要8位空间,那么整张图片就需要使用1024 x 1024 x 8 x 3 位的信息,也就是3M,这3M的信息都需要加载到GPU当中,这和图片文件采用什么样的压缩格式没有任何关系。如果图像中每个像素需要rgba 四个通道,则是则需要4兆的GPU内存空间。
可以看出使用jpeg, png等图片格式的缺点是:
- 图片需要解压,这会消耗CPU的性能。
- 纹理数据占用内存较多。通常是浏览器和GPU各自保存一份位图数据。
压缩纹理正是为了解决上述的问题而出现的。通过使用压缩纹理,我们可以把像素通过压缩算法,包装成数据块,这可以减少在显存中的存储容量。 这种包装好的数据块又很方便GPU进行解压,查询。所以从性能的角度来说也提高了访问纹理的速度。
压缩文里有很多格式,比如DDS,KTX等。严格来说,DDS和kTX是一种容器而不是格式,而压缩纹理的格式是有多种。此处为了简便起见,我们就说成DDS和KTX格式,我们知道KTX有2.0的版本。而我们最终选用的也就是ktx2.0,它能够很方便的和gltf模型格式进行集成。
有关压缩纹理的更多知识,大家可以在网上搜索啊,此处不进行详细的介绍。
0x02 工作流
建模工程师给的是OBJ模型,项目最开始用的也是OBJ模型,首先我们需要把OBJ模型转换成GLTF格式。 可以使用插件obj2gltf进行转换。转换的流程大致如下:
npm install obj2gltf -g
obj2gltf -i a.obj -o a.gltf
首先通过npm安装obj2gltf。然后通过obj2gltf 进行模型的转换,其中 -i表示输入的OBJ模型。-o就是输出的gltf模型。
转换为gltf之后,通过对gltf进行压缩。其中贴图压缩的工具为一套开源的ktx工具,ktx-software,官方文档如下:
https://github.com/KhronosGroup/KTX-Software#readme
安装ktx-software之后,可以对贴图进行压缩,此处我们可以选择gltfpack(gltfpack相对比较简单,ktx-software也自带转换工具,比较复杂,但是转换的可选参数更多,能够更灵活的选择高质量还是低质量压缩纹理,有兴趣读者可以查看文档研究)。
压缩的命令大致:
gltfpack -i scene.gltf -o scene.glb --tc
其中tc是对贴图进行压缩,原文如下:gltfpack can also compress textures using Basis Universal format stored in a KTX2 container (
-tcflag, requires support forKHR_texture_basisu). Textures can also be embedded into.bin/.glboutput using-teflag.
0x03加载压缩贴图
贴图改成ktx2之后,在加载模型的时候需要对贴图进行解析,以threejs为例,加载ktx2需要指定KTX2Loader,KTX2Loader需要指定js文件“basis_transcoder”,所以需要指定basis_transcoder.js和basis_transcoder.wasm文件的路径,大致如下所示:
let ktx2Loader = new KTX2Loader(manager)
.setTranscoderPath('./')
.detectSupport(renderder)
gltfLoader.setKTX2Loader(ktx2Loader);
gltfLoader指定ktx2loader之后,就可以像加载普通gltf模型一样,加载带ktx2贴图的模型。
0x04 压缩结果对比
压缩之后,webgl程序的显存和内存占用都大幅度的降低。 整个场景的内存下降大概50%左右,效果还是很明显的。
当然降低显存,还有许多更多的手段,比如建模过程中降低模型的面数,减小贴图的尺寸,禁用mipmap,能复用的模型尽量复用等等。
结语
本文讲述了降低显存的一种手段,压缩纹理。 压缩纹理和性能优化还有更多的知识技能点,如果你有好的经验,也欢迎和我交流。关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。
WebGL压缩纹理实践的更多相关文章
- OpenGL ES 压缩纹理
什么是压缩纹理 在实际应用特别是游戏中纹理占用了相当大的包体积,而且GPU无法直接解码目前流行的图片格式,图片必须转换为RGB等类型的格式才能上传到GPU内存,这显然增加了GPU内存的占用.为了处理这 ...
- Android 使用压缩纹理
本文介绍了什么是压缩纹理,以及加载压缩纹理的核心步骤.并在 Android OpenGLES 平台上实现了压缩纹理的显示. 一.压缩纹理概念 传统的图片文件格式有 PNG . JPEG 等,这种类型的 ...
- [转]各种移动GPU压缩纹理的使用方法
介绍了各种移动设备所使用的GPU,以及各个GPU所支持的压缩纹理的格式和使用方法.1. 移动GPU大全 目前移动市场的GPU主要有四大厂商系列:1)Imagination Technologies的P ...
- 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...
- Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题
Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致& ...
- OpenGL 加载DDS文件(压缩纹理)
想必很多人都见过DDS这种文件,它是一个“图片文件”,如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/ ...
- 各种移动GPU压缩纹理的使用方法
本文系原创整理,欢迎转载,请标明链接 http://www.cnblogs.com/luming1979 有问题欢迎加qq群讨论:366239605 介绍了各种移动设备所使用的GPU,以及各个GPU所 ...
- ASP.NET Core文件压缩最佳实践
前言 在微软官方文档中,未明确指出文件压缩功能的使用误区. 本文将对 ASP.NET Core 文件响应压缩的常见使用误区做出说明. 误区1:未使用 Brotil 压缩 几乎不需要任何额外的代价,Br ...
- WebGL 与 WebGPU比对[6] - 纹理
目录 1. WebGL 中的纹理 1.1. 创建二维纹理与设置采样参数 1.2. 纹理数据写入与拷贝 1.3. 着色器中的纹理 1.4. 纹理对象 vs 渲染缓冲对象 1.5. 立方体六面纹理 1.6 ...
- WebGL入门教程(五)-webgl纹理
前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 WebGL入门教程(四)-webgl颜色 这里就需要用到 ...
随机推荐
- Garnet:微软官方基于.NET开源的高性能分布式缓存存储数据库
前言 前不久Redis宣布从 Redis 7.4 开始,将原先比较宽松的 BSD 源码使用协议修改为 RSALv2 和 SSPLv1 协议,该协议变化意味着Redis不再开源.今天给大家分享一款完全开 ...
- openstack虚拟机用keep alive添加的VIP,其它机器无法访问
neutron port-list |grep ipneutron port-update a7fbxxf6cc2 --allowed_address_pairs type=dict list=tru ...
- Django测试与持续集成:从入门到精通
title: Django测试与持续集成:从入门到精通 date: 2024/5/18 16:38:41 updated: 2024/5/18 16:38:41 categories: 后端开发 ta ...
- 生物医学顶刊论文(JBHI-2024):TransFOL:药物相互作用中复杂关系推理的逻辑查询模型
(2024.5.17)JBHI-TransFOL:药物相互作用中复杂关系推理的逻辑查询模型 论文题目:TransFOL: A Logical Query Model for Complex Relat ...
- vue多页面应用
多页面应用本身和单页面应用没什么差别,无非是多了几个入口点. 入口点多的话,还可以写个函数扫描路径取添加入口点. 比较让人好奇的是路径的问题.我们要开发的时候要体现目录层级接口,所以入口文件是一层套一 ...
- Navigator.sendBeacon()
navigator.sendBeacon() 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器. 这个方法主要用于满足统计和诊断代码的需要,这些代码通常尝试在卸载(unload ...
- group_concat 和 case when 的坑
SELECT size,instrument_id, (CASE side WHEN "sell" THEN group_concat(id ORDER BY id) END )a ...
- 资源编排ROS之模块:实现模板代码复用(进阶篇)
背景 资源编排服务(Resource Orchestration Service, 简称ROS)是阿里云提供的一项简化云计算资源管理的服务.您可以遵循ROS定义的模板规范编写资源栈模板,在模板中定义所 ...
- 使用Docker安装Odoo 17(非Docker Compose)
使用Docker安装Odoo 17(非Docker Compose) 前言 最近在学习Odoo,先是windows 安装企业版,多年不用windows的服务器操作系统,一看windows的ECS那么贵 ...
- 使用C#开发微信公众号对接ChatGPT和DALL-E
本人是一家小公司的技术总监,工作包括写市场分析.工作汇报.产品推广文案及代码开发等.在ChatGPT推出之后本人一直在工作中使用,在头脑风暴.大纲生成.语句优化.代码生成方面很有效果.但ChatGPT ...