Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where should we indicate the number of channels in BasisU data? #100

Closed
MarkCallow opened this issue Oct 2, 2019 · 6 comments · Fixed by #103
Closed

Where should we indicate the number of channels in BasisU data? #100

MarkCallow opened this issue Oct 2, 2019 · 6 comments · Fixed by #103

Comments

@MarkCallow
Copy link
Contributor

MarkCallow commented Oct 2, 2019

Basis Universal compressed data may have 2, 3 or 4 channels. The number of channels affects the choice of transcode target format so the recipient of a file needs to know the information. This could be provided within the BasisU global data or by the DFD. Which should we use?

Currently presence of an alpha channel (alpha slices) is indicated by a flag in the global data similar to the .basis format. There is nothing to indicate if there are only 2 channels either in global data or in .basis files.

From an API user's point of view, having a function on the ktxTexture object that returns the number of channels, regardless of the internal format of the ktxTexture data is clean and simple. From an implementer's point of view having that function interact with only one part of the file is simpler. So I lean toward using the DFD.

@lexaknyazev
Copy link
Member

Could we somehow store precise channel information?
Here are all source channel mappings enforced by BasisU transcoders:

One channel

Expected by BC4 and ETC2_EAC_R11.

  • Slice 1 or 2, green (source)-> red (target)

Two channels

Expected by BC5, ETC2_EAC_RG11.

  • Slice 1, green (source) -> red (target)
  • Slice 2, green (source) -> green (target); optional

Three channels

Expected by ETC1, BC1_RGB, BC7_M6_RGB, ATC_RGB, PVRTC1_4_RGB, PVRTC2_4_RGB, FXT1_RGB

  • Slice 1 or 2, RGB (source) -> RGB (target)

Four channels

Expected by BC7_M5_RGBA, ETC2_EAC_A8, BC3, ASTC, ATC_RGBA, PVRTC1_4_RGBA, PVRTC2_4_RGBA

  • Slice 1, RGB (source) -> RGB (target)
  • Slice 2, green (source) -> Alpha (target); optional

Technically, any transcoder can be used on any source data. However only some combinations would make practical sense. Also, given that one- and three-channel transcoders allow using either slice as a source, it's probably possible to store up to 6 channels in one Basis U "image level" and decode it as two RGB textures.

I think that there could be some confusion between channels of Basis U slices and channels of the decoded texture.

@MarkCallow
Copy link
Contributor Author

Two channels

...
Slice 1, green (source) -> red (target)
Slice 2, green (source) -> green (target); optional

How is this 2 channels?

Four channels

...
Slice 2, green (source) -> Alpha (target); optional

Shouldn't this be alpha (source)?

@MarkCallow
Copy link
Contributor Author

I think KTX2 should just provide information about the number of channels in the Basis compressed file and the mapping during transcoding is better specified as part of a, e.g., glTF specification.

This gives maximum flexibility for KTX2 users similar to what they have if using .basis. I suppose though that if this mapping is specified as metadata we can describe is as "recommended." so users can still do their own thing. For glTF it would be "required".

@lexaknyazev
Copy link
Member

How is this 2 channels?

After transcoding, only red and green (if the second slice was present) channels will be written for these target formats.

Shouldn't this be alpha (source)?

"source" there refers to Basis slices, not the original uncompressed image. IIUC, there's no distinction between RGB and Alpha slices in BasisU. My mention of "green" channel for getting "alpha" values from the second slice is based on the source code comments and may be inaccurate.

For glTF it would be "required".

I can certainly see two trade-offs for non-color data here, for instance:

  • With low-frequency metallic-roughness texture, one could use one RGB slice and still get acceptable results; the pipeline should treat such image data as regular RGB (with glTF default sampling from green and blue). Probably, the encoder for this case should have a mode that would exclude unused channel from internal metrics (it's a good question for Rich, btw).
  • With high-frequency metallic-roughness texture, a proper 2-channel image (with two slices) would be used and the pipeline would swizzle green-blue to red-green before performing BasisU compression. At runtime, an additional glTF extension (TBD) would be used to signal the expected channel mapping. Alternatively, we may allow KTX swizzling metadata for glTF clients (up to WG).

That new Basis-specific KTX metadata entry would inevitably be influenced by the mapping list above (to differentiate RG texture in RGB slice from RG texture in two slices).

@MarkCallow
Copy link
Contributor Author

MarkCallow commented Oct 11, 2019

After transcoding, only red and green (if the second slice was present) channels will be written for these target formats.

This didn't answer my question which stemmed from a misunderstanding, cleared up by your following answer, about the meaning of

Slice 1, green (source)
Slice 2, green (source)

Which I originally took to be saying the both slice 1 & slice 2 had the green channel from the original pre-encoding data.

During encoding the values in the RGB components will be encoded as is into slice 1 and the alpha component is swizzled into all 3 components of the slice 2, unless m_seperate_rg_to_color_alpha is set. If set, the input is expected to be RG. The R component is swizzled into all 3 channels of slice 1 and the G component into all 3 channels of slice 2.

You are correct that during transcoding Basis always uses the green component of slice 2 for alpha and when transcoding to BC5 uses the green channel of slice 1 for the R component and the green component of slice 2 for the G component of the BC5 texture. As far as I can understand from in the ETC1/ETC1S specs the green component has no more bits than R or B so there seems no particular reason for choosing green.

@MarkCallow
Copy link
Contributor Author

Please review PR #103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants