vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
454 stars 72 forks source link

Setting Specular with the MetalicRoughness shader #141

Closed Garmichael closed 2 years ago

Garmichael commented 2 years ago

I'm having trouble setting the SpecularFactor of my GTLF

I'm doing the following:

MaterialBuilder material = new MaterialBuilder();

material.AlphaMode = AlphaMode.MASK;
material.WithMetallicRoughness(0, 1);
material.WithChannelImage(KnownChannel.BaseColor, memoryImage);
material.GetChannel(KnownChannel.BaseColor)
    .Texture
    .WithSampler(
        TextureWrapMode.CLAMP_TO_EDGE,
        TextureWrapMode.MIRRORED_REPEAT,
        TextureMipMapFilter.NEAREST_MIPMAP_NEAREST,
        TextureInterpolationFilter.NEAREST
    );
material.WithSpecularFactor(memoryImage, 0);
material.WithSpecularColor(memoryImage, Vector3.Zero);

When importing into Blender, the specular is always 0.5.

What's the correct way to set the specular property?

I attached the GLTF I'm exporting.

Also I tried using the SpecularGlossiness Shader and the output look pretty bad.

MAP034.zip

Garmichael commented 2 years ago

Im sorry, I didnt mean to add the BUG label

vpenades commented 2 years ago

Before anything else, your example is missing some parts:

           var material = new MaterialBuilder()
                .WithAlpha(Materials.AlphaMode.OPAQUE); // I use Mask in my examples to show how to change the alpha, but Opaque is the default value

            material.WithMetallicRoughnessShader() // this is required to tell the material which properties are valid
                .WithMetallicRoughness(0, 1)
                .WithChannelImage(KnownChannel.BaseColor, memoryImage)
                .UseChannel(KnownChannel.BaseColor)    // UseChannel instead of GetChannel (which is used for read only)
                    .Texture
                    .WithSampler(
                        TextureWrapMode.CLAMP_TO_EDGE,
                        TextureWrapMode.MIRRORED_REPEAT,
                        TextureMipMapFilter.NEAREST_MIPMAP_NEAREST,
                        TextureInterpolationFilter.NEAREST
                    );

            material
                .WithSpecularFactor(memoryImage, 0)
                .WithSpecularColor(memoryImage, Vector3.Zero);

The output of the example looks like this:

{
  "asset": {
    "copyright": "",
    "generator": "SharpGLTF 1.0.0",
    "version": "2.0"
  },
  "images": [
    {}
  ],
  "materials": [
    {
      "extensions": {
        "KHR_materials_specular": {    <- extension
          "specularColorFactor": [     <- color
            0,
            0,
            0
          ],
          "specularColorTexture": {
            "index": 1
          },
          "specularFactor": 0,  <- factor
          "specularTexture": {
            "index": 1
          }
        }
      },
      "pbrMetallicRoughness": {
        "baseColorTexture": {
          "index": 0
        },
        "metallicFactor": 0
      }
    }
  ],
  "samplers": [
    {
      "magFilter": 9728,
      "minFilter": 9984,
      "wrapS": 33071,
      "wrapT": 33648
    }
  ],
  "textures": [
    {
      "sampler": 0,
      "source": 0
    },
    {
      "source": 0
    }
  ]
}

As you can see, the SpecularColor and SpecularFactor have been correctly written into the KHR_materials_specular extension.

So why it's failing in blender? most probably because the importer you're using in Blender doesn't support that extension yet. In other words: you should report this issue to the gltf plugin importer you're using.