Create RawTexture2DArray with full mipmap chain compressed texture

This is a follow up question of the previous one:

Context: I was using dxt5 compressed textures (a number of .dds files) to render my terrain. For simplicity, I was only taking mip level 0 data from those textures and combined them together. It worked after the fix. Now I want to use the full mipmap chain.

One thing I suddenly noticed was that “RawTexture” and “RawTexture2DArray” are meant to be uncompressed by design. There are clues like in the documentation:

Raw texture can help creating a texture directly from an array of data. This can be super useful if you either get the data from an uncompressed source or if you wish to create your texture pixel by pixel.

And in the code of ThinWebGPUEngine.prototype.updateRawTexture the mip level is a fixed 0.

On the other hand, I can see there are multiple TODOs mentioning to “separate generateMipMaps and useMipMaps in InternalTexture”. Without touching InternalTexture, I currently just monkey patched ThinWebGPUEngine.updateRawTexture2DArray as a temporary solution.

My questions are,

  1. Is “RawTexture2DArray” the right place for compressed, full mipmaps chain textures? Am i missing something?
  2. I was trying to add “useMipMaps” option but there seems to be a huge amount interface changes. It is feasible but I am not sure if my fix will cause compatibility issue. I want to know your opinions and if possible, some guidance.

Thanks!

Allowing users to provide their own mipmap textures has been on our to-do list for quite some time, but it is not a high priority.

Would you like to give it a try and create a PR for it?

I think we could simply add a new mipLevel parameter to all updateRawXXX methods.

Sorry Evgeni, I wasn’t able to reply in last few days. Now I’m working on it. But it seems there are plenty of trade-offs I need to decide.

  1. Adding mipLevel to engine.updateRawXXX works. It requires:
  • modify engine.createRawXXX signature to have either a mipLevelCount: number or useMipMaps: boolean . If a number is provided, we can have a subset of mipmaps as well.
  • modify AbstractEngine so that all engine share same signature . I am not too sure about this. Currently I am focusing on the WebGPU side. I might leave a unused optional parameter in the WebGL side in the first PR.
  • create a new instance method in RawXXX class to update data for certain mip level.
  • add a new mipmaps:ArrayBufferView[] field in InternalTexture to store the reference if need to handle context lost.
  1. I also have an idea to make data to accept data: Nullable<ArrayBufferView | ArrayBufferView[]> during both creating and updating. In this way, the interface has less changes than the previous one but other code that implicitly relying on texture._bufferView being a TypedArray will broke.

I will go for option1 first. And see if the result really match my expectation.
Sorry again for the late reply.

No worries, we’re in no rush :).

I think adding a count is more future-proof.

Yes, we should update AbstractEngine as we will want to support the feature in WebGL.

Why not adding an optional mipLevel parameter to the existing updateRawXXX functions?

Yes, we will need it. Also, InternalTexture._rebuild will have to be updated accordingly.

Thank you for the detailed guidance!

2 Likes