0x01
This article will describe the use of compressed textures in real projects. A recent project is like this: The project involves a lot of buildings, about 40 buildings, and each building has 10 floors, and each floor has a lot of equipment. This leads us to use a lot of textures. During the actual project process, our clients' computers often encounter webgl crashes. This requires us to find a way to reduce the texture and memory usage under the project.
The following are some screenshots of the campus and floors, the data has been desensitized:
The first thing we might think of is to reduce the size of the image. However, there is a limit to reducing the image size, because if the image size is too small, it will affect our final rendering effect. Therefore, we need to think of new ways to reduce the occupancy of this resource.
Another idea is to not use generateMipmap. Mipmap will generate pyramidal image results. Generating a mipmap will occupy about 1/3 of the memory space, so not using a mipmap will reduce it, about 1/3 of the memory space. However, Mipmap is for the model to have a good rendering effect when it is reduced, so not using Mipmap will lead to a decrease in rendering quality.
In the end we use compressed textures.
0x01 Introduction to Compressed Textures
I believe that students who are familiar with webgl know about compressed textures.
The texture images we commonly use are in jpeg, png and other image formats. These pictures are compressed pictures. Based on the compression algorithm, the files are compressed and the file size is reduced, which is beneficial for the transmission of a large number of pictures on the network.
However, when a jpeg png image is used as a texture, it will first be converted into a bitmap. The bitmap mentioned here refers to the original image data without any compression algorithm. Taking 1024×1024 as an example, if each pixel in the image requires three RGB channels, and each channel requires 8-bit space, then the entire image needs to use 1024 x 1024 x 8 x 3 bits of information, which is 3M, which is All 3M information needs to be loaded into the GPU, which has nothing to do with the compression format of the image file. If each pixel in the image requires four channels of rgba, then 4 megabytes of GPU memory space is required.
It can be seen that the disadvantages of using image formats such as jpeg and png are:
- Images need to be decompressed, which consumes CPU performance.
- Texture data takes up a lot of memory. Usually the browser and GPU each save a bitmap data.
Compressed textures appear to solve the above problems. By using compressed textures, we can pack pixels into data blocks through a compression algorithm, which can reduce the storage capacity in video memory. This packaged data block is very convenient for GPU to decompress and query. So from a performance point of view, the speed of accessing textures is also improved.
There are many formats in the compressed file, such as DDS, KTX, etc. Strictly speaking, DDS and kTX are a container rather than a format, and there are multiple formats for compressed textures. For the sake of simplicity, we will say DDS and KTX formats, we know that KTX has a 2.0 version. And we finally chose ktx2.0, which can be easily integrated with the gltf model format.
For more knowledge about compressed textures, you can search on the Internet, and will not be introduced in detail here.
0x02 Workflow
The modeling engineer gave the OBJ model, and the project also used the OBJ model at the beginning. First, we need to convert the OBJ model into GLTF format. The conversion can be done using the plugin obj2gltf. The conversion process is roughly as follows:
npm install obj2gltf -g
obj2gltf -i a.obj -o a.gltf
First install obj2gltf via npm. Then convert the model through obj2gltf, where -i represents the input OBJ model. -o is the output gltf model.
After converting to gltf, by compressing the gltf. The tool for texture compression is a set of open source ktx tools, ktx-software. The official documents are as follows:
https://github.com/KhronosGroup/KTX-Software#readme
After installing ktx-software, you can compress the textures. Here we can choose gltfpack (gltfpack is relatively simple, ktx-software also comes with a conversion tool, which is more complicated, but there are more optional parameters for conversion, which can be more flexible. High-quality or low-quality compressed textures, interested readers can check the documentation).
The compressed command is roughly:
gltfpack -i scene.gltf -o scene.glb --tc
Where tc is to compress textures, the original text is as follows: 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 Load compressed texture
After the texture is changed to ktx2, the texture needs to be parsed when loading the model. Taking threejs as an example, when loading ktx2, you need to specify KTX2Loader, and KTX2Loader needs to specify the js file "basis_transcoder", so you need to specify the path of the basis_transcoder.js and basis_transcoder.wasm files. , roughly as follows:
let ktx2Loader = new KTX2Loader(manager)
.setTranscoderPath('./')
.detectSupport(renderder)
gltfLoader.setKTX2Loader(ktx2Loader);
After gltfLoader specifies ktx2loader, the model with ktx2 texture can be loaded like normal gltf model.
0x04 Comparison of compression results
After compression, the video memory and memory usage of the webgl program are greatly reduced. The memory of the entire scene drops by about 50%, and the effect is still obvious.
Of course, there are many more ways to reduce the video memory, such as reducing the number of faces of the model during the modeling process, reducing the size of the texture, disabling mipmaps, and reusing the models that can be reused as much as possible.
Epilogue
This article describes a means of reducing video memory, compressing textures. There are more knowledge and skill points for compressed textures and performance optimization. If you have good experience, you are also welcome to communicate with me. Follow the official account "ITMan Biao Shu", you can add the author's WeChat to communicate, and receive more valuable articles in time.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。