using System; using System.Collections.Generic; using System.Threading.Tasks; using UniGLTF; using Unity.IO.LowLevel.Unsafe; using UnityEngine; namespace UniVRM10.VRM10Viewer { /// /// GLTF の MaterialImporter /// public sealed class CustomMaterialDescriptorGenerator : IMaterialDescriptorGenerator { public UrpGltfPbrMaterialImporter PbrMaterialImporter { get; } = new(); public UrpGltfDefaultMaterialImporter DefaultMaterialImporter { get; } = new(); public Material CustomMaterial { get; set; } public CustomMaterialDescriptorGenerator(Material customMaterial) { CustomMaterial = customMaterial; } public MaterialDescriptor Get(GltfData data, int i) { // TODO: VRM // UNLIT MaterialDescriptor param; // if (BuiltInGltfUnlitMaterialImporter.TryCreateParam(data, i, out param)) return param; if (TryCreateParam(data, i, out param)) return param; // NOTE: Fallback to default material if (Symbols.VRM_DEVELOP) { Debug.LogWarning($"material: {i} out of range. fallback"); } return GetGltfDefault(GltfMaterialImportUtils.ImportMaterialName(i, null)); } public MaterialDescriptor GetGltfDefault(string materialName = null) => DefaultMaterialImporter.CreateParam(materialName); public bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc) { if (i < 0 || i >= data.GLTF.materials.Count) { matDesc = default; return false; } var src = data.GLTF.materials[i]; matDesc = new MaterialDescriptor( GltfMaterialImportUtils.ImportMaterialName(i, src), CustomMaterial.shader, null, new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary(), new List>(), new[] { (MaterialDescriptor.MaterialGenerateAsyncFunc)AsyncAction } ); return true; Task AsyncAction(Material x, GetTextureAsyncFunc y, IAwaitCaller z) => GenerateMaterialAsync(data, src, x, y, z); } public static async Task GenerateMaterialAsync(GltfData data, glTFMaterial src, Material dst, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller) { var context = new CustomMaterialContext(dst); if (src is { pbrMetallicRoughness: { baseColorTexture: { index: >= 0 } } }) { if (GltfPbrTextureImporter.TryBaseColorTexture(data, src, out _, out var desc)) { context.BaseTexture = await getTextureAsync(desc, awaitCaller); context.BaseTextureOffset = desc.Offset; context.BaseTextureScale = desc.Scale; } } } } }