Ejemplo n.º 1
0
 private static void ConstructScene(this GltfObject gltfObject, GltfScene gltfScene)
 {
     for (int i = 0; i < gltfScene.nodes.Length; i++)
     {
         ConstructNode(gltfObject, gltfObject.nodes[gltfScene.nodes[i]], gltfScene.nodes[i], gltfObject.GameObjectReference.transform);
     }
 }
 private static async Task ConstructSceneAsync(this GltfObject gltfObject, GltfScene gltfScene)
 {
     for (int i = 0; i < gltfScene.nodes.Length; i++)
     {
         await ConstructNodeAsync(gltfObject, gltfObject.nodes[gltfScene.nodes[i]], gltfScene.nodes[i], gltfObject.GameObjectReference.transform);
     }
 }
Ejemplo n.º 3
0
        private async void Start()
        {
            var path = $"{Application.streamingAssetsPath}{uri}";

            path = path.Replace("/", "\\");

            if (!File.Exists(path))
            {
                Debug.LogError($"Unable to find the glTF object at {path}");
            }

            GltfObject gltfObject = null;

            try
            {
                gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path);
            }
            catch (Exception e)
            {
                Debug.LogError($"{e.Message}\n{e.StackTrace}");
            }

            if (gltfObject != null)
            {
                Debug.Log("Import successful");
            }
        }
        private static async Task ConstructMaterialAsync(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId)
        {
            if (gltfObject.UseBackgroundThread)
            {
                await Update;
            }

            Material material = await CreateMRTKShaderMaterial(gltfObject, gltfMaterial, materialId);

            if (material == null)
            {
                Debug.LogWarning("The Mixed Reality Toolkit/Standard Shader was not found. Falling back to Standard Shader");
                material = await CreateStandardShaderMaterial(gltfObject, gltfMaterial, materialId);
            }

            if (material == null)
            {
                Debug.LogWarning("The Standard Shader was not found. Failed to create material for glTF object");
            }
            else
            {
                gltfMaterial.Material = material;
            }

            if (gltfObject.UseBackgroundThread)
            {
                await BackgroundThread;
            }
        }
Ejemplo n.º 5
0
        private async void Start()
        {
            var path = AbsolutePath;

            if (!File.Exists(path))
            {
                Debug.LogError($"Unable to find the glTF object at {path}");
                DebugText.SetActive(true);
                return;
            }

            DebugText.SetActive(false);

            GltfObject gltfObject = null;

            try
            {
                gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path);

                // Put object in front of user
                gltfObject.GameObjectReference.transform.position = new Vector3(0.0f, 0.0f, 1.0f);

                gltfObject.GameObjectReference.transform.localScale *= this.ScaleFactor;
            }
            catch (Exception e)
            {
                Debug.LogError($"TestGltfLoading start failed - {e.Message}\n{e.StackTrace}");
            }

            if (gltfObject != null)
            {
                Debug.Log("Import successful");
            }
        }
Ejemplo n.º 6
0
 private static async Task ConstructSceneAsync(this GltfObject gltfObject, GltfScene gltfScene, GameObject root)
 {
     for (int i = 0; i < gltfScene.nodes.Length; i++)
     {
         // TODO Uncomment this out after implementing root object transform normalization.
         await ConstructNodeAsync(gltfObject, gltfObject.nodes[gltfScene.nodes[i]], gltfScene.nodes[i], root.transform /*, gltfObject.scenes.Length == 1*/);
     }
 }
 private static async Task ConstructSceneAsync(this GltfObject gltfObject, GltfScene gltfScene, GameObject root)
 {
     for (int i = 0; i < gltfScene.nodes.Length; i++)
     {
         // Note: glTF objects are currently imported with their original scale from the glTF scene, which may apply an unexpected transform
         // to the root node. If this behavior needs to be changed, functionality should be added below to ConstructNodeAsync
         await ConstructNodeAsync(gltfObject, gltfObject.nodes[gltfScene.nodes[i]], gltfScene.nodes[i], root.transform);
     }
 }
Ejemplo n.º 8
0
        private static void ConstructBuffer(this GltfObject gltfObject, GltfBuffer gltfBuffer)
        {
            var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;

#if UNITY_WSA
            gltfBuffer.BufferData = UnityEngine.Windows.File.ReadAllBytes($"{parentDirectory}\\{gltfBuffer.uri}");
#else
            gltfBuffer.BufferData = File.ReadAllBytes($"{parentDirectory}\\{gltfBuffer.uri}");
#endif
        }
        /// <summary>
        /// Constructs the glTF Object.
        /// </summary>
        /// <returns>The new <see href="https://docs.unity3d.com/ScriptReference/GameObject.html">GameObject</see> of the final constructed <see cref="Schema.GltfScene"/></returns>
        public static async Task <GameObject> ConstructAsync(this GltfObject gltfObject)
        {
            if (!gltfObject.asset.version.Contains("2.0"))
            {
                Debug.LogWarning($"Expected glTF 2.0, but this asset is using {gltfObject.asset.version}");
                return(null);
            }

            if (gltfObject.UseBackgroundThread)
            {
                await Update;
            }

            var rootObject = new GameObject($"glTF Scene {gltfObject.Name}");

            rootObject.SetActive(false);

            if (gltfObject.UseBackgroundThread)
            {
                await BackgroundThread;
            }

            for (int i = 0; i < gltfObject.bufferViews?.Length; i++)
            {
                gltfObject.ConstructBufferView(gltfObject.bufferViews[i]);
            }

            for (int i = 0; i < gltfObject.textures?.Length; i++)
            {
                await gltfObject.ConstructTextureAsync(gltfObject.textures[i]);
            }

            for (int i = 0; i < gltfObject.materials?.Length; i++)
            {
                await gltfObject.ConstructMaterialAsync(gltfObject.materials[i], i);
            }

            if (gltfObject.scenes == null)
            {
                Debug.LogError($"No scenes found for {gltfObject.Name}");
            }

            if (gltfObject.UseBackgroundThread)
            {
                await Update;
            }

            for (int i = 0; i < gltfObject.scenes?.Length; i++)
            {
                await gltfObject.ConstructSceneAsync(gltfObject.scenes[i], rootObject);
            }

            rootObject.SetActive(true);
            return(gltfObject.GameObjectReference = rootObject);
        }
