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 (
-tc
flag, requires support forKHR_texture_basisu
). Textures can also be embedded into.bin
/.glb
output using-te
flag.
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颜色 这里就需要用到 ...
随机推荐
- 2024-05-15:用go语言,考虑一个整数 k 和一个整数 x。 对于一个数字 num, 在其二进制表示中, 从最低有效位开始, 我们计算在 x,2x,3x 等位置处设定位的数量来确定其价值。
2024-05-15:用go语言,考虑一个整数 k 和一个整数 x. 对于一个数字 num, 在其二进制表示中, 从最低有效位开始, 我们计算在 x,2x,3x 等位置处设定位的数量来确定其价值. 举 ...
- 初识上位机(上):搭建PLC模拟仿真环境
大家好,我是Edison. 作为一个工业自动化领域的程序员,不懂点PLC和上位机,貌似有点说不过去.这里我用两篇小文带你快速进入上位机开发领域.后续,我会考虑再出一个系列文章一起玩工控上位机. 什么是 ...
- windows 文件夹添加备注
1,选中希望改动的文件夹,然后右键"单击",选择"属性"按钮. 2,打开"自定义"面板,选择"更改图标",将原来的默认文 ...
- Java计算百分比保留整数
1.Java计算百分比保留整数的方法步骤 在Java中计算百分比并保留整数,通常涉及以下步骤: (1)计算原始数值与基准数值的百分比(通常使用 (原始数值 / 基准数值) * 100 的公式). (2 ...
- Immich让你从此告别百度网盘备份手机照片
一. Immich 是什么 Immich是一个开源的图片自托管服务,它能实现类似于百度网盘的照片自动备份.分类等功能,它同时提供了Web管理页面,和移动端APP,可以轻松备份手机中的照片至家庭服务器中 ...
- C#中位枚举(Flags)
在日常的开发工作当中,位枚举可能会被经常使用,如星期多选.租期多选等等,我们可以将多选字段做或运算,然后保存到数据库表的字段中,如 1 | 2 = 3(0001 | 0010 = 0011 = 3). ...
- ProcessStartInfo 类
定义 命名空间: System.Diagnostics 程序集: System.Diagnostics.Process.dll 指定启动进程时使用的一组值. C#复制 public sealed ...
- Flutter TextField开始输入中文的时候,被打断导致错误输入字母问题
一.Bug样例 建立一个web demo flutter run -d chrome --web-renderer html 出现问题: 输入中文的时候,比如打字 hao, 第一个字母h会先输入,变成 ...
- DBEAVER 23.0.2 调整SQL编辑器字体大小 ver:20240112
DBEAVER 23.0.2 调整SQL编辑器字体大小 ver:20240112 版本是:23.0.2. 菜单-窗口-首选项.用户界面-外观-颜色和字体.展开 DBeaver Font."M ...
- realtek高清晰音频管理器 WIN10
在WIN10里已经改名了: Realtek Audio Console . 在安装realtek声卡驱动后,Realtek Audio Console 会自动安装.