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

ModelExperimental - Default material #9992

Closed
ptrgags opened this issue Jan 5, 2022 · 8 comments · Fixed by #10476
Closed

ModelExperimental - Default material #9992

ptrgags opened this issue Jan 5, 2022 · 8 comments · Fixed by #10476
Assignees

Comments

@ptrgags
Copy link
Contributor

ptrgags commented Jan 5, 2022

According to the glTF spec,

If material is undefined, then a default material MUST be used.

The "default material" is described here: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#default-material

This should be easy to handle, there's a couple things to check:

  • Ensure that the MaterialPipelineStage doesn't throw an error if primitive.material is undefined. A no-op is probably okay
  • Ensure that the shader defaults match what is described in the spec
  • find a model to test with
@j9liu
Copy link
Contributor

j9liu commented Jun 10, 2022

@ptrgags and I found that gltf-pipeline creates a default material, but we should make sure that for other things loaded as ModelExperimental that a default is created, and that the shader defaults are as expected.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jun 10, 2022

I confirmed that GeoJsonLoader and PntsLoader do create a default material.

However, I think defaultModelMaterial() in ModelExperimentalFS.glsl isn't quite matching the spec.

According to the spec, default material should have:

  • metallic: 1
  • roughness: 1
  • baseColor: [1, 1, 1, 1]

In other words it should be a metallic but rough material, whereas the shader currently defaults to a smooth non-metal.

@j9liu
Copy link
Contributor

j9liu commented Jun 10, 2022

@ptrgags From a glance it doesn't seem like the material struct for ModelExperimental has a metallic factor, and that the other fields (f0, diffuseColor, roughness) are derived from the metallic factor in czm_pbrMetallicRoughnessMaterial. Should this be invoked with the default metallic roughness values in defaultModelMaterial() ?

EDIT: Actually, we can just hard-code the values based on how they would be computed in czm_pbrMetallicRoughnessMaterial, that would be simpler

@ptrgags
Copy link
Contributor Author

ptrgags commented Jun 10, 2022

I agree, hardcode the computed values. I think they'll all turn out to be straightforward constants like vec3(1.0) but better safe to check

@lilleyse
Copy link
Contributor

Technically we can use whatever default we want in ModelExperimental but it's good to be consistent. I get these values:

czm_modelMaterial defaultModelMaterial()
{
    czm_modelMaterial material;
    material.diffuse = vec3(0.0);
    material.specular = vec3(1.0);
    material.roughness = 1.0;
    material.occlusion = 1.0;
    material.normalEC = vec3(0.0, 0.0, 1.0);
    material.emissive = vec3(0.0);
    material.alpha = 1.0;
    return material;
}
@jjhembd
Copy link
Contributor

jjhembd commented Jun 22, 2022

Hi @ptrgags, I'm looking at this and have a couple questions.

I confirmed that GeoJsonLoader and PntsLoader do create a default material.

Is there anywhere else I need to check to make sure we always get a default material?

Also, in PntsLoader, I see this:

  const metallicRoughness = new MetallicRoughness();
  metallicRoughness.metallicFactor = 0;
  metallicRoughness.roughnessFactor = 0.9;

  const material = new Material();
  material.metallicRoughness = metallicRoughness;

Based on the spec, do we need to set metallicFactor = 1.0 and roughnessFactor = 1.0?

This is my first time looking through the code, so let me know if I'm misunderstanding the context here.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jun 22, 2022

Hi @jjhembd,

Is there anywhere else I need to check to make sure we always get a default material?

At this point I think it's really just ModelExperimentalFS.glsl that needs to be updated since that's hard-coding defaults in the shader.

As far as the ModelComponents.Material() goes, I think we covered all the main cases in the above discussion, but I guess it doesn't hurt to do a search through the code for ModelComponents.Material ModelComponents.MetallicRoughness and ModelComponents.SpecularGlossiness to double check nothing is hard-coding an unexpected default.

Also, in PntsLoader...

That's a good question... .pnts not technically a glTF file in the first place (unlike .b3dm and .i3dm which wrap a .glb file). So I don't think this particular case has a correct answer, it's more about what we think looks good as a default. Might be good to compare Model vs ModelExperimental rendering the same .pnts model and try to make them match.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jun 22, 2022

Oh @jjhembd here's A modified Sandcastle example that sets up the default material. Basically I (ab)used a CustomShader's REPLACE_MATERIAL mode so the material is set to the default rather than what was in the glTF.

The relevant code is this part

// Modified this shader to use the default material
const textureUniformShader = new Cesium.CustomShader({
  lightingModel: Cesium.LightingModel.PBR,
  mode: Cesium.CustomShaderMode.REPLACE_MATERIAL,
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
    {
    }
    `,
});

EDIT: Also note that the lighting looks weird for the default material since the normal is set to a constant +z direction. This was mainly because we haven't implemented #6506

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants