TextureFactory.m_textureCache の使い方を整理、テスト追加

This commit is contained in:
ousttrue 2021-03-25 15:37:39 +09:00
parent f2b82200f1
commit 2d4d5315ba
5 changed files with 180 additions and 73 deletions

View File

@ -49,30 +49,6 @@ namespace UniGLTF
public readonly Dictionary<string, Texture2D> ExternalMap;
public bool TryGetExternal(TextureImportParam param, bool used, out Texture2D external)
{
if (param.Index0!=null && ExternalMap != null)
{
var cacheName = param.ConvertedName;
if (param.TextureType == TextureImportTypes.NormalMap)
{
cacheName = param.GltfName;
if (m_textureCache.TryGetValue(cacheName, out TextureLoadInfo normalInfo))
{
external = normalInfo.Texture;
return true;
}
}
if (ExternalMap.TryGetValue(cacheName, out external))
{
m_textureCache.Add(cacheName, new TextureLoadInfo(external, used, true));
return true;
}
}
external = default;
return false;
}
public TextureFactory(glTF gltf, IStorage storage, IEnumerable<(string, UnityEngine.Object)> externalMap)
{
m_gltf = gltf;
@ -128,6 +104,12 @@ namespace UniGLTF
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="string"></typeparam>
/// <typeparam name="TextureLoadInfo"></typeparam>
/// <returns></returns>
Dictionary<string, TextureLoadInfo> m_textureCache = new Dictionary<string, TextureLoadInfo>();
public IEnumerable<TextureLoadInfo> Textures => m_textureCache.Values;
@ -223,43 +205,58 @@ namespace UniGLTF
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(IAwaitCaller awaitCaller, glTF gltf, TextureImportParam param)
{
if (m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo cacheInfo))
//
// ExtractKey で External とのマッチングを試みる
//
// Normal => GltfName
// Standard => ConvertedName
// sRGB => GltfName
// Linear => GltfName
//
if (param.Index0 != null && ExternalMap != null)
{
return cacheInfo.Texture;
}
if (TryGetExternal(param, true, out Texture2D external))
{
return external;
if (ExternalMap.TryGetValue(param.ExtractKey, out Texture2D external))
{
return external;
}
}
switch (param.TextureType)
{
case TextureImportTypes.NormalMap:
// Runtime/SubAsset 用に変換する
{
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index0, RenderTextureReadWrite.Linear, false);
var converted = NormalConverter.Import(baseTexture.Texture);
converted.name = param.ConvertedName;
var info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
if (!m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo info))
{
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index0, RenderTextureReadWrite.Linear, false);
var converted = NormalConverter.Import(baseTexture.Texture);
converted.name = param.ConvertedName;
info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
}
return info.Texture;
}
case TextureImportTypes.StandardMap:
// 変換する
{
TextureLoadInfo baseTexture = default;
if (param.Index0!=null)
if (!m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo info))
{
baseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index0, RenderTextureReadWrite.Linear, false);
TextureLoadInfo baseTexture = default;
if (param.Index0!=null)
{
baseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index0, RenderTextureReadWrite.Linear, false);
}
TextureLoadInfo occlusionBaseTexture = default;
if (param.Index1!=null)
{
occlusionBaseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index1, RenderTextureReadWrite.Linear, false);
}
var converted = OcclusionMetallicRoughnessConverter.Import(baseTexture.Texture, param.MetallicFactor, param.RoughnessFactor, occlusionBaseTexture.Texture);
converted.name = param.ConvertedName;
info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
}
TextureLoadInfo occlusionBaseTexture = default;
if (param.Index1!=null)
{
occlusionBaseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index1, RenderTextureReadWrite.Linear, false);
}
var converted = OcclusionMetallicRoughnessConverter.Import(baseTexture.Texture, param.MetallicFactor, param.RoughnessFactor, occlusionBaseTexture.Texture);
converted.name = param.ConvertedName;
var info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
return info.Texture;
}
@ -268,9 +265,9 @@ namespace UniGLTF
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, param, param.Index0, RenderTextureReadWrite.sRGB, true);
return baseTexture.Texture;
}
throw new NotImplementedException();
}
throw new NotImplementedException();
}
public static TextureImportParam CreateSRGB(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
@ -327,8 +324,7 @@ namespace UniGLTF
throw new ArgumentOutOfRangeException();
}
var gltfImage = gltf.images[gltfTexture.source];
var convertedName = TextureImportName.Convert(gltfTexture.name, textureType);
return new TextureImportName(gltfTexture.name, convertedName, gltfImage.GetExt(), gltfImage.uri);
return new TextureImportName(textureType, gltfTexture.name, gltfImage.GetExt(), gltfImage.uri);
}
public static SamplerParam CreateSampler(glTF gltf, int index)

View File

@ -12,51 +12,71 @@ namespace VRM
{
m_vrm = vrm;
}
public IEnumerable<TextureImportParam> EnumerateMaterial(GltfParser parser, glTF_VRM_Material vrmMaterial)
{
// MToon
var offsetScaleMap = new Dictionary<string, float[]>();
foreach (var kv in vrmMaterial.vectorProperties)
{
if (vrmMaterial.textureProperties.ContainsKey(kv.Key))
{
// texture offset & scale
offsetScaleMap.Add(kv.Key, kv.Value);
}
}
foreach (var kv in vrmMaterial.textureProperties)
{
var (offset, scale) = (Vector2.zero, Vector2.one);
if (offsetScaleMap.TryGetValue(kv.Key, out float[] value))
{
offset = new Vector2(value[0], value[1]);
scale = new Vector2(value[2], value[3]);
}
// SRGB color or normalmap
yield return VRMTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, default, default);
}
}
public IEnumerable<TextureImportParam> Enumerate(GltfParser parser)
{
var used = new HashSet<string>();
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
var vrmMaterial = m_vrm.materialProperties[i];
if (vrmMaterial.shader == MToon.Utils.ShaderName)
{
// MToon
var offsetScaleMap = new Dictionary<string, float[]>();
foreach (var kv in vrmMaterial.vectorProperties)
foreach(var textureInfo in EnumerateMaterial(parser, vrmMaterial))
{
if (vrmMaterial.textureProperties.ContainsKey(kv.Key))
if (used.Add(textureInfo.ExtractKey))
{
// texture offset & scale
offsetScaleMap.Add(kv.Key, kv.Value);
yield return textureInfo;
}
}
foreach (var kv in vrmMaterial.textureProperties)
{
var (offset, scale) = (Vector2.zero, Vector2.one);
if (offsetScaleMap.TryGetValue(kv.Key, out float[] value))
{
offset = new Vector2(value[0], value[1]);
scale = new Vector2(value[2], value[3]);
}
// SRGB color or normalmap
yield return VRMTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, default, default);
}
}
}
else
{
// PBR or Unlit
foreach (var textureInfo in GltfTextureEnumerator.EnumerateTextures(parser, parser.GLTF.materials[i]))
{
yield return textureInfo;
}
if (used.Add(textureInfo.ExtractKey))
{
yield return textureInfo;
}
}
}
}
// thumbnail
if (m_vrm.meta != null && m_vrm.meta.texture != -1)
{
yield return TextureFactory.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
var textureInfo = TextureFactory.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
if (used.Add(textureInfo.ExtractKey))
{
yield return textureInfo;
}
}
}
}

View File

@ -4,7 +4,8 @@
"VRM",
"UniGLTF",
"MeshUtility",
"MeshUtility.Editor"
"MeshUtility.Editor",
"VRMShaders"
],
"optionalUnityReferences": [
"TestAssemblies"

View File

@ -0,0 +1,79 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using UniGLTF;
namespace VRM
{
public class VRMTextureEnumerateTests
{
/// <summary>
/// Test uniqueness
/// </summary>
[Test]
public void TextureEnumerationTest()
{
{
var parser = new GltfParser
{
GLTF = new glTF
{
images = new List<glTFImage>
{
new glTFImage{
mimeType = "image/png",
}
},
textures = new List<glTFTexture>
{
new glTFTexture{
source = 0,
}
},
materials = new List<glTFMaterial>
{
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
}
}
};
var vrm = new glTF_VRM_extensions
{
materialProperties = new List<glTF_VRM_Material>
{
new glTF_VRM_Material
{
textureProperties = new Dictionary<string, int>
{
{"_MainTex", 0},
}
},
new glTF_VRM_Material
{
textureProperties = new Dictionary<string, int>
{
{"_MainTex", 0},
}
},
}
};
var items = new VRMTextureEnumerator(vrm).Enumerate(parser).ToArray();
Assert.AreEqual(1, items.Length);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72dc7f800d853bd4289ac73fe53e499f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: