Ejemplo n.º 1
0
        public UnityEngine.Material GenerateMaterial(Schema.Material gltfMaterial, Schema.Texture[] textures, Texture2D[] images, List <UnityEngine.Object> additionalResources)
        {
            var material = Material.Instantiate <Material>(GetDefaultMaterial());

            material.name = gltfMaterial.name;

            material.mainTextureScale  = TEXTURE_SCALE;
            material.mainTextureOffset = TEXTURE_OFFSET;

            //added support for KHR_materials_pbrSpecularGlossiness
            if (gltfMaterial.extensions != null)
            {
                Schema.PbrSpecularGlossiness specGloss = gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness;
                if (specGloss != null)
                {
                    if (!specularSetupShader)
                    {
                        specularSetupShader = Shader.Find("Standard (Specular setup)");
                    }
                    material.shader = specularSetupShader;
                    var diffuseTexture = GetTexture(specGloss.diffuseTexture, textures, images);
                    if (diffuseTexture != null)
                    {
                        material.mainTexture = diffuseTexture;
                    }
                    else
                    {
                        material.color = specGloss.diffuseColor;
                    }
                    var specGlossTexture = GetTexture(specGloss.specularGlossinessTexture, textures, images);
                    if (specGlossTexture != null)
                    {
                        material.SetTexture(StandardShaderHelper.specGlossMapPropId, specGlossTexture);
                        material.EnableKeyword("_SPECGLOSSMAP");
                    }
                    else
                    {
                        material.SetVector(StandardShaderHelper.specColorPropId, specGloss.specularColor);
                        material.SetFloat(StandardShaderHelper.glossinessPropId, (float)specGloss.glossinessFactor);
                    }
                }

                Schema.MaterialUnlit unlitMaterial = gltfMaterial.extensions.KHR_materials_unlit;
                if (unlitMaterial != null)
                {
                    if (gltfMaterial.pbrMetallicRoughness != null)
                    {
                        if (!unlitShader)
                        {
                            unlitShader = Shader.Find("Unlit/Color");
                        }
                        material.shader = unlitShader;
                    }
                }
            }

            if (gltfMaterial.pbrMetallicRoughness != null)
            {
                material.color = gltfMaterial.pbrMetallicRoughness.baseColor;
                material.SetFloat(StandardShaderHelper.metallicPropId, gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.SetFloat(StandardShaderHelper.glossinessPropId, 1 - gltfMaterial.pbrMetallicRoughness.roughnessFactor);

                var mainTxt = GetTexture(gltfMaterial.pbrMetallicRoughness.baseColorTexture, textures, images);
                if (mainTxt != null)
                {
                    mainTxt.wrapMode     = TextureWrapMode.Clamp;
                    material.mainTexture = mainTxt;
                }

                var metallicRoughnessTxt = GetTexture(gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture, textures, images);
                if (metallicRoughnessTxt != null)
                {
                    Profiler.BeginSample("ConvertMetallicRoughnessTexture");
                    // todo: Avoid this conversion by switching to a shader that accepts the given layout.
                    Debug.LogWarning("Convert MetallicRoughnessTexture structure to fit Unity Standard Shader (slow operation).");
                    var newmrt = new UnityEngine.Texture2D(metallicRoughnessTxt.width, metallicRoughnessTxt.height);
#if DEBUG
                    newmrt.name = string.Format("{0}_metal_smooth", metallicRoughnessTxt.name);
#endif
                    var buf = metallicRoughnessTxt.GetPixels32();
                    for (int i = 0; i < buf.Length; i++)
                    {
                        // TODO: Reassure given space (linear) is correct (no gamma conversion needed).
                        var color = buf[i];
                        color.a = (byte)(255 - color.g);
                        color.r = color.g = color.b;
                        buf[i]  = color;
                    }
                    newmrt.SetPixels32(buf);
                    newmrt.Apply();
                    Profiler.EndSample();

                    material.SetTexture(StandardShaderHelper.metallicGlossMapPropId, newmrt);
                    material.EnableKeyword("_METALLICGLOSSMAP");

                    additionalResources.Add(newmrt);
                }
            }

            var normalTxt = GetTexture(gltfMaterial.normalTexture, textures, images);
            if (normalTxt != null)
            {
                material.SetTexture(StandardShaderHelper.bumpMapPropId, normalTxt);
                material.EnableKeyword("_NORMALMAP");
            }

            var occlusionTxt = GetTexture(gltfMaterial.occlusionTexture, textures, images);
            if (occlusionTxt != null)
            {
                Profiler.BeginSample("ConvertOcclusionTexture");
                // todo: Avoid this conversion by switching to a shader that accepts the given layout.
                Debug.LogWarning("Convert OcclusionTexture structure to fit Unity Standard Shader (slow operation).");
                var newOcclusionTxt = new UnityEngine.Texture2D(occlusionTxt.width, occlusionTxt.height);
#if DEBUG
                newOcclusionTxt.name = string.Format("{0}_occlusion", occlusionTxt.name);
#endif
                var buf = occlusionTxt.GetPixels32();
                for (int i = 0; i < buf.Length; i++)
                {
                    var color = buf[i];
                    color.g = color.b = color.r;
                    color.a = 1;
                    buf[i]  = color;
                }
                newOcclusionTxt.SetPixels32(buf);
                newOcclusionTxt.Apply();
                Profiler.EndSample();

                material.SetTexture(StandardShaderHelper.occlusionMapPropId, newOcclusionTxt);

                additionalResources.Add(newOcclusionTxt);
            }

            var emmissiveTxt = GetTexture(gltfMaterial.emissiveTexture, textures, images);
            if (emmissiveTxt != null)
            {
                material.SetTexture(StandardShaderHelper.emissionMapPropId, emmissiveTxt);
                material.EnableKeyword("_EMISSION");
            }

            if (gltfMaterial.alphaModeEnum == AlphaMode.MASK)
            {
                material.SetFloat(StandardShaderHelper.cutoffPropId, gltfMaterial.alphaCutoff);
                StandardShaderHelper.SetAlphaModeMask(material, gltfMaterial);
            }
            else if (gltfMaterial.alphaModeEnum == AlphaMode.BLEND)
            {
                StandardShaderHelper.SetAlphaModeBlend(material);
            }
            else
            {
                StandardShaderHelper.SetOpaqueMode(material);
            }

            if (gltfMaterial.emissive != Color.black)
            {
                material.SetColor("_EmissionColor", gltfMaterial.emissive);
                material.EnableKeyword("_EMISSION");
            }

            if (gltfMaterial.doubleSided)
            {
                Debug.LogWarning("Double sided shading is not supported!");
            }
            return(material);
        }
        public UnityEngine.Material GenerateMaterial(
            Schema.Material gltfMaterial,
            ref Schema.Texture[] textures,
            ref Schema.Image[] schemaImages,
            ref Dictionary <int, Texture2D>[] imageVariants
            )
        {
            UnityEngine.Material material;

            if (gltfMaterial.extensions != null && gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness != null)
            {
                material = GetPbrSpecularGlossinessMaterial(gltfMaterial.doubleSided);
            }
            else
            if (gltfMaterial.extensions.KHR_materials_unlit != null)
            {
                material = GetUnlitMaterial(gltfMaterial.doubleSided);
            }
            else
            {
                material = GetPbrMetallicRoughnessMaterial(gltfMaterial.doubleSided);
            }

            material.name = gltfMaterial.name;

            //added support for KHR_materials_pbrSpecularGlossiness
            if (gltfMaterial.extensions != null)
            {
                Schema.PbrSpecularGlossiness specGloss = gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness;
                if (specGloss != null)
                {
                    material.color = specGloss.diffuseColor.gamma;
                    material.SetVector(StandardShaderHelper.specColorPropId, specGloss.specularColor);
                    material.SetFloat(StandardShaderHelper.glossinessPropId, specGloss.glossinessFactor);

                    TrySetTexture(specGloss.diffuseTexture, material, StandardShaderHelper.mainTexPropId, ref textures, ref schemaImages, ref imageVariants);

                    if (TrySetTexture(specGloss.specularGlossinessTexture, material, StandardShaderHelper.specGlossMapPropId, ref textures, ref schemaImages, ref imageVariants))
                    {
                        material.EnableKeyword(StandardShaderHelper.KW_SPEC_GLOSS_MAP);
                    }
                }
            }

            if (gltfMaterial.pbrMetallicRoughness != null)
            {
                material.color = gltfMaterial.pbrMetallicRoughness.baseColor.gamma;
                material.SetFloat(StandardShaderHelper.metallicPropId, gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.SetFloat(StandardShaderHelper.roughnessPropId, gltfMaterial.pbrMetallicRoughness.roughnessFactor);

                TrySetTexture(
                    gltfMaterial.pbrMetallicRoughness.baseColorTexture,
                    material,
                    StandardShaderHelper.mainTexPropId,
                    ref textures,
                    ref schemaImages,
                    ref imageVariants
                    );

                if (TrySetTexture(gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture, material, StandardShaderHelper.metallicGlossMapPropId, ref textures, ref schemaImages, ref imageVariants))
                {
                    material.EnableKeyword(StandardShaderHelper.KW_METALLIC_ROUGNESS_MAP);
                }
            }

            if (TrySetTexture(gltfMaterial.normalTexture, material, StandardShaderHelper.bumpMapPropId, ref textures, ref schemaImages, ref imageVariants))
            {
                material.EnableKeyword("_NORMALMAP");
            }

            if (TrySetTexture(gltfMaterial.occlusionTexture, material, StandardShaderHelper.occlusionMapPropId, ref textures, ref schemaImages, ref imageVariants))
            {
                material.EnableKeyword(StandardShaderHelper.KW_OCCLUSION);
            }

            if (TrySetTexture(gltfMaterial.emissiveTexture, material, StandardShaderHelper.emissionMapPropId, ref textures, ref schemaImages, ref imageVariants))
            {
                material.EnableKeyword(StandardShaderHelper.KW_EMISSION);
            }

            if (gltfMaterial.alphaModeEnum == AlphaMode.MASK)
            {
                material.SetFloat(StandardShaderHelper.cutoffPropId, gltfMaterial.alphaCutoff);
                StandardShaderHelper.SetAlphaModeMask(material, gltfMaterial);
            }
            else if (gltfMaterial.alphaModeEnum == AlphaMode.BLEND)
            {
                StandardShaderHelper.SetAlphaModeBlend(material);
            }
            else
            {
                StandardShaderHelper.SetOpaqueMode(material);
            }

            if (gltfMaterial.emissive != Color.black)
            {
                material.SetColor("_EmissionColor", gltfMaterial.emissive.gamma);
                material.EnableKeyword(StandardShaderHelper.KW_EMISSION);
            }

            return(material);
        }
        public UnityEngine.Material GenerateMaterial(Schema.Material gltfMaterial, Schema.Texture[] textures, Texture2D[] images, string shader)
        {
            UnityEngine.Material material;

            // Check for user defined shader
            if (shader != null)
            {
                if (shader.Contains("glTF/PbrSpecularGlossiness"))
                {
                    material = GetPbrSpecularGlossinessMaterial(gltfMaterial.doubleSided);
                }
                else if (shader.Contains("glTF/PbrMetallicRoughness"))
                {
                    material = GetPbrMetallicRoughnessMaterial(gltfMaterial.doubleSided);
                }
                else if (shader.Contains("glTF/Unlit"))
                {
                    material = GetUnlitMaterial(gltfMaterial.doubleSided);
                }
                else
                {
                    material = new Material(Shader.Find(shader));
                }
            }
            else
            {
                // Original setting
                if (gltfMaterial.extensions != null && gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness != null)
                {
                    material = GetPbrSpecularGlossinessMaterial(gltfMaterial.doubleSided);
                }
                else
                if (gltfMaterial.extensions.KHR_materials_unlit != null)
                {
                    material = GetUnlitMaterial(gltfMaterial.doubleSided);
                }
                else
                {
                    // Enable Pbr Metallic Roughness Material by default (original setting)
                    material = GetPbrMetallicRoughnessMaterial(gltfMaterial.doubleSided);
                    // Disable unlit Shader by default
                    // material = GetUnlitMaterial(gltfMaterial.doubleSided);
                }
            }

            material.name = gltfMaterial.name;

            if (material.HasProperty(StandardShaderHelper.KW_MAIN_MAP))
            {
                // Initialize texture transform
                material.mainTextureScale  = TEXTURE_SCALE;
                material.mainTextureOffset = TEXTURE_OFFSET;
            }

            //added support for KHR_materials_pbrSpecularGlossiness
            if (gltfMaterial.extensions != null)
            {
                Schema.PbrSpecularGlossiness specGloss = gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness;
                if (specGloss != null)
                {
                    material.color = specGloss.diffuseColor;
                    material.SetVector(StandardShaderHelper.specColorPropId, specGloss.specularColor);
                    material.SetFloat(StandardShaderHelper.glossinessPropId, specGloss.glossinessFactor);

                    TrySetTexture(specGloss.diffuseTexture, material, StandardShaderHelper.mainTexPropId, textures, images);

                    if (TrySetTexture(specGloss.specularGlossinessTexture, material, StandardShaderHelper.specGlossMapPropId, textures, images))
                    {
                        material.EnableKeyword(StandardShaderHelper.KW_SPEC_GLOSS_MAP);
                    }
                }
            }

            if (gltfMaterial.pbrMetallicRoughness != null)
            {
                material.color = gltfMaterial.pbrMetallicRoughness.baseColor;
                material.SetFloat(StandardShaderHelper.metallicPropId, gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.SetFloat(StandardShaderHelper.roughnessPropId, gltfMaterial.pbrMetallicRoughness.roughnessFactor);

                TrySetTexture(
                    gltfMaterial.pbrMetallicRoughness.baseColorTexture,
                    material,
                    StandardShaderHelper.mainTexPropId,
                    textures,
                    images
                    );

                if (TrySetTexture(gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture, material, StandardShaderHelper.metallicGlossMapPropId, textures, images))
                {
                    material.EnableKeyword(StandardShaderHelper.KW_METALLIC_ROUGNESS_MAP);
                }
            }

            if (TrySetTexture(gltfMaterial.normalTexture, material, StandardShaderHelper.bumpMapPropId, textures, images))
            {
                material.EnableKeyword("_NORMALMAP");
            }

            if (TrySetTexture(gltfMaterial.occlusionTexture, material, StandardShaderHelper.occlusionMapPropId, textures, images))
            {
                material.EnableKeyword(StandardShaderHelper.KW_OCCLUSION);
            }

            if (TrySetTexture(gltfMaterial.emissiveTexture, material, StandardShaderHelper.emissionMapPropId, textures, images))
            {
                material.EnableKeyword(StandardShaderHelper.KW_EMISSION);
            }

            if (gltfMaterial.alphaModeEnum == AlphaMode.MASK)
            {
                material.SetFloat(StandardShaderHelper.cutoffPropId, gltfMaterial.alphaCutoff);
                StandardShaderHelper.SetAlphaModeMask(material, gltfMaterial);
            }
            else if (gltfMaterial.alphaModeEnum == AlphaMode.BLEND)
            {
                StandardShaderHelper.SetAlphaModeBlend(material);
            }
            else
            {
                StandardShaderHelper.SetOpaqueMode(material);
            }

            if (gltfMaterial.emissive != Color.black)
            {
                material.SetColor("_EmissionColor", gltfMaterial.emissive);
                material.EnableKeyword(StandardShaderHelper.KW_EMISSION);
            }

            return(material);
        }