Extend ImageLoader interface with texture channel mask.#820
Conversation
…d extend ImageLoader interface.
|
Thanks for the contribution! May I ask you to target either branch Do you mind elaborating the concept a bit further to me? I need a better understanding of the subject first. Expanding on your example, a texture that's used as an occlusion map only could get loaded into Does that work in conjunction with compressed formats? For example how to transcode a Basis Universal supercompressed texture with a non-RGBA mask? How does it influence picking a transcode format? Code itself, on a first glimpse, looks good. May I suggest a more idiomatic alternative to the namespace UnityEngine.Rendering;
/// <summary>
/// <para>Specifies which color components will get written into the target framebuffer.</para>
/// </summary>
[Flags]
public enum ColorWriteMask
{
/// <summary>
/// <para>Write alpha component.</para>
/// </summary>
Alpha = 1,
/// <summary>
/// <para>Write blue component.</para>
/// </summary>
Blue = 2,
/// <summary>
/// <para>Write green component.</para>
/// </summary>
Green = 4,
/// <summary>
/// <para>Write red component.</para>
/// </summary>
Red = 8,
/// <summary>
/// <para>Write all components (R, G, B and Alpha).</para>
/// </summary>
All = Red | Green | Blue | Alpha, // 0x0000000F
}Again, thanks for the effort! |
No problem, I'll open a PR on that repo.
That's right.
The most optimal solution would be to use In practice the simplest approach would be to use the
In the context of runtime compression this is extremely useful. Having this information allows much more optimal format selection. For example, R-only textures can be encoded in BC4 or EAC. RGB-only textures can use BC1/ETC which is half the size as ASTC/BC7. Even when targeting the same format, knowing what subset of the channels is used allows the use of more efficient, higher quality encoders.
What to do with the mask is up to the implementation of the loader interface. The only requirement is that the resulting texture has storage for the channels specified in the mask. When transcoding KTX files you want to take other factors into consideration. An UASTC file transcodes to ASTC much more efficiently than to EAC_RG, so in some way the preferred target format is decided when the KTX file is compressed, not when it's loaded. On the other hand, when loading a JPEG or an AVIF file having a mask allows you to specify the most efficient target format, whether it's compressed or not.
I chose byte to avoid introducing new types, but I can certainly use an enum. |
This API extends the
ITextureImageLoaderinterface with a new overload of theLoadImagemethod that also takes anint channelMaskargument. This is a bitmask that indicates what channels of the texture are consumed by the material.The default implementation forwards calls to the original
LoadImagemethod, so existing implementations are unaffected.Computing the texture channel masks is trivial. It only requires traversing the materials and tagging the textures based on the slots in which the texture is used. This is similar to the way we currently tag sRGB textures.
Motivation:
When loading textures it's often possible to chose the storage format based on how the texture is used. For example, a texture that is only bound as an occlusion map only uses the R channel, but the input file may be decoded in RGBA format and consume 4x more video memory than required.
This contribution is sponsored by Ludicon.