public async Task LoadKHRSpecGlossGLTFFromStreamUWP()
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            StorageFile   sampleFile  = await StorageFile.GetFileFromApplicationUriAsync(new Uri(GLTF_PBR_SPECGLOSS_PATH));


            IRandomAccessStream gltfStream = await sampleFile.OpenAsync(FileAccessMode.Read);

            var reader = new DataReader(gltfStream.GetInputStreamAt(0));
            var bytes  = new byte[gltfStream.Size];
            await reader.LoadAsync((uint)gltfStream.Size);

            reader.ReadBytes(bytes);
            GLTFRoot gltfRoot = GLTFParser.ParseJson(bytes);

            Assert.IsNotNull(gltfRoot.ExtensionsUsed);
            Assert.IsTrue(gltfRoot.ExtensionsUsed.Contains(KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME));

            Assert.IsNotNull(gltfRoot.Materials);
            Assert.AreEqual(1, gltfRoot.Materials.Count);
            Material materialDef = gltfRoot.Materials[0];
            KHR_materials_pbrSpecularGlossinessExtension specGloss = materialDef.Extensions[KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME] as KHR_materials_pbrSpecularGlossinessExtension;

            Assert.IsTrue(specGloss != null);

            Assert.AreEqual(Color.White, specGloss.DiffuseFactor);
            Assert.AreEqual(4, specGloss.DiffuseTexture.Index.Id);
            Assert.AreEqual(KHR_materials_pbrSpecularGlossinessExtension.SPEC_FACTOR_DEFAULT, specGloss.SpecularFactor);
            Assert.AreEqual(KHR_materials_pbrSpecularGlossinessExtension.GLOSS_FACTOR_DEFAULT, specGloss.GlossinessFactor);
            Assert.AreEqual(5, specGloss.SpecularGlossinessTexture.Index.Id);
        }