Ejemplo n.º 10
0
        private static void ConstructBufferView(this GltfObject gltfObject, GltfBufferView bufferView)
        {
            bufferView.Buffer = gltfObject.buffers[bufferView.buffer];

            if (bufferView.Buffer.BufferData == null &&
                !string.IsNullOrEmpty(gltfObject.Uri) &&
                !string.IsNullOrEmpty(bufferView.Buffer.uri))
            {
                var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;
                bufferView.Buffer.BufferData = File.ReadAllBytes($"{parentDirectory}\\{bufferView.Buffer.uri}");
            }
        }
        private static async Task ConstructNodeAsync(GltfObject gltfObject, GltfNode node, int nodeId, Transform parent)
        {
            await Update;
            var   nodeGameObject = new GameObject(string.IsNullOrEmpty(node.name) ? $"glTF Node {nodeId}" : node.name);

            // If we're creating a really large node, we need it to not be visible in partial stages. So we hide it while we create it
            nodeGameObject.SetActive(false);

            await BackgroundThread;

            node.Matrix = node.GetTrsProperties(out Vector3 position, out Quaternion rotation, out Vector3 scale);

            if (node.Matrix == Matrix4x4.identity)
            {
                if (node.translation != null)
                {
                    position = node.translation.GetVector3Value();
                }

                if (node.rotation != null)
                {
                    rotation = node.rotation.GetQuaternionValue();
                }

                if (node.scale != null)
                {
                    scale = node.scale.GetVector3Value(false);
                }
            }

            await Update;

            nodeGameObject.transform.localPosition = position;
            nodeGameObject.transform.localRotation = rotation;
            nodeGameObject.transform.localScale    = scale;

            if (node.mesh >= 0)
            {
                await ConstructMeshAsync(gltfObject, nodeGameObject, node.mesh);
            }

            if (node.children != null)
            {
                for (int i = 0; i < node.children.Length; i++)
                {
                    await ConstructNodeAsync(gltfObject, gltfObject.nodes[node.children[i]], node.children[i], nodeGameObject.transform);
                }
            }

            nodeGameObject.transform.SetParent(parent, false);
            nodeGameObject.SetActive(true);
        }
Ejemplo n.º 12
0
        private void Awake()
        {
            GltfObject gltfObject = GltfSerializationUtility.GetGltfObjectFromPath(Application.streamingAssetsPath + "/" + uri);

            if (gltfObject == null)
            {
                Debug.LogError("Failed to load gltf object");
            }
            else
            {
                Debug.Log("Import successful");
            }
        }
Ejemplo n.º 13
0
        private static void ConstructMesh(GltfObject gltfObject, GameObject parent, int meshId)
        {
            var gltfMesh = gltfObject.meshes[meshId];

            for (int i = 0; i < gltfMesh.primitives.Length; i++)
            {
                var meshPrimitive = ConstructMeshPrimitive(gltfObject, gltfMesh.primitives[i]);
                var renderer      = parent.gameObject.AddComponent <MeshRenderer>();
                var filter        = parent.gameObject.AddComponent <MeshFilter>();
                filter.sharedMesh       = meshPrimitive;
                renderer.sharedMaterial = gltfObject.materials[gltfMesh.primitives[i].material].Material;
            }
        }
Ejemplo n.º 14
0
        public IEnumerator TestGltfCustomAttributes()
        {
            // Load glTF
            string path = AssetDatabase.GUIDToAssetPath(AvocadoCustomAttrGuid);
            var    task = GltfUtility.ImportGltfObjectFromPathAsync(path);

            yield return(WaitForTask(task));

            GltfObject gltfObject = task.Result;

            yield return(null);

            // Check for custom attribute
            int temperatureIdx;

            gltfObject.meshes[0].primitives[0].Attributes.TryGetValue("_TEMPERATURE", out temperatureIdx);

            int temperature = gltfObject.accessors[temperatureIdx].count;

            Assert.AreEqual(100, temperature);
        }
        private static async Task ConstructMeshAsync(GltfObject gltfObject, GameObject parent, int meshId)
        {
            GltfMesh gltfMesh = gltfObject.meshes[meshId];

            var renderer = parent.gameObject.AddComponent <MeshRenderer>();
            var filter   = parent.gameObject.AddComponent <MeshFilter>();

            if (gltfMesh.primitives.Length == 1)
            {
                gltfMesh.Mesh = await ConstructMeshPrimitiveAsync(gltfObject, gltfMesh.primitives[0]);

                gltfMesh.Mesh.name      = gltfMesh.name;
                filter.sharedMesh       = gltfMesh.Mesh;
                renderer.sharedMaterial = gltfObject.materials[gltfMesh.primitives[0].material].Material;
                return;
            }

            var materials    = new List <Material>();
            var meshCombines = new CombineInstance[gltfMesh.primitives.Length];

            for (int i = 0; i < gltfMesh.primitives.Length; i++)
            {
                meshCombines[i].mesh = await ConstructMeshPrimitiveAsync(gltfObject, gltfMesh.primitives[i]);

                var meshMaterial = gltfObject.materials[gltfMesh.primitives[i].material].Material;

                if (!materials.Contains(meshMaterial))
                {
                    materials.Add(meshMaterial);
                }
            }

            var newMesh = new Mesh();

            newMesh.CombineMeshes(meshCombines);
            gltfMesh.Mesh            = filter.sharedMesh = newMesh;
            gltfMesh.Mesh.name       = gltfMesh.name;
            renderer.sharedMaterials = materials.ToArray();
        }
Ejemplo n.º 16
0
        public IEnumerator TestGltfLoads()
        {
            // Load glTF
            string path = AssetDatabase.GUIDToAssetPath(AvocadoCustomAttrGuid);
            var    task = GltfUtility.ImportGltfObjectFromPathAsync(path);

            yield return(WaitForTask(task));

            GltfObject gltfObject = task.Result;

            yield return(null);

            Assert.IsNotNull(gltfObject);
            Assert.AreEqual(1, gltfObject.meshes.Length);
            Assert.AreEqual(1, gltfObject.nodes.Length);

            // Check if mesh variables have been set by attributes
            Assert.AreEqual(406, gltfObject.meshes[0].Mesh.uv.Length);
            Assert.AreEqual(406, gltfObject.meshes[0].Mesh.normals.Length);
            Assert.AreEqual(406, gltfObject.meshes[0].Mesh.tangents.Length);
            Assert.AreEqual(406, gltfObject.meshes[0].Mesh.vertexCount);
        }
Ejemplo n.º 17
0
        public IEnumerator TestGltfCustomAttributesData()
        {
            // Load glTF
            string path = AssetDatabase.GUIDToAssetPath(CubeCustomAttrGuid);
            var    task = GltfUtility.ImportGltfObjectFromPathAsync(path);

            yield return(WaitForTask(task));

            GltfObject gltfObject = task.Result;

            yield return(null);

            // Check for custom vertex data is a list of 10s
            gltfObject.meshes[0].primitives[0].Attributes.TryGetValue("_CUSTOM_ATTR", out var customAttrIdx);

            GltfAccessor accessor = gltfObject.GetAccessor(customAttrIdx);
            var          intArray = accessor.GetIntArray(false);

            foreach (var item in intArray)
            {
                Assert.AreEqual(10, item);
            }
        }
