1.原因
我们知道传统的图片文件格式有 PNG 、 JPEG 等,这种类型的图片格式无法直接被 GPU 读取,需要先经过 CPU 解码后再上传到 GPU 使用,解码后的数据无压缩。
而纹理压缩顾名思义是一种压缩的纹理格式,它通常会将纹理划分为固定大小的块(block)或者瓦片(tile),每个块单独进行压缩,整体显存占用更低,并且能直接被 GPU 读取和渲染(无需 CPU 解码)。
2.项目技术方案
本项目选择使用basis_universal压缩图片,生成.basis文件,使用ThreeJS中basisTextureLoader加载压缩后文件。
已知basisTextureLoader加载.basis文件后,获取设备信息,将文件快速转换为适用于设备的压缩格式。如basisTextureLoader如下源码所示:
var config = this.workerConfig;
config.astcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_astc' );
config.etcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_etc1' );
config.dxtSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_s3tc' );
config.pvrtcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_pvrtc' )
|| !! renderer.extensions.get( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
if ( config.astcSupported ) {
config.format = BasisTextureLoader.BASIS_FORMAT.cTFASTC_4x4;
} else if ( config.dxtSupported ) {
config.format = BasisTextureLoader.BASIS_FORMAT.cTFBC3;
} else if ( config.pvrtcSupported ) {
config.format = BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA;
} else if ( config.etcSupported ) {
config.format = BasisTextureLoader.BASIS_FORMAT.cTFETC1;
} else {
throw new Error( 'THREE.BasisTextureLoader: No suitable compressed texture format found.' );
}
return this;
},
3.代码实现
本项目使用BasisTextureLoader加载文件
完整代码如下链接:
核心代码如下所示:
loader.setTranscoderPath( '../../public/lib/basis/' );
loader.detectSupport( renderer );
let a = new URL('../assets/textureCompression/9000.basis', import.meta.url)
loader.load( a, function ( texture ) {
texture.encoding = THREE.sRGBEncoding;
material.map = texture;
material.needsUpdate = true;
}, undefined, function ( error ) {
console.error( error );
} );
4.效果对比
项目中选择了纯白图片进行压缩
4.1 显示效果对比
压缩前:
压缩后:
4.2 图片压缩尺寸
图片压缩前大小为262KB,压缩后大小为4KB
4.3 内存对比
压缩前:
压缩后:
所以可以知道对于纯色图片,纹理压缩对于性能优化是有较好效果。
对于其他项目和设备,还需要针对项目进行多端试验,本文旨在提供一个纹理优化的思路。
参考资料
isux.tencent.com/articles/is… 如何在页面极速渲染3D模型
wow.techbrood.com/fiddle/6319… 代码参考
zhuanlan.zhihu.com/p/154425898 webgl中大场景优化
zhuanlan.zhihu.com/p/486903217 图像块压缩/纹理压缩技术细节(文献翻译)
zhuanlan.zhihu.com/p/553445757 纹理压缩
docs.egret.com/engine/docs… ktx纹理压缩
www.jianshu.com/p/a4aec9f06… ktx转换工具的使用
www.jiazhengblog.com/blog/2017/0… webgl纹理详解-纹理压缩的使用
blog.csdn.net/Taobaojishu… 内存优化:纹理压缩技术
www.wenjiangs.com/doc/qmwhjzy… BasisTextureLoader使用
zhuanlan.zhihu.com/p/561894569 webgl压缩纹理实践