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;
            }
        }
Example #2
0
        static void LoadCommonParams(this Material self, GltfMaterial material, List <Texture> textures)
        {
            var pbr = material.pbrMetallicRoughness;

            if (pbr != null)
            {
                if (pbr.baseColorFactor != null)
                {
                    self.BaseColorFactor = LinearColor.FromLiner(
                        pbr.baseColorFactor[0],
                        pbr.baseColorFactor[1],
                        pbr.baseColorFactor[2],
                        pbr.baseColorFactor[3]);
                }
                var baseColorTexture = pbr.baseColorTexture;
                if (baseColorTexture != null)
                {
                    self.BaseColorTexture = new TextureInfo(textures[baseColorTexture.index]);
                }
            }

            self.AlphaMode   = (VrmLib.AlphaModeType)material.alphaMode;
            self.AlphaCutoff = material.alphaCutoff;
            self.DoubleSided = material.doubleSided;
        }
Example #3
0
        private Material readMaterial(int index)
        {
            if (_materialMap.TryGetValue(index, out Material material))
            {
                return(material);
            }

            GltfMaterial gltfMaterial = _root.Materials[index];

            material = new Material(gltfMaterial.Name);
            _materialMap.Add(index, material);

            //TODO: implement gltf material reader
            if (gltfMaterial.PbrMetallicRoughness != null)
            {
                byte r = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[0] * 255);
                byte g = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[1] * 255);
                byte b = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[2] * 255);
                byte a = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[3] * 255);

                material.AmbientColor  = new Color(r, g, b, a);
                material.DiffuseColor  = new Color(r, g, b, a);
                material.SpecularColor = new Color(r, g, b, a);
            }

            return(material);
        }
Example #4
0
        public static UnlitMaterial UnlitFromGltf(GltfMaterial material, List <Texture> textures)
        {
            var unlit = new UnlitMaterial(material.name);

            unlit.LoadCommonParams(material, textures);
            return(unlit);
        }
Example #5
0
 public static Material FromGltf(this GltfMaterial x, List <Texture> textures)
 {
     return(x.IsUnlit()
     ? (Material)UnlitFromGltf(x, textures)
     : (Material)PBRFromGltf(x, textures)
            );
 }
Example #6
0
 static GltfImage GetNormalImage(GltfSerialization.GltfStorage storage, GltfMaterial m)
 {
     if (m.normalTexture == null)
     {
         return(null);
     }
     return(GetTexture(storage, m.normalTexture.index));
 }
Example #7
0
        public static PBRMaterial PBRFromGltf(GltfMaterial material, List <Texture> textures)
        {
            var self = new PBRMaterial(material.name);

            self.LoadCommonParams(material, textures);

            //
            // pbr
            //
            var pbr = material.pbrMetallicRoughness;

            // metallic roughness
            self.MetallicFactor  = pbr.metallicFactor;
            self.RoughnessFactor = pbr.roughnessFactor;
            var metallicRoughnessTexture = pbr.metallicRoughnessTexture;

            if (metallicRoughnessTexture != null)
            {
                self.MetallicRoughnessTexture = textures[metallicRoughnessTexture.index];
            }
            //
            // emissive
            //
            if (material.emissiveFactor != null)
            {
                self.EmissiveFactor = new Vector3(
                    material.emissiveFactor[0], material.emissiveFactor[1], material.emissiveFactor[2]);
            }
            var emissiveTexture = material.emissiveTexture;

            if (emissiveTexture != null)
            {
                self.EmissiveTexture = textures[emissiveTexture.index];
            }
            //
            // normal
            //
            var normalTexture = material.normalTexture;

            if (normalTexture != null)
            {
                self.NormalTexture = textures[normalTexture.index];
            }
            //
            // occlusion
            //
            var occlusionTexture = material.occlusionTexture;

            if (occlusionTexture != null)
            {
                self.OcclusionTexture = textures[occlusionTexture.index];
            }

            return(self);
        }
Example #8
0
 static GltfImage GetColorImage(GltfSerialization.GltfStorage storage, GltfMaterial m)
 {
     if (m.pbrMetallicRoughness == null)
     {
         return(null);
     }
     if (m.pbrMetallicRoughness.baseColorTexture == null)
     {
         return(null);
     }
     return(GetTexture(storage, m.pbrMetallicRoughness.baseColorTexture.index));
 }
Example #9
0
        /// Glb interface. bin is binary chunk
        public GltfStorage(FileInfo path, ArraySegment <byte> json, Memory <byte> bin)
        {
            OriginalJson = json;
            Gltf         = Generated.GltfDeserializer.Deserialize(json.ParseAsJson());

            Path = path;
            Json = new Utf8String(json);

            if (!bin.IsEmpty)
            {
                // glb
                MemoryMarshal.TryGetArray(bin, out ArraySegment <byte> segment);
                Buffers.Add(new SimpleBuffer(segment));
            }
            else
            {
                // gltf
                var baseDir = path.Directory.FullName;
                Buffers.AddRange(Gltf.buffers.Select(x => new UriByteBuffer(baseDir, x.uri)));
            }

            if (Gltf.extensions != null && Gltf.extensions.VRM != null)
            {
                // VRM
                if (Gltf.extensions.VRM.humanoid != null)
                {
                    Gltf.extensions.VRM.humanoid.humanBones =
                        Gltf.extensions.VRM.humanoid.humanBones.OrderBy(x => x.bone).ToList();
                }
            }

            if (!Gltf.materials.Any())
            {
                // default material
                Gltf.materials.Add(GltfMaterial.CreateDefault("__default__"));
            }
        }
Example #10
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;
            }
        }
        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);
        }
        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);
        }
Example #13
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;
        }