Ejemplo n.º 18
0
        private static void ConstructTexture(this GltfObject gltfObject, GltfTexture gltfTexture)
        {
            var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;

            if (gltfTexture.source >= 0)
            {
                GltfImage gltfImage = gltfObject.images[gltfTexture.source];

                var imagePath = $"{parentDirectory}\\{gltfImage.uri}";

                // TODO Check if texture is in unity project, and use the asset reference instead.

                gltfImage.Texture = new Texture2D(0, 0);

#if UNITY_WSA
                var imageData = UnityEngine.Windows.File.ReadAllBytes(imagePath);
#else
                var imageData = File.ReadAllBytes(imagePath);
#endif

                gltfImage.Texture.LoadImage(imageData, false);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Imports the glTF Object and returns a new <see cref="GameObject"/> of the final constructed <see cref="GltfScene"/>.
        /// </summary>
        /// <param name="gltfObject"></param>
        /// <returns></returns>
        public static GameObject ImportGltfObject(GltfObject gltfObject)
        {
            if (!gltfObject.asset.version.Contains("2.0"))
            {
                Debug.LogWarning($"Expected glTF 2.0, but this asset is using {gltfObject.asset.version}");
                return(null);
            }

            gltfObject.GameObjectReference = new GameObject($"glTF Scene {gltfObject.Name}");

            for (int i = 0; i < gltfObject.buffers?.Length; i++)
            {
                gltfObject.ConstructBuffer(gltfObject.buffers[i]);
            }

            for (int i = 0; i < gltfObject.textures?.Length; i++)
            {
                gltfObject.ConstructTexture(gltfObject.textures[i]);
            }

            for (int i = 0; i < gltfObject.materials?.Length; i++)
            {
                gltfObject.ConstructMaterial(gltfObject.materials[i], i);
            }

            if (gltfObject.scenes == null)
            {
                Debug.LogError($"No scenes found for {gltfObject.Name}");
            }

            for (int i = 0; i < gltfObject.scenes?.Length; i++)
            {
                gltfObject.ConstructScene(gltfObject.scenes[i]);
            }

            return(gltfObject.GameObjectReference);
        }
        private static async Task ConstructTextureAsync(this GltfObject gltfObject, GltfTexture gltfTexture)
        {
            if (gltfTexture.source >= 0)
            {
                GltfImage gltfImage = gltfObject.images[gltfTexture.source];

                // TODO Check if texture is in unity project, and use the asset reference instead.
                await BackgroundThread;

                byte[] imageData;

                if (!string.IsNullOrEmpty(gltfObject.Uri) && !string.IsNullOrEmpty(gltfImage.uri))
                {
                    var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;
                    using (FileStream stream = File.Open($"{parentDirectory}\\{gltfImage.uri}", FileMode.Open))
                    {
                        imageData = new byte[stream.Length];
                        await stream.ReadAsync(imageData, 0, (int)stream.Length);
                    }
                }
                else
                {
                    var imageBufferView = gltfObject.bufferViews[gltfImage.bufferView];
                    imageData = new byte[imageBufferView.byteLength];
                    Array.Copy(imageBufferView.Buffer.BufferData, imageBufferView.byteOffset, imageData, 0, imageData.Length);
                }

                await Update;

                gltfImage.Texture = new Texture2D(2, 2);
                // TODO Load texture async
                gltfImage.Texture.LoadImage(imageData);

                await BackgroundThread;
            }
        }
Ejemplo n.º 21
0
        private async void Start()
        {
            var path = $"{Application.streamingAssetsPath}{uri}";

            path = path.Replace("/", "\\");

            if (!File.Exists(path))
            {
                Debug.LogError($"Unable to find the glTF object at {path}");
                this.DebugText.SetActive(true);
                return;
            }

            this.DebugText.SetActive(false);

            GltfObject gltfObject = null;

            try
            {
                gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path);

                // Put object in front of user
                gltfObject.GameObjectReference.transform.position = new Vector3(0.0f, 0.0f, 1.0f);

                gltfObject.GameObjectReference.transform.localScale *= this.ScaleFactor;
            }
            catch (Exception e)
            {
                Debug.LogError($"{e.Message}\n{e.StackTrace}");
            }

            if (gltfObject != null)
            {
                Debug.Log("Import successful");
            }
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Constructs the glTF Object.
 /// </summary>
 /// <param name="gltfObject"></param>
 /// <returns>The new <see cref="GameObject"/> of the final constructed <see cref="GltfScene"/></returns>
 public static async void Construct(this GltfObject gltfObject)
 {
     await gltfObject.ConstructAsync();
 }
Ejemplo n.º 23
0
        private static async Task <Mesh> ConstructMeshPrimitiveAsync(GltfObject gltfObject, GltfMeshPrimitive meshPrimitive)
        {
            if (Application.isPlaying)
            {
                await BackgroundThread;
            }

            GltfAccessor positionAccessor   = null;
            GltfAccessor normalsAccessor    = null;
            GltfAccessor textCoord0Accessor = null;
            GltfAccessor textCoord1Accessor = null;
            GltfAccessor textCoord2Accessor = null;
            GltfAccessor textCoord3Accessor = null;
            GltfAccessor colorAccessor      = null;
            GltfAccessor indicesAccessor    = null;
            GltfAccessor tangentAccessor    = null;
            GltfAccessor weight0Accessor    = null;
            GltfAccessor joint0Accessor     = null;
            int          vertexCount        = 0;

            if (meshPrimitive.Attributes.POSITION >= 0)
            {
                positionAccessor                   = gltfObject.accessors[meshPrimitive.Attributes.POSITION];
                positionAccessor.BufferView        = gltfObject.bufferViews[positionAccessor.bufferView];
                positionAccessor.BufferView.Buffer = gltfObject.buffers[positionAccessor.BufferView.buffer];
                vertexCount = positionAccessor.count;
            }

            if (meshPrimitive.Attributes.NORMAL >= 0)
            {
                normalsAccessor                   = gltfObject.accessors[meshPrimitive.Attributes.NORMAL];
                normalsAccessor.BufferView        = gltfObject.bufferViews[normalsAccessor.bufferView];
                normalsAccessor.BufferView.Buffer = gltfObject.buffers[normalsAccessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.TEXCOORD_0 >= 0)
            {
                textCoord0Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_0];
                textCoord0Accessor.BufferView        = gltfObject.bufferViews[textCoord0Accessor.bufferView];
                textCoord0Accessor.BufferView.Buffer = gltfObject.buffers[textCoord0Accessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.TEXCOORD_1 >= 0)
            {
                textCoord1Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_1];
                textCoord1Accessor.BufferView        = gltfObject.bufferViews[textCoord1Accessor.bufferView];
                textCoord1Accessor.BufferView.Buffer = gltfObject.buffers[textCoord1Accessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.TEXCOORD_2 >= 0)
            {
                textCoord2Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_2];
                textCoord2Accessor.BufferView        = gltfObject.bufferViews[textCoord2Accessor.bufferView];
                textCoord2Accessor.BufferView.Buffer = gltfObject.buffers[textCoord2Accessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.TEXCOORD_3 >= 0)
            {
                textCoord3Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_3];
                textCoord3Accessor.BufferView        = gltfObject.bufferViews[textCoord3Accessor.bufferView];
                textCoord3Accessor.BufferView.Buffer = gltfObject.buffers[textCoord3Accessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.COLOR_0 >= 0)
            {
                colorAccessor                   = gltfObject.accessors[meshPrimitive.Attributes.COLOR_0];
                colorAccessor.BufferView        = gltfObject.bufferViews[colorAccessor.bufferView];
                colorAccessor.BufferView.Buffer = gltfObject.buffers[colorAccessor.BufferView.buffer];
            }

            if (meshPrimitive.indices >= 0)
            {
                indicesAccessor                   = gltfObject.accessors[meshPrimitive.indices];
                indicesAccessor.BufferView        = gltfObject.bufferViews[indicesAccessor.bufferView];
                indicesAccessor.BufferView.Buffer = gltfObject.buffers[indicesAccessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.TANGENT >= 0)
            {
                tangentAccessor                   = gltfObject.accessors[meshPrimitive.Attributes.TANGENT];
                tangentAccessor.BufferView        = gltfObject.bufferViews[tangentAccessor.bufferView];
                tangentAccessor.BufferView.Buffer = gltfObject.buffers[tangentAccessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.WEIGHTS_0 >= 0)
            {
                weight0Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.WEIGHTS_0];
                weight0Accessor.BufferView        = gltfObject.bufferViews[weight0Accessor.bufferView];
                weight0Accessor.BufferView.Buffer = gltfObject.buffers[weight0Accessor.BufferView.buffer];
            }

            if (meshPrimitive.Attributes.JOINTS_0 >= 0)
            {
                joint0Accessor                   = gltfObject.accessors[meshPrimitive.Attributes.JOINTS_0];
                joint0Accessor.BufferView        = gltfObject.bufferViews[joint0Accessor.bufferView];
                joint0Accessor.BufferView.Buffer = gltfObject.buffers[joint0Accessor.BufferView.buffer];
            }

            if (Application.isPlaying)
            {
                await Update;
            }

            var mesh = new Mesh
            {
                indexFormat = vertexCount > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16,
            };

            if (positionAccessor != null)
            {
                mesh.vertices = await positionAccessor.GetVector3Array();
            }

            if (normalsAccessor != null)
            {
                mesh.normals = await normalsAccessor.GetVector3Array();
            }

            if (textCoord0Accessor != null)
            {
                mesh.uv = await textCoord0Accessor.GetVector2Array();
            }

            if (textCoord1Accessor != null)
            {
                mesh.uv2 = await textCoord1Accessor.GetVector2Array();
            }

            if (textCoord2Accessor != null)
            {
                mesh.uv3 = await textCoord2Accessor.GetVector2Array();
            }

            if (textCoord3Accessor != null)
            {
                mesh.uv4 = await textCoord3Accessor.GetVector2Array();
            }

            if (colorAccessor != null)
            {
                mesh.colors = await colorAccessor.GetColorArray();
            }

            if (indicesAccessor != null)
            {
                mesh.triangles = await indicesAccessor.GetIntArray();
            }

            if (tangentAccessor != null)
            {
                mesh.tangents = await tangentAccessor.GetVector4Array();
            }

            if (weight0Accessor != null && joint0Accessor != null)
            {
                mesh.boneWeights = CreateBoneWeightArray(await joint0Accessor.GetVector4Array(false), await weight0Accessor.GetVector4Array(false), vertexCount);
            }

            mesh.RecalculateBounds();
            meshPrimitive.SubMesh = mesh;
            return(mesh);
        }
Ejemplo n.º 24
0
        private static async Task ConstructMaterialAsync(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId)
        {
            if (Application.isPlaying)
            {
                await Update;
            }
            Shader shader = Shader.Find("Standard");

            if (shader == null)
            {
                Debug.LogWarning("No Standard shader found. Falling back to Legacy Diffuse");
                shader = Shader.Find("Legacy Shaders/Diffuse");
            }

            var material = new Material(shader)
            {
                name = string.IsNullOrEmpty(gltfMaterial.name) ? $"Gltf Material {materialId}" : gltfMaterial.name
            };

            if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0)
            {
                material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture;
            }

            material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue();

            if (shader.name == "Standard")
            {
                if (gltfMaterial.alphaMode == "MASK")
                {
                    material.SetInt(SrcBlend, (int)BlendMode.One);
                    material.SetInt(DstBlend, (int)BlendMode.Zero);
                    material.SetInt(ZWrite, 1);
                    material.SetInt(Mode, 3);
                    material.SetOverrideTag("RenderType", "Cutout");
                    material.EnableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = 2450;
                }
                else if (gltfMaterial.alphaMode == "BLEND")
                {
                    material.SetInt(SrcBlend, (int)BlendMode.One);
                    material.SetInt(DstBlend, (int)BlendMode.OneMinusSrcAlpha);
                    material.SetInt(ZWrite, 0);
                    material.SetInt(Mode, 3);
                    material.SetOverrideTag("RenderType", "Transparency");
                    material.DisableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = 3000;
                }
            }

            if (gltfMaterial.emissiveTexture.index >= 0 && material.HasProperty("_EmissionMap"))
            {
                material.EnableKeyword("_EmissionMap");
                material.EnableKeyword("_EMISSION");
                material.SetTexture(EmissionMap, gltfObject.images[gltfMaterial.emissiveTexture.index].Texture);
                material.SetColor(EmissionColor, gltfMaterial.emissiveFactor.GetColorValue());
            }

            if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0 && material.HasProperty("_MetallicGlossMap"))
            {
                var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture;

                if (texture.isReadable)
                {
                    var pixels = texture.GetPixels();
                    if (Application.isPlaying)
                    {
                        await BackgroundThread;
                    }

                    var pixelCache = new Color[pixels.Length];

                    for (int c = 0; c < pixels.Length; c++)
                    {
                        // Unity only looks for metal in R channel, and smoothness in A.
                        pixelCache[c].r = pixels[c].g;
                        pixelCache[c].g = 0f;
                        pixelCache[c].b = 0f;
                        pixelCache[c].a = pixels[c].b;
                    }

                    if (Application.isPlaying)
                    {
                        await Update;
                    }
                    texture.SetPixels(pixelCache);
                    texture.Apply();

                    material.SetTexture(MetallicGlossMap, gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture);
                }

                material.SetFloat(Glossiness, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f));
                material.SetFloat(Metallic, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.EnableKeyword("_MetallicGlossMap");
                material.EnableKeyword("_METALLICGLOSSMAP");
            }

            if (gltfMaterial.normalTexture.index >= 0 && material.HasProperty("_BumpMap"))
            {
                material.SetTexture(BumpMap, gltfObject.images[gltfMaterial.normalTexture.index].Texture);
                material.EnableKeyword("_BumpMap");
            }

            material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
            gltfMaterial.Material            = material;

            if (Application.isPlaying)
            {
                await BackgroundThread;
            }
        }
Ejemplo n.º 25
0
        private static void ConstructMaterial(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId)
        {
            Shader shader = Shader.Find("Standard");

            if (shader == null)
            {
                Debug.LogWarning("No Standard shader found. Falling back to Legacy Diffuse");
                shader = Shader.Find("Legacy Shaders/Diffuse");
            }

            var material = new Material(shader)
            {
                name = string.IsNullOrEmpty(gltfMaterial.name) ? $"Gltf Material {materialId}" : gltfMaterial.name
            };

            if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0)
            {
                material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture;
            }

            material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue();

            if (shader.name == "Standard")
            {
                if (gltfMaterial.alphaMode == "MASK")
                {
                    material.SetInt("_SrcBlend", (int)BlendMode.One);
                    material.SetInt("_DstBlend", (int)BlendMode.Zero);
                    material.SetInt("_ZWrite", 1);
                    material.SetInt("_Mode", 3);
                    material.SetOverrideTag("RenderType", "Cutout");
                    material.EnableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = 2450;
                }
                else if (gltfMaterial.alphaMode == "BLEND")
                {
                    material.SetInt("_SrcBlend", (int)BlendMode.One);
                    material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
                    material.SetInt("_ZWrite", 0);
                    material.SetInt("_Mode", 3);
                    material.SetOverrideTag("RenderType", "Transparency");
                    material.DisableKeyword("_ALPHATEST_ON");
                    material.DisableKeyword("_ALPHABLEND_ON");
                    material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                    material.renderQueue = 3000;
                }
            }

            if (material.HasProperty("_MetallicGlossMap"))
            {
                // TODO if using extension handle it appropriately.

                if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0)
                {
                    var texture   = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture;
                    var pixels    = texture.GetPixels();
                    var newPixels = new Color[pixels.Length];

                    for (int c = 0; c < pixels.Length; c++)
                    {
                        // Unity only looks for metal in R channel, and smoothness in A.
                        newPixels[c] = new Color(pixels[c].g, 0f, 0f, pixels[c].b);
                    }

                    texture.SetPixels(newPixels);
                    texture.Apply();

                    material.SetTexture("_MetallicGlossMap", gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture);
                }

                material.SetFloat("_Glossiness", Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f));
                material.SetFloat("_Metallic", (float)gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.EnableKeyword("_MetallicGlossMap");
            }

            if (gltfMaterial.normalTexture.index >= 0 && material.HasProperty("_BumpMap"))
            {
                material.SetTexture("_BumpMap", gltfObject.images[gltfMaterial.normalTexture.index].Texture);
                material.EnableKeyword("_BumpMap");
                material.EnableKeyword("_NORMALMAP");
            }

            if (material.HasProperty("_EmissionMap") && material.HasProperty("_EMISSION"))
            {
                var enable = false;
                if (gltfMaterial.emissiveTexture.index >= 0)
                {
                    material.SetTexture("_EmissionMap", gltfObject.images[gltfMaterial.emissiveTexture.index].Texture);
                    material.EnableKeyword("_EmissionMap");
                    enable = true;
                }

                var emissiveColor = gltfMaterial.emissiveFactor.GetColorValue();

                if (gltfMaterial.emissiveFactor != null && emissiveColor != Color.black)
                {
                    material.SetColor("_EmissionColor", emissiveColor);
                    enable = true;
                }

                if (enable)
                {
                    material.EnableKeyword("_EMISSION");
                }
            }

            gltfMaterial.Material = material;
        }
