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

Spec fails to describe occlusion packed into metallicRoughness texture #1982

Closed
tim-rex opened this issue May 11, 2021 · 8 comments
Closed

Comments

@tim-rex
Copy link

tim-rex commented May 11, 2021

I'm a little confused at the minute, this page very clearly describes the idea of an occlusion texture being packed into the metallic-roughness texture.

The spec seems to make no mention of this, but does define a seperate occlusion texture.

I see issue #857 saw fit to make changes to accomodate packing occlusion into the metallic-roughness texture.
Is it simply that this remains undocumented?

There is a comment here that mentions this is documented in the schema... The link to the schema in that comment is broken, and the only schema documentation I can find (here) continues to make no mention.

I guess I want to know:

  • How should I determine if occlusion data is baked into the metallic-roughness texture?
  • Would a metallic-roughness workflow ever define a seperate occlusion texture?
  • Is it an error for a metallic-roughness workflow to define occlusion in both the metallic-roughness texture as well as a seperate occlusion texture?
@lexaknyazev
Copy link
Member

Occlusion is always sampled from the red channel while metall-roughness uses green and blue.

Separate storage example:

"images": [
    {
        "uri": "occlusion.png"
    },
    {
        "uri": "m-r.png",
    }
],
"textures": [
    {
        "source": 0
    },
    {
        "source": 1
    }
],
"materials": [
    {
        "occlusionTexture": {
            "index": 0
        },
        "pbrMetallicRoughness": {
            "metallicRoughnessTexture": {
                "index": 1
            }
        }
    }
]

Combined storage example:

"images": [
    {
        "uri": "o-r-m.png"
    }
],
"textures": [
    {
        "source": 0
    }
],
"materials": [
    {
        "occlusionTexture": {
            "index": 0
        },
        "pbrMetallicRoughness": {
            "metallicRoughnessTexture": {
                "index": 0
            }
        }
    }
]

Is it an error for a metallic-roughness workflow to define occlusion in both the metallic-roughness texture as well as a separate occlusion texture?

It is not an error. The red channel of the metallic-roughness texture would be ignored by design if occlusionTexture property points to another texture.

@donmccurdy
Copy link
Contributor

donmccurdy commented May 11, 2021

A few additional comments — the specification has no requirements about what can or cannot be packed into a single texture, other than colorspace requirements: e.g.baseColorTexture must be sRGB, normalTexture must be linear, so these cannot be combined.

For another example...

{
    "name": "MyMaterial",
    "pbrMetallicRoughness": {
        "baseColorTexture": {
            "index": 10,
            "texCoord": 0
        },
        "metallicRoughnessTexture": {
            "index": 11,
            "texCoord": 1
        }
    },
    "emissiveTexture": {
        "index": 10,
        "texCoord": 2
    },
    "occlusionTexture": {
        "index": 11,
        "texCoord": 1
    }
}

... note that baseColorTexture and emissiveTexture refer to texture 10, and metallicRoughnessTexture and occlusionTexture refer to texture 11. This is valid and plausible:

  • occlusionTexture uses the R channel, metallicRoughnessTexture uses GB channels. Both are linear.
  • baseColorTexture uses texCoord 0 in this sample, emissiveTexture uses texCoord 2, so they may refer to different parts of the same texture, e.g. in a texture atlas. Both are sRGB.

Having each property use a separate texture would also be valid. Certain extensions (e.g. KHR_materials_clearcoat) define new material properties, which can similarly be packed into shared textures. The packing flexibility is helpful when optimizing a model to meet sampler and GPU memory requirements.

@tim-rex
Copy link
Author

tim-rex commented May 12, 2021

Brilliant, thank you both. That's very helpful.

I suspect it is safe and reasonable to conclude then, that where no explicit occlusion texture index is defined, that there should be no expectation (implicit or otherwise) of it being packed into the metallicRoughnessTexture?

Eg:

    "name": "MyMaterial",
    "pbrMetallicRoughness": {
        "baseColorTexture": {
            "index": 10,
            "texCoord": 0
        },
        "metallicRoughnessTexture": {
            "index": 11,
            "texCoord": 1
        }
    }
}

@donmccurdy
Copy link
Contributor

Correct, yes — even if there happens to be data in the R channel of the metallicRoughnessTexture image, an implementation should not attempt to treat it as occlusion information unless indicated by an occlusionTexture pointer.

@tim-rex
Copy link
Author

tim-rex commented May 13, 2021

One more question if I may....
Is it odd that many (all?) of the textures defined for VC.gltf are defined for both pbr_metallic_roughness_base_color and for occlusion?

        {
            "pbrMetallicRoughness": {
                "baseColorTexture": {
                    "index": 14
                },
                "metallicFactor": 0.0
            },
            "emissiveFactor": [
                0.0,
                0.0,
                0.0
            ],
            "occlusionTexture": {
                "index": 14
            },
            "name": "Material__10539"
        },

That means the red channel of the base-colour is performing double-duty as occlusion... perhaps that just stylistic intent?

@donmccurdy
Copy link
Contributor

Hm, that wouldn't be correct, since the occlusion texture is supposed to be linear... There have been some other issues with this particular model (see KhronosGroup/glTF-Sample-Assets#71 and KhronosGroup/COLLADA2GLTF#146) probably related to tricky conversion from an older format, I would consider that a bug in the model.

@donmccurdy
Copy link
Contributor

Oops, just saw you already commented in that thread back in 2020 as well! 😅

@tim-rex
Copy link
Author

tim-rex commented May 13, 2021

Thanks Don. I suspected that might be the case. Good to know.

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

No branches or pull requests

3 participants