From e7d850f51d8805931408d1a76ea728ebffc570f6 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 7 Jun 2024 18:19:01 +0900 Subject: [PATCH] use DefaultMaterial if gltfPrimitive.material is not exists or -1 --- .../Runtime/Extensions/IndexExtensions.cs | 19 +++++++++++++ .../Runtime/UniGLTF/IO/ImporterContext.cs | 24 ++++++++++------- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 13 +++++---- .../Material/Importer/MaterialFactory.cs | 27 +++++++++++++++++-- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/Assets/UniGLTF/Runtime/Extensions/IndexExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/IndexExtensions.cs index 7599e5b95..e855768a5 100644 --- a/Assets/UniGLTF/Runtime/Extensions/IndexExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/IndexExtensions.cs @@ -15,5 +15,24 @@ namespace UniGLTF } return true; } + + public static bool HasValidIndex(this int? self, int collectionLength) + { + if (!self.HasValue) + { + return false; + } + if (self.Value < 0) + { + // 古いモデルで index の無効値に -1 を使っている場合がある + return false; + } + if (self.Value >= collectionLength) + { + // ついでに上限もチェック + return false; + } + return true; + } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index fba947b0e..a2605d732 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -49,7 +49,8 @@ namespace UniGLTF Data.MigrationFlags.IsRoughnessTextureValueSquared); MaterialFactory = new MaterialFactory(ExternalObjectMap .Where(x => x.Value is Material) - .ToDictionary(x => x.Key, x => (Material)x.Value)); + .ToDictionary(x => x.Key, x => (Material)x.Value), + MaterialDescriptorGenerator.GetGltfDefault()); AnimationClipFactory = new AnimationClipFactory(ExternalObjectMap .Where(x => x.Value is AnimationClip) .ToDictionary(x => x.Key, x => (AnimationClip)x.Value)); @@ -285,14 +286,7 @@ namespace UniGLTF throw new ArgumentNullException(); } - if (Data.GLTF.materials == null || Data.GLTF.materials.Count == 0) - { - // no material. work around. - // TODO: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#default-material - var param = MaterialDescriptorGenerator.GetGltfDefault(); - await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync, awaitCaller); - } - else + if (Data.GLTF.materials != null) { for (int i = 0; i < Data.GLTF.materials.Count; ++i) { @@ -314,7 +308,17 @@ namespace UniGLTF using (MeasureTime("BuildMesh")) { var meshWithMaterials = await MeshUploader.BuildMeshAndUploadAsync(awaitCaller, meshData, - (int? materialIndex) => materialIndex.HasValidIndex() ? MaterialFactory.GetMaterial(materialIndex.Value) : null); + (int? materialIndex) => + { + if (materialIndex.HasValidIndex()) + { + return MaterialFactory.GetMaterial(materialIndex.Value); + } + else + { + return MaterialFactory.DefaultMaterial; + } + }); var mesh = meshWithMaterials.Mesh; // mesh name diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index e75572cb6..352e8807d 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -240,7 +240,7 @@ namespace UniVRM10 continue; } - CreateRenderer(node, go, map, MaterialFactory.Materials); + CreateRenderer(node, go, map, MaterialFactory); await awaitCaller.NextFrame(); } } @@ -802,8 +802,7 @@ namespace UniVRM10 /// /// MeshFilter + MeshRenderer もしくは SkinnedMeshRenderer を構築する /// - public static Renderer CreateRenderer(VrmLib.Node node, GameObject go, ModelMap map, - IReadOnlyList materialLoadInfos) + public static Renderer CreateRenderer(VrmLib.Node node, GameObject go, ModelMap map, MaterialFactory materialFactory) { Renderer renderer = null; var hasBlendShape = node.MeshGroup.Meshes[0].MorphTargets.Any(); @@ -842,11 +841,11 @@ namespace UniVRM10 { if (x.Material.HasValidIndex()) { - return materialLoadInfos[x.Material.Value].Asset; + return materialFactory.Materials[x.Material.Value].Asset; } else { - return null; + return materialFactory.DefaultMaterial; } } ).ToArray(); @@ -858,11 +857,11 @@ namespace UniVRM10 { if (x.Submeshes[0].Material.HasValidIndex()) { - return materialLoadInfos[x.Submeshes[0].Material.Value].Asset; + return materialFactory.Materials[x.Submeshes[0].Material.Value].Asset; } else { - return null; + return materialFactory.DefaultMaterial; } } ).ToArray(); diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialFactory.cs b/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialFactory.cs index 882818fbb..0e578c92c 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialFactory.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialFactory.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using UnityEngine; @@ -13,9 +12,33 @@ namespace VRMShaders { private readonly IReadOnlyDictionary m_externalMap; - public MaterialFactory(IReadOnlyDictionary externalMaterialMap) + MaterialDescriptor m_defaultMaterialParams; + + /// + /// gltfPritmitive.material が無い場合のデフォルトマテリアル + /// https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#default-material + /// + Material m_defaultMaterial; + + public Material DefaultMaterial + { + get + { + if (m_defaultMaterial == null) + { + // default material にバリエーションがある? + var task = LoadAsync(m_defaultMaterialParams, (_x, _y) => Task.FromResult(null), new ImmediateCaller()); + task.Wait(); + m_defaultMaterial = task.Result; + } + return m_defaultMaterial; + } + } + + public MaterialFactory(IReadOnlyDictionary externalMaterialMap, MaterialDescriptor defaultMaterialParams) { m_externalMap = externalMaterialMap; + m_defaultMaterialParams = defaultMaterialParams; } public struct MaterialLoadInfo