donmccurdy / glTF-Transform

glTF 2.0 SDK for JavaScript and TypeScript, on Web and Node.js.
https://gltf-transform.dev
MIT License
1.39k stars 149 forks source link

GPU memory size calculation optimization #424

Closed LoJunKai closed 2 years ago

LoJunKai commented 2 years ago

Is your feature request related to a problem? Please describe. In the calculation of getMemSize(), to account for mipmapping, the texture is summed over all mipmap sizes down to 1x1px.

Describe the solution you'd like The calculation done is essentially the sum of geometric series, and can just be replaced by a multiplication of 4/3 as an optimization to calculate the final amount.

Just an additional question, I am wondering for textures that are metallicRoughnessTexture or normalTexture or occlusionTexture, is the use of channels = 4 still justified? It seems like these textures are not RGB.

donmccurdy commented 2 years ago

Hi! While it's the sum of a geometric series for square textures, it is a bit more complicated if the texture isn't square I think. Since texture dimensions >214 are very rare, the loop iterations are bounded enough that this shouldn't be a problem for performance in practice.

Just an additional question, I am wondering for textures that are metallicRoughnessTexture or normalTexture or occlusionTexture, is the use of channels = 4 still justified? It seems like these textures are not RGB.

Unfortunately there's no perfect answer — the real size depends on the device and drivers, see https://github.com/donmccurdy/glTF-Transform/issues/151. I think it's best to be conservative and assume that PNG and JPEG textures will be expanded in GPU memory to RGBA8. For GPU compressed texture formats (KTX2 with Basis Universal), single-channel textures will benefit from a reduced memory footprint as you'd expect, and the inspect function does account for those.