Ejemplo n.º 26
0
        private static async Task ConstructTextureAsync(this GltfObject gltfObject, GltfTexture gltfTexture)
        {
            if (Application.isPlaying)
            {
                await BackgroundThread;
            }

            if (gltfTexture.source >= 0)
            {
                GltfImage gltfImage = gltfObject.images[gltfTexture.source];

                byte[]    imageData = null;
                Texture2D texture   = null;


                if (!string.IsNullOrEmpty(gltfObject.Uri) && !string.IsNullOrEmpty(gltfImage.uri))
                {
                    // TODO update to download and use http paths.
                    var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;
                    var path            = $"{parentDirectory}\\{gltfImage.uri}";

#if UNITY_EDITOR
                    if (Application.isPlaying)
                    {
                        await Update;
                    }
                    var projectPath = path.Replace("\\", "/");
                    projectPath = projectPath.Replace(Application.dataPath, "Assets");
                    texture     = UnityEditor.AssetDatabase.LoadAssetAtPath <Texture2D>(projectPath);

                    if (Application.isPlaying)
                    {
                        await BackgroundThread;
                    }
#endif

                    if (texture == null)
                    {
                        Debug.LogWarning($"Attempting to load asset at {path}");

                        using (FileStream stream = File.Open(path, FileMode.Open))
                        {
                            imageData = new byte[stream.Length];

                            if (Application.isPlaying)
                            {
                                await stream.ReadAsync(imageData, 0, (int)stream.Length);
                            }
                            else
                            {
                                stream.Read(imageData, 0, (int)stream.Length);
                            }
                        }
                    }
                }
                else
                {
                    var imageBufferView = gltfObject.bufferViews[gltfImage.bufferView];
                    imageData = new byte[imageBufferView.byteLength];
                    Array.Copy(imageBufferView.Buffer.BufferData, imageBufferView.byteOffset, imageData, 0, imageData.Length);
                }

                if (texture == null)
                {
                    if (Application.isPlaying)
                    {
                        await Update;
                    }
                    // TODO Load texture async
                    texture           = new Texture2D(2, 2);
                    gltfImage.Texture = texture;
                    gltfImage.Texture.LoadImage(imageData);
                }
                else
                {
                    gltfImage.Texture = texture;
                }

                gltfTexture.Texture = texture;

                if (Application.isPlaying)
                {
                    await BackgroundThread;
                }
            }
        }
        private static async Task ConstructTextureAsync(this GltfObject gltfObject, GltfTexture gltfTexture)
        {
            if (gltfObject.UseBackgroundThread)
            {
                await BackgroundThread;
            }

            if (gltfTexture.source >= 0)
            {
                GltfImage gltfImage = gltfObject.images[gltfTexture.source];

                byte[]    imageData = null;
                Texture2D texture   = null;

                if (!string.IsNullOrEmpty(gltfObject.Uri) && !string.IsNullOrEmpty(gltfImage.uri))
                {
                    var parentDirectory = Directory.GetParent(gltfObject.Uri).FullName;
                    var path            = Path.Combine(parentDirectory, gltfImage.uri);

#if UNITY_EDITOR
                    if (gltfObject.UseBackgroundThread)
                    {
                        await Update;
                    }
                    var projectPath = Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "Assets");
                    texture = UnityEditor.AssetDatabase.LoadAssetAtPath <Texture2D>(projectPath);

                    if (gltfObject.UseBackgroundThread)
                    {
                        await BackgroundThread;
                    }
#endif

                    if (texture == null)
                    {
#if WINDOWS_UWP
                        if (gltfObject.UseBackgroundThread)
                        {
                            try
                            {
                                var storageFile = await StorageFile.GetFileFromPathAsync(path);

                                if (storageFile != null)
                                {
                                    var buffer = await FileIO.ReadBufferAsync(storageFile);

                                    using (DataReader dataReader = DataReader.FromBuffer(buffer))
                                    {
                                        imageData = new byte[buffer.Length];
                                        dataReader.ReadBytes(imageData);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Debug.LogError(e.Message);
                            }
                        }
                        else
                        {
                            imageData = UnityEngine.Windows.File.ReadAllBytes(path);
                        }
#else
                        using (FileStream stream = File.Open(path, FileMode.Open))
                        {
                            imageData = new byte[stream.Length];

                            if (gltfObject.UseBackgroundThread)
                            {
                                await stream.ReadAsync(imageData, 0, (int)stream.Length);
                            }
                            else
                            {
                                stream.Read(imageData, 0, (int)stream.Length);
                            }
                        }
#endif
                    }
                }
                else
                {
                    var imageBufferView = gltfObject.bufferViews[gltfImage.bufferView];
                    imageData = new byte[imageBufferView.byteLength];
                    Array.Copy(imageBufferView.Buffer.BufferData, imageBufferView.byteOffset, imageData, 0, imageData.Length);
                }

                if (texture == null)
                {
                    if (gltfObject.UseBackgroundThread)
                    {
                        await Update;
                    }
                    // TODO Load texture async
                    texture           = new Texture2D(2, 2);
                    gltfImage.Texture = texture;
                    gltfImage.Texture.LoadImage(imageData);
                }
                else
                {
                    gltfImage.Texture = texture;
                }

                gltfTexture.Texture = texture;

                if (gltfObject.UseBackgroundThread)
                {
                    await BackgroundThread;
                }
            }
        }
        private static async Task <Mesh> ConstructMeshPrimitiveAsync(GltfObject gltfObject, GltfMeshPrimitive meshPrimitive)
        {
            if (gltfObject.UseBackgroundThread)
            {
                await BackgroundThread;
            }

            GltfAccessor positionAccessor   = null;
            GltfAccessor normalsAccessor    = null;
            GltfAccessor textCoord0Accessor = null;
            GltfAccessor textCoord1Accessor = null;
            GltfAccessor textCoord2Accessor = null;
            GltfAccessor textCoord3Accessor = null;
            GltfAccessor colorAccessor      = null;
            GltfAccessor indicesAccessor    = null;
            GltfAccessor tangentAccessor    = null;
            GltfAccessor weight0Accessor    = null;
            GltfAccessor joint0Accessor     = null;
            int          vertexCount        = 0;

            positionAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.POSITION);
            if (positionAccessor != null)
            {
                vertexCount = positionAccessor.count;
            }

            normalsAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.NORMAL);

            textCoord0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_0);

            textCoord1Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_1);

            textCoord2Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_2);

            textCoord3Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_3);

            colorAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.COLOR_0);

            indicesAccessor = gltfObject.GetAccessor(meshPrimitive.indices);

            tangentAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TANGENT);

            weight0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.WEIGHTS_0);

            joint0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.JOINTS_0);

            if (gltfObject.UseBackgroundThread)
            {
                await Update;
            }

            var mesh = new Mesh
            {
                indexFormat = vertexCount > UInt16.MaxValue ? IndexFormat.UInt32 : IndexFormat.UInt16,
            };

            if (positionAccessor != null)
            {
                mesh.vertices = positionAccessor.GetVector3Array();
            }

            if (normalsAccessor != null)
            {
                mesh.normals = normalsAccessor.GetVector3Array();
            }

            if (textCoord0Accessor != null)
            {
                mesh.uv = textCoord0Accessor.GetVector2Array();
            }

            if (textCoord1Accessor != null)
            {
                mesh.uv2 = textCoord1Accessor.GetVector2Array();
            }

            if (textCoord2Accessor != null)
            {
                mesh.uv3 = textCoord2Accessor.GetVector2Array();
            }

            if (textCoord3Accessor != null)
            {
                mesh.uv4 = textCoord3Accessor.GetVector2Array();
            }

            if (colorAccessor != null)
            {
                mesh.colors = colorAccessor.GetColorArray();
            }

            if (indicesAccessor != null)
            {
                mesh.triangles = indicesAccessor.GetIntArray();
            }

            if (tangentAccessor != null)
            {
                mesh.tangents = tangentAccessor.GetVector4Array();
            }

            if (weight0Accessor != null && joint0Accessor != null)
            {
                mesh.boneWeights = CreateBoneWeightArray(joint0Accessor.GetVector4Array(false), weight0Accessor.GetVector4Array(false), vertexCount);
            }

            mesh.RecalculateBounds();
            meshPrimitive.SubMesh = mesh;
            return(mesh);
        }
        private static async Task <Material> CreateMRTKShaderMaterial(GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId)
        {
            var shader = Shader.Find("Mixed Reality Toolkit/Standard");

            if (shader == null)
            {
                return(null);
            }

            var material = new Material(shader)
            {
                name = string.IsNullOrEmpty(gltfMaterial.name) ? $"glTF Material {materialId}" : gltfMaterial.name
            };

            if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0)
            {
                material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture;
            }

            material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue();

            if (gltfMaterial.alphaMode == "MASK")
            {
                material.SetInt(SrcBlendId, (int)BlendMode.One);
                material.SetInt(DstBlendId, (int)BlendMode.Zero);
                material.SetInt(ZWriteId, 1);
                material.SetInt(ModeId, 3);
                material.SetOverrideTag("RenderType", "Cutout");
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;
            }
            else if (gltfMaterial.alphaMode == "BLEND")
            {
                material.SetInt(SrcBlendId, (int)BlendMode.One);
                material.SetInt(DstBlendId, (int)BlendMode.OneMinusSrcAlpha);
                material.SetInt(ZWriteId, 0);
                material.SetInt(ModeId, 3);
                material.SetOverrideTag("RenderType", "Transparency");
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
            }

            if (gltfMaterial.emissiveTexture.index >= 0 && material.HasProperty("_EmissionMap"))
            {
                material.EnableKeyword("_EMISSION");
                material.SetColor(EmissiveColorId, gltfMaterial.emissiveFactor.GetColorValue());
            }

            if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0)
            {
                var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture;

                Texture2D occlusionTexture = null;
                if (gltfMaterial.occlusionTexture.index >= 0)
                {
                    occlusionTexture = gltfObject.images[gltfMaterial.occlusionTexture.index].Texture;
                }

                if (texture.isReadable)
                {
                    var     pixels          = texture.GetPixels();
                    Color[] occlusionPixels = null;
                    if (occlusionTexture != null &&
                        occlusionTexture.isReadable)
                    {
                        occlusionPixels = occlusionTexture.GetPixels();
                    }

                    if (gltfObject.UseBackgroundThread)
                    {
                        await BackgroundThread;
                    }

                    var pixelCache = new Color[pixels.Length];

                    for (int c = 0; c < pixels.Length; c++)
                    {
                        pixelCache[c].r = pixels[c].b;                   // MRTK standard shader metallic value, glTF metallic value
                        pixelCache[c].g = occlusionPixels?[c].r ?? 1.0f; // MRTK standard shader occlusion value, glTF occlusion value if available
                        pixelCache[c].b = 0f;                            // MRTK standard shader emission value
                        pixelCache[c].a = (1.0f - pixels[c].g);          // MRTK standard shader smoothness value, invert of glTF roughness value
                    }

                    if (gltfObject.UseBackgroundThread)
                    {
                        await Update;
                    }
                    texture.SetPixels(pixelCache);
                    texture.Apply();

                    material.SetTexture(ChannelMapId, texture);
                    material.EnableKeyword("_CHANNEL_MAP");
                }
                else
                {
                    material.DisableKeyword("_CHANNEL_MAP");
                }

                material.SetFloat(SmoothnessId, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f));
                material.SetFloat(MetallicId, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor);
            }


            if (gltfMaterial.normalTexture.index >= 0)
            {
                material.SetTexture(NormalMapId, gltfObject.images[gltfMaterial.normalTexture.index].Texture);
                material.SetFloat(NormalMapScaleId, (float)gltfMaterial.normalTexture.scale);
                material.EnableKeyword("_NORMAL_MAP");
            }

            if (gltfMaterial.doubleSided)
            {
                material.SetFloat(CullModeId, (float)UnityEngine.Rendering.CullMode.Off);
            }

            material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
            return(material);
        }
        private static async Task <Material> CreateStandardShaderMaterial(GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId)
        {
            var shader = Shader.Find("Standard");

            if (shader == null)
            {
                return(null);
            }

            var material = new Material(shader)
            {
                name = string.IsNullOrEmpty(gltfMaterial.name) ? $"glTF Material {materialId}" : gltfMaterial.name
            };

            if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0)
            {
                material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture;
            }

            material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue();

            if (gltfMaterial.alphaMode == "MASK")
            {
                material.SetInt(SrcBlendId, (int)BlendMode.One);
                material.SetInt(DstBlendId, (int)BlendMode.Zero);
                material.SetInt(ZWriteId, 1);
                material.SetInt(ModeId, 3);
                material.SetOverrideTag("RenderType", "Cutout");
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;
            }
            else if (gltfMaterial.alphaMode == "BLEND")
            {
                material.SetInt(SrcBlendId, (int)BlendMode.One);
                material.SetInt(DstBlendId, (int)BlendMode.OneMinusSrcAlpha);
                material.SetInt(ZWriteId, 0);
                material.SetInt(ModeId, 3);
                material.SetOverrideTag("RenderType", "Transparency");
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
            }

            if (gltfMaterial.emissiveTexture.index >= 0)
            {
                material.EnableKeyword("_EmissionMap");
                material.EnableKeyword("_EMISSION");
                material.SetTexture(EmissionMapId, gltfObject.images[gltfMaterial.emissiveTexture.index].Texture);
                material.SetColor(EmissionColorId, gltfMaterial.emissiveFactor.GetColorValue());
            }

            if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0)
            {
                var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture;

                if (texture.isReadable)
                {
                    var pixels = texture.GetPixels();
                    if (gltfObject.UseBackgroundThread)
                    {
                        await BackgroundThread;
                    }

                    var pixelCache = new Color[pixels.Length];

                    for (int c = 0; c < pixels.Length; c++)
                    {
                        // Unity only looks for metal in R channel, and smoothness in A.
                        pixelCache[c].r = pixels[c].g;
                        pixelCache[c].g = 0f;
                        pixelCache[c].b = 0f;
                        pixelCache[c].a = pixels[c].b;
                    }

                    if (gltfObject.UseBackgroundThread)
                    {
                        await Update;
                    }
                    texture.SetPixels(pixelCache);
                    texture.Apply();

                    material.SetTexture(MetallicGlossMapId, texture);
                }

                material.SetFloat(GlossinessId, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f));
                material.SetFloat(MetallicId, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor);
                material.EnableKeyword("_MetallicGlossMap");
                material.EnableKeyword("_METALLICGLOSSMAP");
            }

            if (gltfMaterial.normalTexture.index >= 0)
            {
                material.SetTexture(BumpMapId, gltfObject.images[gltfMaterial.normalTexture.index].Texture);
                material.EnableKeyword("_BumpMap");
            }

            material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
            return(material);
        }