gltf-rs / gltf

A crate for loading glTF 2.0
Apache License 2.0
534 stars 124 forks source link

image data formats #371

Closed stefnotch closed 1 year ago

stefnotch commented 1 year ago

When one has an image data struct with a format like Format::R8G8B8, how should the bytes be interpreted?

Are they linear values between 0 and 255, or are they sRGB values between 0 and 255.

I'm asking, since the source code indicates that DynamicImage from the image crate is being used https://github.com/gltf-rs/gltf/blob/69caa857827f534f3f5deade83b37f5b407d79d0/src/image.rs#L146 which defines RgbImage, which might be in sRGB space https://docs.rs/image/latest/image/struct.Rgb.html ?

alteous commented 1 year ago

Hi, good question! It seems no conversion is performed by the PNG decoder, so it is unspecified. The glTF spec says:

Any colorspace information (such as ICC profiles, intents, gamma values, etc.) from PNG or JPEG images MUST be ignored. Effective transfer function (encoding) is defined by a glTF object that refers to the image (in most cases it’s a texture that is used by a material).

So my understanding is the colour space is defined/implied elsewhere, such as the metallic-roughness material.

The base color texture MUST contain 8-bit values encoded with the sRGB opto-electronic transfer function so RGB values MUST be decoded to real linear values before they are used for any computations. To achieve correct filtering, the transfer function SHOULD be decoded before performing linear interpolation.

The textures for metalness and roughness properties are packed together in a single texture called metallicRoughnessTexture. Its green channel contains roughness values and its blue channel contains metalness values. This texture MUST be encoded with linear transfer function and MAY use more than 8 bits per channel.

Is this helpful?

stefnotch commented 1 year ago

Thank you for that detailed response!

So, I suppose simply assuming that color textures are sRGB, and metalness textures are linear should be fine.

Apparently the documentation actually does mention that https://docs.rs/gltf/latest/gltf/material/struct.PbrMetallicRoughness.html#method.base_color_texture . So I can probably close this issue. Thank you very much!

Any colorspace information (such as ICC profiles, intents, gamma values, etc.) from PNG or JPEG images MUST be ignored.

I think it's a odd that the gltf specification goes out of its way to ignore that information, but I guess that's not too bad to deal with. Time to figure out how to get my image editors to behave accordingly. :)