void HandleSpecular(string text, RenderMaterial pbr)
        {
            glTFExtensions.KHR_materials_specular specular = Newtonsoft.Json.JsonConvert.DeserializeObject <glTFExtensions.KHR_materials_specular>(text);

            if (specular == null)
            {
                pbr.SetParameter(PhysicallyBased.Specular, 1.0);
            }
            else
            {
                if (specular.SpecularTexture != null)
                {
                    RenderTexture specularTexture = converter.GetRenderTextureFromChannel(specular.SpecularTexture.Index, RgbaChannel.Alpha);

                    pbr.SetChild(specularTexture, PhysicallyBased.Specular);
                    pbr.SetChildSlotOn(PhysicallyBased.Specular, true, RenderContent.ChangeContexts.Program);
                    pbr.SetChildSlotAmount(PhysicallyBased.Specular, specular.SpecularFactor * 100.0, RenderContent.ChangeContexts.Program);
                }
                else
                {
                    pbr.SetParameter(PhysicallyBased.Specular, specular.SpecularFactor);
                }
            }
        }
        public int AddMaterial()
        {
            // Prep
            glTFLoader.Schema.Material material = new glTFLoader.Schema.Material()
            {
                Name = renderMaterial.Name,
                PbrMetallicRoughness = new glTFLoader.Schema.MaterialPbrMetallicRoughness(),
            };

            if (!rhinoMaterial.IsPhysicallyBased)
            {
                rhinoMaterial.ToPhysicallyBased();
            }

            Rhino.DocObjects.PhysicallyBasedMaterial pbr = rhinoMaterial.PhysicallyBased;

            // Textures
            Rhino.DocObjects.Texture metallicTexture          = pbr.GetTexture(TextureType.PBR_Metallic);
            Rhino.DocObjects.Texture roughnessTexture         = pbr.GetTexture(TextureType.PBR_Roughness);
            Rhino.DocObjects.Texture normalTexture            = pbr.GetTexture(TextureType.Bump);
            Rhino.DocObjects.Texture occlusionTexture         = pbr.GetTexture(TextureType.PBR_AmbientOcclusion);
            Rhino.DocObjects.Texture emissiveTexture          = pbr.GetTexture(TextureType.PBR_Emission);
            Rhino.DocObjects.Texture opacityTexture           = pbr.GetTexture(TextureType.Opacity);
            Rhino.DocObjects.Texture clearcoatTexture         = pbr.GetTexture(TextureType.PBR_Clearcoat);
            Rhino.DocObjects.Texture clearcoatRoughessTexture = pbr.GetTexture(TextureType.PBR_ClearcoatRoughness);
            Rhino.DocObjects.Texture clearcoatNormalTexture   = pbr.GetTexture(TextureType.PBR_ClearcoatBump);
            Rhino.DocObjects.Texture specularTexture          = pbr.GetTexture(TextureType.PBR_Specular);

            HandleBaseColor(rhinoMaterial, material);

            bool hasMetalTexture     = metallicTexture == null ? false : metallicTexture.Enabled;
            bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled;

            if (hasMetalTexture || hasRoughnessTexture)
            {
                material.PbrMetallicRoughness.MetallicRoughnessTexture = AddMetallicRoughnessTexture(rhinoMaterial);

                float metallic  = metallicTexture == null ? (float)pbr.Metallic : GetTextureWeight(metallicTexture);
                float roughness = roughnessTexture == null ? (float)pbr.Roughness : GetTextureWeight(roughnessTexture);

                material.PbrMetallicRoughness.MetallicFactor  = metallic;
                material.PbrMetallicRoughness.RoughnessFactor = roughness;
            }
            else
            {
                material.PbrMetallicRoughness.MetallicFactor  = (float)pbr.Metallic;
                material.PbrMetallicRoughness.RoughnessFactor = (float)pbr.Roughness;
            }

            if (normalTexture != null && normalTexture.Enabled)
            {
                material.NormalTexture = AddTextureNormal(normalTexture);
            }

            if (occlusionTexture != null && occlusionTexture.Enabled)
            {
                material.OcclusionTexture = AddTextureOcclusion(occlusionTexture);
            }

            if (emissiveTexture != null && emissiveTexture.Enabled)
            {
                material.EmissiveTexture = AddTexture(emissiveTexture.FileReference.FullPath);

                float emissionMultiplier = 1.0f;

                var param = rhinoMaterial.RenderMaterial.GetParameter("emission-multiplier");

                if (param != null)
                {
                    emissionMultiplier = (float)Convert.ToDouble(param);
                }

                material.EmissiveFactor = new float[]
                {
                    emissionMultiplier,
                    emissionMultiplier,
                    emissionMultiplier,
                };
            }
            else
            {
                material.EmissiveFactor = new float[]
                {
                    rhinoMaterial.PhysicallyBased.Emission.R,
                    rhinoMaterial.PhysicallyBased.Emission.G,
                    rhinoMaterial.PhysicallyBased.Emission.B,
                };
            }

            //Extensions

            material.Extensions = new Dictionary <string, object>();

            //Opacity => Transmission https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_transmission/README.md

            glTFExtensions.KHR_materials_transmission transmission = new glTFExtensions.KHR_materials_transmission();

            if (opacityTexture != null && opacityTexture.Enabled)
            {
                //Transmission texture is stored in an images R channel
                //https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_transmission/README.md#properties
                transmission.TransmissionTexture = GetSingleChannelTexture(opacityTexture, RgbaChannel.Red, true);
                transmission.TransmissionFactor  = GetTextureWeight(opacityTexture);
            }
            else
            {
                transmission.TransmissionFactor = 1.0f - (float)pbr.Opacity;
            }

            material.Extensions.Add(glTFExtensions.KHR_materials_transmission.Tag, transmission);

            //Clearcoat => Clearcoat https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md

            glTFExtensions.KHR_materials_clearcoat clearcoat = new glTFExtensions.KHR_materials_clearcoat();

            if (clearcoatTexture != null && clearcoatTexture.Enabled)
            {
                clearcoat.ClearcoatTexture = AddTexture(clearcoatTexture.FileReference.FullPath);
                clearcoat.ClearcoatFactor  = GetTextureWeight(clearcoatTexture);
            }
            else
            {
                clearcoat.ClearcoatFactor = (float)pbr.Clearcoat;
            }

            if (clearcoatRoughessTexture != null && clearcoatRoughessTexture.Enabled)
            {
                clearcoat.ClearcoatRoughnessTexture = AddTexture(clearcoatRoughessTexture.FileReference.FullPath);
                clearcoat.ClearcoatRoughnessFactor  = GetTextureWeight(clearcoatRoughessTexture);
            }
            else
            {
                clearcoat.ClearcoatRoughnessFactor = (float)pbr.ClearcoatRoughness;
            }

            if (clearcoatNormalTexture != null && clearcoatNormalTexture.Enabled)
            {
                clearcoat.ClearcoatNormalTexture = AddTextureNormal(clearcoatNormalTexture);
            }

            material.Extensions.Add(glTFExtensions.KHR_materials_clearcoat.Tag, clearcoat);

            //Opacity IOR -> IOR https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior

            glTFExtensions.KHR_materials_ior ior = new glTFExtensions.KHR_materials_ior()
            {
                Ior = (float)pbr.OpacityIOR,
            };

            material.Extensions.Add(glTFExtensions.KHR_materials_ior.Tag, ior);

            //Specular -> Specular https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular

            glTFExtensions.KHR_materials_specular specular = new glTFExtensions.KHR_materials_specular();

            if (specularTexture != null && specularTexture.Enabled)
            {
                //Specular is stored in the textures alpha channel
                specular.SpecularTexture = GetSingleChannelTexture(specularTexture, RgbaChannel.Alpha, false);
                specular.SpecularFactor  = GetTextureWeight(specularTexture);
            }
            else
            {
                specular.SpecularFactor = (float)pbr.Specular;
            }

            material.Extensions.Add(glTFExtensions.KHR_materials_specular.Tag, specular);

            return(dummy.Materials.AddAndReturnIndex(material));
        }