示例#2
0
        public void LoadKHRSpecGlossGLTFFromStream()
        {
            Assert.IsTrue(File.Exists(GLTF_PBR_SPECGLOSS_PATH));
            FileStream gltfStream = File.OpenRead(GLTF_PBR_SPECGLOSS_PATH);

            GLTFRoot gltfRoot;

            GLTFParser.ParseJson(gltfStream, out gltfRoot);

            Assert.IsNotNull(gltfRoot.ExtensionsUsed);
            Assert.IsTrue(gltfRoot.ExtensionsUsed.Contains(KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME));

            Assert.IsNotNull(gltfRoot.Materials);
            Assert.AreEqual(1, gltfRoot.Materials.Count);
            GLTFMaterial materialDef = gltfRoot.Materials[0];
            KHR_materials_pbrSpecularGlossinessExtension specGloss = materialDef.Extensions[KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME] as KHR_materials_pbrSpecularGlossinessExtension;

            Assert.IsTrue(specGloss != null);

            Assert.AreEqual(Color.White, specGloss.DiffuseFactor);
            Assert.AreEqual(4, specGloss.DiffuseTexture.Index.Id);
            Assert.AreEqual(KHR_materials_pbrSpecularGlossinessExtension.SPEC_FACTOR_DEFAULT, specGloss.SpecularFactor);
            Assert.AreEqual(KHR_materials_pbrSpecularGlossinessExtension.GLOSS_FACTOR_DEFAULT, specGloss.GlossinessFactor);
            Assert.AreEqual(5, specGloss.SpecularGlossinessTexture.Index.Id);
        }
        protected virtual MaterialCacheData CreateMaterial(GLTF.Schema.Material def, int materialIndex)
        {
            MaterialCacheData materialWrapper = null;

            if (materialIndex < 0 || _assetCache.MaterialCache[materialIndex] == null)
            {
                Shader shader;

                // get the shader to use for this material
                try
                {
                    if (_root.ExtensionsUsed != null && _root.ExtensionsUsed.Contains("KHR_materials_pbrSpecularGlossiness"))
                    {
                        shader = _shaderCache[MaterialType.KHR_materials_pbrSpecularGlossiness];
                    }
                    else if (def.PbrMetallicRoughness != null)
                    {
                        shader = _shaderCache[MaterialType.PbrMetallicRoughness];
                    }
                    else if (_root.ExtensionsUsed != null && _root.ExtensionsUsed.Contains("KHR_materials_common") &&
                             def.CommonConstant != null)
                    {
                        shader = _shaderCache[MaterialType.CommonConstant];
                    }
                    else
                    {
                        shader = _shaderCache[MaterialType.PbrMetallicRoughness];
                    }
                }
                catch (KeyNotFoundException)
                {
                    Debug.LogWarningFormat("No shader supplied for type of glTF material {0}, using Standard fallback", def.Name);
                    shader = Shader.Find("Standard");
                }

                shader.maximumLOD = MaximumLod;

                var material = new UnityEngine.Material(shader);

                if (def.AlphaMode == AlphaMode.MASK)
                {
                    material.SetOverrideTag("RenderType", "TransparentCutout");
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                    material.SetInt("_ZWrite", 1);
                    material.EnableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
                    material.SetFloat("_Cutoff", (float)def.AlphaCutoff);
                }
                else if (def.AlphaMode == AlphaMode.BLEND)
                {
                    material.SetOverrideTag("RenderType", "Transparent");
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                    material.SetInt("_ZWrite", 0);
                    material.DisableKeyword("_ALPHATEST_ON");
                    material.EnableKeyword("_ALPHABLEND_ON");
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
                }
                else
                {
                    material.SetOverrideTag("RenderType", "Opaque");
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                    material.SetInt("_ZWrite", 1);
                    material.DisableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = -1;
                }

                if (def.DoubleSided)
                {
                    material.SetInt("_Cull", (int)CullMode.Off);
                }
                else
                {
                    material.SetInt("_Cull", (int)CullMode.Back);
                }

                if (def.PbrMetallicRoughness != null)
                {
                    var pbr = def.PbrMetallicRoughness;

                    material.SetColor("_Color", pbr.BaseColorFactor.ToUnityColor());

                    if (pbr.BaseColorTexture != null)
                    {
                        var textureDef = pbr.BaseColorTexture.Index.Value;
                        material.SetTexture("_MainTex", CreateTexture(textureDef));

                        ApplyTextureTransform(pbr.BaseColorTexture, material, "_MainTex");
                    }

                    material.SetFloat("_Metallic", (float)pbr.MetallicFactor);

                    if (pbr.MetallicRoughnessTexture != null)
                    {
                        var texture = pbr.MetallicRoughnessTexture.Index.Value;
                        material.SetTexture("_MetallicRoughnessMap", CreateTexture(texture));

                        ApplyTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicRoughnessMap");
                    }

                    material.SetFloat("_Roughness", (float)pbr.RoughnessFactor);
                }

                if (_root.ExtensionsUsed != null && _root.ExtensionsUsed.Contains(KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME))
                {
                    KHR_materials_pbrSpecularGlossinessExtension specGloss = def.Extensions[KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME] as KHR_materials_pbrSpecularGlossinessExtension;

                    if (specGloss.DiffuseTexture != null)
                    {
                        var texture = specGloss.DiffuseTexture.Index.Value;
                        material.SetTexture("_MainTex", CreateTexture(texture));

                        ApplyTextureTransform(specGloss.DiffuseTexture, material, "_MainTex");
                    }
                    else
                    {
                        material.SetColor("_Color", specGloss.DiffuseFactor.ToUnityColor());
                    }

                    if (specGloss.SpecularGlossinessTexture != null)
                    {
                        var texture = specGloss.SpecularGlossinessTexture.Index.Value;
                        material.SetTexture("_SpecGlossMap", CreateTexture(texture));
                        material.EnableKeyword("_SPECGLOSSMAP");

                        ApplyTextureTransform(specGloss.SpecularGlossinessTexture, material, "_SpecGlossMap");
                    }
                    else
                    {
                        material.SetVector("_SpecColor", specGloss.SpecularFactor.ToUnityVector3());
                        material.SetFloat("_Glossiness", (float)specGloss.GlossinessFactor);
                    }
                }

                if (def.CommonConstant != null)
                {
                    material.SetColor("_AmbientFactor", def.CommonConstant.AmbientFactor.ToUnityColor());

                    if (def.CommonConstant.LightmapTexture != null)
                    {
                        material.EnableKeyword("LIGHTMAP_ON");

                        var texture = def.CommonConstant.LightmapTexture.Index.Value;
                        material.SetTexture("_LightMap", CreateTexture(texture));
                        material.SetInt("_LightUV", def.CommonConstant.LightmapTexture.TexCoord);

                        ApplyTextureTransform(def.CommonConstant.LightmapTexture, material, "_LightMap");
                    }

                    material.SetColor("_LightFactor", def.CommonConstant.LightmapFactor.ToUnityColor());
                }

                if (def.NormalTexture != null)
                {
                    var texture = def.NormalTexture.Index.Value;
                    material.SetTexture("_BumpMap", CreateTexture(texture));
                    material.SetFloat("_BumpScale", (float)def.NormalTexture.Scale);
                    material.EnableKeyword("_NORMALMAP");

                    ApplyTextureTransform(def.NormalTexture, material, "_BumpMap");
                }

                if (def.OcclusionTexture != null)
                {
                    var texture = def.OcclusionTexture.Index;

                    material.SetFloat("_OcclusionStrength", (float)def.OcclusionTexture.Strength);

                    if (def.PbrMetallicRoughness != null &&
                        def.PbrMetallicRoughness.MetallicRoughnessTexture != null &&
                        def.PbrMetallicRoughness.MetallicRoughnessTexture.Index.Id == texture.Id)
                    {
                        material.EnableKeyword("OCC_METAL_ROUGH_ON");
                    }
                    else
                    {
                        material.SetTexture("_OcclusionMap", CreateTexture(texture.Value));

                        ApplyTextureTransform(def.OcclusionTexture, material, "_OcclusionMap");
                    }
                }

                if (def.EmissiveTexture != null)
                {
                    var texture = def.EmissiveTexture.Index.Value;
                    material.EnableKeyword("EMISSION_MAP_ON");
                    material.EnableKeyword("_EMISSION");
                    material.SetTexture("_EmissionMap", CreateTexture(texture));
                    material.SetInt("_EmissionUV", def.EmissiveTexture.TexCoord);

                    ApplyTextureTransform(def.EmissiveTexture, material, "_EmissionMap");
                }

                material.SetColor("_EmissionColor", def.EmissiveFactor.ToUnityColor());

                materialWrapper = new MaterialCacheData
                {
                    UnityMaterial = material,
                    UnityMaterialWithVertexColor = new UnityEngine.Material(material),
                    GLTFMaterial = def
                };

                materialWrapper.UnityMaterialWithVertexColor.EnableKeyword("VERTEX_COLOR_ON");

                if (materialIndex > 0)
                {
                    _assetCache.MaterialCache[materialIndex] = materialWrapper;
                }
            }

            return(materialIndex > 0 ? _assetCache.MaterialCache[materialIndex] : materialWrapper);
        }
        protected virtual void CreateUnityMaterial(GLTF.Schema.Material def, int materialIndex)
        {
            Extension specularGlossinessExtension = null;
            bool      isSpecularPBR = def.Extensions != null && def.Extensions.TryGetValue("KHR_materials_pbrSpecularGlossiness", out specularGlossinessExtension);

            Shader shader = isSpecularPBR ? Shader.Find("Standard (Specular setup)") : Shader.Find("Standard");

            var material = new UnityEngine.Material(shader);

            material.hideFlags = HideFlags.DontUnloadUnusedAsset;             // Avoid material to be deleted while being built
            material.name      = def.Name;

            //Transparency
            if (def.AlphaMode == AlphaMode.MASK)
            {
                GLTFUtils.SetupMaterialWithBlendMode(material, GLTFUtils.BlendMode.Cutout);
                material.SetFloat("_Mode", 1);
                material.SetFloat("_Cutoff", (float)def.AlphaCutoff);
            }
            else if (def.AlphaMode == AlphaMode.BLEND)
            {
                GLTFUtils.SetupMaterialWithBlendMode(material, GLTFUtils.BlendMode.Fade);
                material.SetFloat("_Mode", 3);
            }

            if (def.NormalTexture != null)
            {
                var       texture       = def.NormalTexture.Index.Id;
                Texture2D normalTexture = getTexture(texture) as Texture2D;

                //Automatically set it to normal map
                TextureImporter im = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(normalTexture)) as TextureImporter;
                im.textureType = TextureImporterType.NormalMap;
                im.SaveAndReimport();
                material.SetTexture("_BumpMap", getTexture(texture));
                material.SetFloat("_BumpScale", (float)def.NormalTexture.Scale);
            }

            if (def.EmissiveTexture != null)
            {
                material.EnableKeyword("EMISSION_MAP_ON");
                var texture = def.EmissiveTexture.Index.Id;
                material.SetTexture("_EmissionMap", getTexture(texture));
                material.SetInt("_EmissionUV", def.EmissiveTexture.TexCoord);
            }

            // PBR channels
            if (specularGlossinessExtension != null)
            {
                KHR_materials_pbrSpecularGlossinessExtension pbr = (KHR_materials_pbrSpecularGlossinessExtension)specularGlossinessExtension;
                material.SetColor("_Color", pbr.DiffuseFactor.ToUnityColor().gamma);
                if (pbr.DiffuseTexture != null)
                {
                    var texture = pbr.DiffuseTexture.Index.Id;
                    material.SetTexture("_MainTex", getTexture(texture));
                }

                if (pbr.SpecularGlossinessTexture != null)
                {
                    var texture = pbr.SpecularGlossinessTexture.Index.Id;
                    material.SetTexture("_SpecGlossMap", getTexture(texture));
                    material.SetFloat("_GlossMapScale", (float)pbr.GlossinessFactor);
                    material.SetFloat("_Glossiness", (float)pbr.GlossinessFactor);
                }
                else
                {
                    material.SetFloat("_Glossiness", (float)pbr.GlossinessFactor);
                }

                Vector3 specularVec3 = pbr.SpecularFactor.ToUnityVector3();
                material.SetColor("_SpecColor", new Color(specularVec3.x, specularVec3.y, specularVec3.z, 1.0f));

                if (def.OcclusionTexture != null)
                {
                    var texture = def.OcclusionTexture.Index.Id;
                    material.SetFloat("_OcclusionStrength", (float)def.OcclusionTexture.Strength);
                    material.SetTexture("_OcclusionMap", getTexture(texture));
                }

                GLTFUtils.SetMaterialKeywords(material, GLTFUtils.WorkflowMode.Specular);
            }
            else if (def.PbrMetallicRoughness != null)
            {
                var pbr = def.PbrMetallicRoughness;

                material.SetColor("_Color", pbr.BaseColorFactor.ToUnityColor().gamma);
                if (pbr.BaseColorTexture != null)
                {
                    var texture = pbr.BaseColorTexture.Index.Id;
                    material.SetTexture("_MainTex", getTexture(texture));
                }

                material.SetFloat("_Metallic", (float)pbr.MetallicFactor);
                material.SetFloat("_Glossiness", 1.0f - (float)pbr.RoughnessFactor);

                if (pbr.MetallicRoughnessTexture != null)
                {
                    var texture = pbr.MetallicRoughnessTexture.Index.Id;
                    UnityEngine.Texture2D inputTexture  = getTexture(texture) as Texture2D;
                    List <Texture2D>      splitTextures = splitMetalRoughTexture(inputTexture, def.OcclusionTexture != null, (float)pbr.MetallicFactor, (float)pbr.RoughnessFactor);
                    material.SetTexture("_MetallicGlossMap", splitTextures[0]);

                    if (def.OcclusionTexture != null)
                    {
                        material.SetFloat("_OcclusionStrength", (float)def.OcclusionTexture.Strength);
                        material.SetTexture("_OcclusionMap", splitTextures[1]);
                    }
                }

                GLTFUtils.SetMaterialKeywords(material, GLTFUtils.WorkflowMode.Metallic);
            }

            material.SetColor("_EmissionColor", def.EmissiveFactor.ToUnityColor().gamma);
            material = _assetManager.saveMaterial(material, materialIndex);
            _assetManager._parsedMaterials.Add(material);
            material.hideFlags = HideFlags.None;
        }