vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
467 stars 75 forks source link

pbrSpecularGlossiness sample? #45

Closed bertt closed 4 years ago

bertt commented 4 years ago

Hi, is there maybe an example available how to use pbrSpecularGlossiness shaders? For example to create 'best practice' json https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness#best-practices

{
    "materials": [
        {
            "name": "gold",
            "pbrMetallicRoughness": {
                "baseColorfactor": [ 1.0, 0.766, 0.336, 1.0 ],
                "roughnessFactor": 0.1
            },
            "extensions": {
                "KHR_materials_pbrSpecularGlossiness": {
                    "diffuseFactor": [ 0.0, 0.0, 0.0, 1.0 ],
                    "specularFactor": [ 1.0, 0.766, 0.336 ],
                    "glossinessFactor": 0.9
                }
            }
        }
    ]
}
vpenades commented 4 years ago

If you're using the Toolkit's MaterialBuilder framework, you can set a fallback material.

So let's say you want to create a material that has a main "specular glossiness" material, and a "metallic roughness" fallback material that will be used if specular glossiness is not available.

var fallback = new Materials.MaterialBuilder("material1 fallback")
                .WithMetallicRoughnessShader();

var primary = new Materials.MaterialBuilder("material1 primary")
                .WithSpecularGlossinessShader()
                .WithFallback(fallback) // sets "fallback" material for this material.

And then you use the "primary" material with MeshBuilders.

There's also a unit test here.

bertt commented 4 years ago

ok good tip, didn't know about the Fallback option. Should I use WithChannelParam() for specifying the diffuseFactor, specularFactor and glossinessFactor ?

vpenades commented 4 years ago

Yes, you can follow this chart for filling the channel parameters.

Also, notice this should also work for the new Coated Material, which is already supported by the latest version of the library... although I could not test it throughfully...

bertt commented 4 years ago

One question about using EmissiveFactor, when I do:

var material1 = new MaterialBuilder()
      .WithDoubleSide(true)
      .WithMetallicRoughnessShader()
      .WithChannelParam(KnownChannel.BaseColor, new Vector4(0.7f, 0, 0f, 1.0f))
      .WithEmissive(new Vector3(0.2f, 0.3f, 0.1f));

Result glTF is:

      "emissiveFactor": [
        1,
        1,
        1
      ],

I'm expecting 0.2, 0.3, 0.1 here. Same behaviour when doing:

.WithChannelParam(KnownChannel.Emissive, new Vector4((float)0.2, (float)0.3, (float)0.1, (float)0));
vpenades commented 4 years ago

It's indeed a bug, and a a critical one, related to the vector min/max clamps.

This is my fault since I have not been able to do proper tests for every single method. The current codebase is massive and it could take quite a lot of time to do a proper coverage test.

I'll fix it and I will upload new packages to nuget along the day.

bertt commented 4 years ago

ok thanks for looking into it!

vpenades commented 4 years ago

I've commited some improvements and API changes... the whole MaterialBuilder framework was more buggy than I expected, so I had to rewrite some code. I'm still not 100% confident, so I'll keep writing more unit tests for a few days before uploading new packages.

In the meantime, if you could use the latest changes directly, it could help me identify any other bug or use case.

bertt commented 4 years ago

ok I've tested the above case with the latest MaterialBuilder code and it works now as expected :-)