UniVRM/Assets/VRM10_Samples/VRM10Viewer/TinyPbrDescriptorGenerator.cs
2025-02-04 16:38:40 +09:00

84 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniGLTF;
using UnityEngine;
namespace UniVRM10.VRM10Viewer
{
/// <summary>
/// GLTF の MaterialImporter
/// </summary>
public sealed class TinyPbrDescriptorGenerator : IMaterialDescriptorGenerator
{
public UrpGltfPbrMaterialImporter PbrMaterialImporter { get; } = new();
public UrpGltfDefaultMaterialImporter DefaultMaterialImporter { get; } = new();
public Material Material { get; set; }
public TinyPbrDescriptorGenerator(Material material)
{
Material = material;
}
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),
Material.shader,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new List<Action<Material>>(),
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 TinyPbrContext(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;
}
}
}
}
}