Merge pull request #872 from ousttrue/feature/extract_key

Feature/extract key
This commit is contained in:
ousttrue 2021-04-14 20:12:05 +09:00 committed by GitHub
commit ed0cfb1f27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 266 additions and 261 deletions

View File

@ -50,33 +50,25 @@ namespace UniGLTF
s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials");
if (s_foldMaterials)
{
importer.DrawRemapGUI<UnityEngine.Material>(parser.GLTF.materials.Select(x => x.name));
importer.DrawRemapGUI<UnityEngine.Material>(parser.GLTF.materials.Select(x => new SubAssetKey(typeof(Material), x.name)));
}
s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures");
if (s_foldTextures)
{
var names = enumTextures(parser)
.Select(x =>
importer.DrawRemapGUI<UnityEngine.Texture2D>(enumTextures(parser)
.Where(x =>
{
if (x.TextureType != TextureImportTypes.StandardMap && !string.IsNullOrEmpty(x.Uri))
var (key, param) = x;
if ((param.TextureType == TextureImportTypes.sRGB || param.TextureType == TextureImportTypes.NormalMap) && !string.IsNullOrEmpty(param.Uri))
{
// GLTF の 無変換テクスチャーをスキップする
return null;
}
switch (x.TextureType)
{
case TextureImportTypes.NormalMap:
return x.GltfName;
default:
return x.ConvertedName;
return false;
}
return true;
})
.Where(x => !string.IsNullOrEmpty(x))
;
importer.DrawRemapGUI<UnityEngine.Texture2D>(names);
.Select(x => x.Key)
);
}
if (GUILayout.Button("Clear"))
@ -100,9 +92,9 @@ namespace UniGLTF
return;
}
Action<Texture2D> addRemap = externalObject =>
Action<SubAssetKey, Texture2D> addRemap = (key, externalObject) =>
{
self.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject);
self.AddRemap(new AssetImporter.SourceAssetIdentifier(key.Type, key.Name), externalObject);
};
Action<IEnumerable<UnityPath>> onCompleted = _ =>
{
@ -133,9 +125,9 @@ namespace UniGLTF
Directory.CreateDirectory(path);
}
foreach (var asset in importer.GetSubAssets<Material>(importer.assetPath))
foreach (var (key, asset) in importer.GetSubAssets<Material>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.mat", false);
asset.ExtractSubAsset($"{path}/{key.Name}.mat", false);
}
}
}

View File

@ -23,37 +23,34 @@ namespace UniGLTF
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
}
public static IEnumerable<T> GetSubAssets<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
public static IEnumerable<(SubAssetKey, T)> GetSubAssets<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
{
return AssetDatabase
.LoadAllAssetsAtPath(assetPath)
.Where(x => AssetDatabase.IsSubAsset(x))
.Where(x => x is T)
.Select(x => x as T);
.Select(x => (new SubAssetKey(typeof(T), x.name), x as T));
}
public static void DrawRemapGUI<T>(this ScriptedImporter importer, IEnumerable<string> names) where T : UnityEngine.Object
public static void DrawRemapGUI<T>(this ScriptedImporter importer, IEnumerable<SubAssetKey> keys) where T : UnityEngine.Object
{
EditorGUI.indentLevel++;
{
var map = importer.GetExternalObjectMap()
.Select(x => (x.Key.name, x.Value as T))
.Where(x => x.Item2 != null)
.ToDictionary(x => x.Item1, x => x.Item2)
;
foreach (var name in names)
var map = importer.GetExternalObjectMap();
foreach (var key in keys)
{
if (string.IsNullOrEmpty(name))
if (string.IsNullOrEmpty(key.Name))
{
throw new System.ArgumentNullException();
continue;
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(name);
map.TryGetValue(name, out T value);
EditorGUILayout.PrefixLabel(key.Name);
map.TryGetValue(new AssetImporter.SourceAssetIdentifier(key.Type, key.Name), out UnityEngine.Object value);
var asset = EditorGUILayout.ObjectField(value, typeof(T), true) as T;
if (asset != value)
{
// update
importer.SetExternalUnityObject(new AssetImporter.SourceAssetIdentifier(value), asset);
}
EditorGUILayout.EndHorizontal();

View File

@ -42,7 +42,7 @@ namespace UniGLTF
using (var loader = new ImporterContext(parser, externalObjectMap.Concat(externalTextures)))
{
// settings TextureImporters
foreach (var textureInfo in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
{
TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
}
@ -69,7 +69,7 @@ namespace UniGLTF
GltfParser parser, UnityPath dir)
{
var used = new HashSet<Texture2D>();
foreach (var texParam in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
foreach (var (key, texParam) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
{
switch (texParam.TextureType)
{

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
using UniGLTF;
using System.Linq;
using VRMShaders;
@ -18,11 +19,11 @@ namespace UniGLTF
public glTF GLTF => m_parser.GLTF;
public IStorage Storage => m_parser.Storage;
public readonly Dictionary<UnityPath, TextureImportParam> Textures = new Dictionary<UnityPath, TextureImportParam>();
UnityEngine.Texture2D[] m_subAssets;
public readonly Dictionary<SubAssetKey, UnityPath> Textures = new Dictionary<SubAssetKey, UnityPath>();
(SubAssetKey Key, UnityEngine.Texture2D Value)[] m_subAssets;
UnityPath m_textureDirectory;
public TextureExtractor(GltfParser parser, UnityPath textureDirectory, UnityEngine.Texture2D[] subAssets)
public TextureExtractor(GltfParser parser, UnityPath textureDirectory, (SubAssetKey, UnityEngine.Texture2D)[] subAssets)
{
m_parser = parser;
m_textureDirectory = textureDirectory;
@ -41,28 +42,29 @@ namespace UniGLTF
return Path.GetExtension(uri).ToLower();
}
public void Extract(TextureImportParam param)
public void Extract(SubAssetKey key, TextureImportParam param)
{
if (Textures.Values.Contains(param))
if (Textures.ContainsKey(key))
{
return;
}
UnityPath targetPath = default;
if (!string.IsNullOrEmpty(param.Uri) && !param.ExtractConverted)
{
targetPath = m_textureDirectory.Child(param.GltfFileName);
// use GLTF external
// targetPath = m_textureDirectory.Child(key.Name);
}
else
{
UnityPath targetPath = default;
switch (param.TextureType)
{
case TextureImportTypes.StandardMap:
{
// write converted texture
var subAsset = m_subAssets.FirstOrDefault(x => x.name == param.ConvertedName);
targetPath = m_textureDirectory.Child(param.ConvertedFileName);
var (_, subAsset) = m_subAssets.FirstOrDefault(x => x.Equals(key));
targetPath = m_textureDirectory.Child($"{key.Name}.png");
File.WriteAllBytes(targetPath.FullPath, subAsset.EncodeToPNG().ToArray());
targetPath.ImportAsset();
break;
@ -71,15 +73,14 @@ namespace UniGLTF
default:
{
// write original bytes
targetPath = m_textureDirectory.Child(param.GltfFileName);
targetPath = m_textureDirectory.Child($"{key.Name}{param.Ext}");
File.WriteAllBytes(targetPath.FullPath, param.Index0().Result.ToArray());
targetPath.ImportAsset();
break;
}
}
Textures.Add(key, targetPath);
}
Textures.Add(targetPath, param);
}
/// <summary>
@ -93,37 +94,44 @@ namespace UniGLTF
/// <param name="dirName"></param>
/// <param name="onCompleted"></param>
public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
EnumerateAllTexturesDistinctFunc textureEnumerator, Texture2D[] subAssets, Action<Texture2D> addRemap,
EnumerateAllTexturesDistinctFunc textureEnumerator, (SubAssetKey, Texture2D)[] subAssets,
Action<SubAssetKey, Texture2D> addRemap,
Action<IEnumerable<UnityPath>> onCompleted = null)
{
var extractor = new TextureExtractor(parser, textureDirectory, subAssets);
foreach (var x in textureEnumerator(parser))
foreach (var (key, x) in textureEnumerator(parser))
{
extractor.Extract(x);
extractor.Extract(key, x);
}
EditorApplication.delayCall += () =>
{
// Wait for the texture assets to be imported
foreach (var kv in extractor.Textures)
foreach (var (key, targetPath) in extractor.Textures)
{
var targetPath = kv.Key;
var param = kv.Value;
// remap
var externalObject = targetPath.LoadAsset<Texture2D>();
if (externalObject != null)
{
addRemap(externalObject);
addRemap(key, externalObject);
}
}
if (onCompleted != null)
{
onCompleted(extractor.Textures.Keys);
onCompleted(extractor.Textures.Values);
}
};
}
}
public static class KeyValuePariExtensions
{
public static void Deconstruct<T, U>(this KeyValuePair<T, U> pair, out T key, out U value)
{
key = pair.Key;
value = pair.Value;
}
}
}

View File

@ -68,7 +68,7 @@ namespace UniGLTF
{
case TextureImportTypes.NormalMap:
{
if (ExternalMap.TryGetValue(textureInfo.GltfName, out Texture2D external))
if (ExternalMap.TryGetValue(textureInfo.UnityObjectName, out Texture2D external))
{
ConfigureSize(external);
ConfigureNormalMap(external);
@ -78,7 +78,7 @@ namespace UniGLTF
case TextureImportTypes.StandardMap:
{
if (ExternalMap.TryGetValue(textureInfo.ConvertedName, out Texture2D external))
if (ExternalMap.TryGetValue(textureInfo.UnityObjectName, out Texture2D external))
{
ConfigureSize(external);
ConfigureLinear(external);
@ -88,7 +88,7 @@ namespace UniGLTF
case TextureImportTypes.sRGB:
{
if (ExternalMap.TryGetValue(textureInfo.GltfName, out Texture2D external))
if (ExternalMap.TryGetValue(textureInfo.UnityObjectName, out Texture2D external))
{
ConfigureSize(external);
}

View File

@ -47,7 +47,7 @@ namespace MeshUtility
value = prefab;
isPrefab = true;
}
catch (ArgumentException ex)
catch (ArgumentException)
{
// Debug.LogWarning(ex);
}

View File

@ -49,13 +49,13 @@ namespace UniGLTF
Transparent
}
public static TextureImportParam BaseColorTexture(GltfParser parser, glTFMaterial src)
public static (SubAssetKey, TextureImportParam Param) BaseColorTexture(GltfParser parser, glTFMaterial src)
{
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
return GltfTextureImporter.CreateSRGB(parser, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
}
public static TextureImportParam StandardTexture(GltfParser parser, glTFMaterial src)
public static (SubAssetKey, TextureImportParam) StandardTexture(GltfParser parser, glTFMaterial src)
{
var metallicFactor = 1.0f;
var roughnessFactor = 1.0f;
@ -65,15 +65,17 @@ namespace UniGLTF
roughnessFactor = src.pbrMetallicRoughness.roughnessFactor;
}
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.metallicRoughnessTexture);
return GltfTextureImporter.CreateStandard(parser,
var param = GltfTextureImporter.CreateStandard(parser,
src.pbrMetallicRoughness?.metallicRoughnessTexture?.index,
src.occlusionTexture?.index,
offset, scale,
metallicFactor,
roughnessFactor);
var key = new SubAssetKey(typeof(Texture2D), param.UnityObjectName);
return (key, param);
}
public static TextureImportParam NormalTexture(GltfParser parser, glTFMaterial src)
public static (SubAssetKey, TextureImportParam Param) NormalTexture(GltfParser parser, glTFMaterial src)
{
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.normalTexture);
return GltfTextureImporter.CreateNormal(parser, src.normalTexture.index, offset, scale);
@ -95,7 +97,8 @@ namespace UniGLTF
{
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null)
{
standardParam = StandardTexture(parser, src);
SubAssetKey key;
(key, standardParam) = StandardTexture(parser, src);
}
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
@ -106,7 +109,7 @@ namespace UniGLTF
if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
{
var textureParam = BaseColorTexture(parser, src);
var (key, textureParam) = BaseColorTexture(parser, src);
param.TextureSlots.Add("_MainTex", textureParam);
}
@ -128,7 +131,7 @@ namespace UniGLTF
if (src.normalTexture != null && src.normalTexture.index != -1)
{
param.Actions.Add(material => material.EnableKeyword("_NORMALMAP"));
var textureParam = NormalTexture(parser, src);
var (key, textureParam) = NormalTexture(parser, src);
param.TextureSlots.Add("_BumpMap", textureParam);
param.FloatValues.Add("_BumpScale", src.normalTexture.scale);
}
@ -142,7 +145,8 @@ namespace UniGLTF
if (src.emissiveFactor != null
|| (src.emissiveTexture != null && src.emissiveTexture.index != -1))
{
param.Actions.Add(material => {
param.Actions.Add(material =>
{
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
});
@ -155,12 +159,13 @@ namespace UniGLTF
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.emissiveTexture);
var textureParam = GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale);
var (key, textureParam) = GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale);
param.TextureSlots.Add("_EmissionMap", textureParam);
}
}
param.Actions.Add(material => {
param.Actions.Add(material =>
{
BlendMode blendMode = BlendMode.Opaque;
// https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
switch (src.alphaMode)

View File

@ -1,10 +1,11 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using VRMShaders;
namespace UniGLTF
{
public delegate IEnumerable<TextureImportParam> EnumerateAllTexturesDistinctFunc(GltfParser parser);
public delegate IEnumerable<(SubAssetKey Key, TextureImportParam Param)> EnumerateAllTexturesDistinctFunc(GltfParser parser);
/// <summary>
/// Texture 生成に関して
@ -12,29 +13,22 @@ namespace UniGLTF
///
/// * (gltf/glb/vrm-1): AssetImporterContext.AddObjectToAsset(SubAsset)
/// * (gltf/glb/vrm-1): ScriptedImporter.GetExternalObjectMap(Extracted)
/// * (vrm-0): (Extracted) ScriptedImporter では無いので ScriptedImporter.AddRemap が無い
/// * (vrm-0): (Extracted) ScriptedImporter では無いので ScriptedImporter.AddRemap, GetExternalObjectMap が無い
///
/// Extract は外部ファイルに png/jpg のバイト列を出力して、TextureImporter を設定すること。ScriptedImporter.AddRemap
/// Extracted は、
/// AddRemap, GetExternalObjectMap は Dictionary[SourceAssetIdentifier, UnityEngine.Object] に対する API で
/// SourceAssetIdentifier 型がリソースを識別するキーとなる。
///
/// ファイル名もしくはSubAsset名を介してテクスチャーアセットにアクセスるので、文字列をユニークなキーとしてテクスチャーを識別できる必要がある。
/// 基本的に、gltf.textures と Texture2D が1対1に対応するので、 gltfTexture.name のユニーク性を確保した上で
/// これを用いればよいが以下の例外がある。
///
/// * PBR の MetallicSmoothness と Occlusion が合体する場合
/// * (gltf)外部テクスチャーファイルの uri 参照が同じになる場合(同じイメージファイルが異なるテクスチャー設定を保持するケースをサポートしない)
/// * 異なる gltfTexture.source が 同じ gltfImage を参照する場合
/// * 異なる gltfImage.uri が 同じ ファイルを参照する場合
///
/// 例外に対処した上で、ユニークなテクスチャー生成情報を列挙するのが
/// gltfTexture から SourceAssetIdentifier を作り出すことで、GetExternalObjectMap との対応関係を作る。
///
/// GltfTextureEnumerator.Enumerate
///
/// である。
/// [例外]
/// glTF で外部ファイルを uri 参照する場合
/// * sRGB 外部ファイルをそのまま使うので SubAsset にしない
/// * normal 外部ライルをそのまま使うので SubAsset にしない(normalとしてロードするためにAssetImporterの設定は必用)
/// * metallicRoughnessOcclusion 変換結果を SubAsset 化する
/// </summary>
public static class GltfTextureEnumerator
{
public static IEnumerable<TextureImportParam> EnumerateTexturesForMaterial(GltfParser parser, int i)
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesForMaterial(GltfParser parser, int i)
{
var m = parser.GLTF.materials[i];
@ -86,16 +80,21 @@ namespace UniGLTF
/// </summary>
/// <param name="parser"></param>
/// <returns></returns>
public static IEnumerable<TextureImportParam> EnumerateAllTexturesDistinct(GltfParser parser)
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
var used = new HashSet<string>();
var used = new HashSet<SubAssetKey>();
Func<(SubAssetKey, TextureImportParam), bool> add = (kv) =>
{
var (key, textureInfo) = kv;
return used.Add(key);
};
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
foreach (var textureInfo in EnumerateTexturesForMaterial(parser, i))
foreach (var kv in EnumerateTexturesForMaterial(parser, i))
{
if (used.Add(textureInfo.ExtractKey))
if (add(kv))
{
yield return textureInfo;
yield return kv;
}
}
}

View File

@ -29,7 +29,7 @@ namespace UniGLTF
if (src.pbrMetallicRoughness.baseColorTexture != null)
{
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
var textureParam = GltfTextureImporter.CreateSRGB(parser, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
var (key, textureParam) = GltfTextureImporter.CreateSRGB(parser, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
param.TextureSlots.Add("_MainTex", textureParam);
}

View File

@ -0,0 +1,35 @@
using System;
namespace UniGLTF
{
/// <summary>
/// UnityEditor.Experimental.AssetImporter.SourceAssetIdentifier に対応する
///
/// * SourceAssetIdentifier が UnityEditor なので、 Runtime でも使えるように
/// * Type が違うが Name が同じだと警告が出る。例えば、Material と 同じ名前の Texture がある場合。
/// Identifier uniqueness violation: 'Alicia_body'. Scripted Importers do not guarantee that subsequent imports of this asset will properly re-link to these targets.
/// * なので、SourceAssetIdentifier は、$"{Type.Name}.{UnityObject.name}" のように強制的に Unique にするのが良さそう
/// * 一方で、Extract したファイル名に $"{Type.Name}." が付属するのは煩わしいのでこれは無しにしたい。
///
/// public void AddRemap(SourceAssetIdentifier identifier, UnityEngine.Object externalObject);
///
/// の呼び出し時に、identifier.name と externalObject.name が同じでない運用にしてみる。
///
/// </summary>
public struct SubAssetKey
{
public readonly Type Type;
public readonly string Name;
public SubAssetKey(Type t, string name)
{
if (string.IsNullOrEmpty(name))
{
throw new System.ArgumentNullException();
}
Type = t;
Name = name;
}
}
}

View File

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

View File

@ -31,31 +31,40 @@ namespace UniGLTF
}
}
public static TextureImportParam CreateSRGB(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
public static (SubAssetKey, TextureImportParam Param) CreateSRGB(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
{
var name = CreateNameExt(parser.GLTF, textureIndex, TextureImportTypes.sRGB);
var gltfTexture = parser.GLTF.textures[textureIndex];
var gltfImage = parser.GLTF.images[gltfTexture.source];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfTexture.name, gltfImage.uri);
var sampler = CreateSampler(parser.GLTF, textureIndex);
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(parser.GLTF.GetImageBytesFromTextureIndex(parser.Storage, textureIndex)));
return new TextureImportParam(name, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default);
var key = new SubAssetKey(typeof(Texture2D), name);
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default);
return (key, param);
}
public static TextureImportParam CreateNormal(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
public static (SubAssetKey, TextureImportParam Param) CreateNormal(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
{
var name = CreateNameExt(parser.GLTF, textureIndex, TextureImportTypes.NormalMap);
var gltfTexture = parser.GLTF.textures[textureIndex];
var gltfImage = parser.GLTF.images[gltfTexture.source];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.NormalMap, null, gltfImage.uri);
var sampler = CreateSampler(parser.GLTF, textureIndex);
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(parser.GLTF.GetImageBytesFromTextureIndex(parser.Storage, textureIndex)));
return new TextureImportParam(name, offset, scale, sampler, TextureImportTypes.NormalMap, default, default, getTextureBytesAsync, default, default, default, default, default);
var key = new SubAssetKey(typeof(Texture2D), name);
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.NormalMap, default, default, getTextureBytesAsync, default, default, default, default, default);
return (key, param);
}
public static TextureImportParam CreateStandard(GltfParser parser, int? metallicRoughnessTextureIndex, int? occlusionTextureIndex, Vector2 offset, Vector2 scale, float metallicFactor, float roughnessFactor)
{
TextureImportName name = default;
string name = default;
GetTextureBytesAsync getMetallicRoughnessAsync = default;
SamplerParam sampler = default;
if (metallicRoughnessTextureIndex.HasValue)
{
name = CreateNameExt(parser.GLTF, metallicRoughnessTextureIndex.Value, TextureImportTypes.StandardMap);
var gltfTexture = parser.GLTF.textures[metallicRoughnessTextureIndex.Value];
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, parser.GLTF.images[gltfTexture.source].uri);
sampler = CreateSampler(parser.GLTF, metallicRoughnessTextureIndex.Value);
getMetallicRoughnessAsync = () => Task.FromResult(ToArray(parser.GLTF.GetImageBytesFromTextureIndex(parser.Storage, metallicRoughnessTextureIndex.Value)));
}
@ -63,30 +72,16 @@ namespace UniGLTF
GetTextureBytesAsync getOcclusionAsync = default;
if (occlusionTextureIndex.HasValue)
{
if (string.IsNullOrEmpty(name.GltfName))
var gltfTexture = parser.GLTF.textures[occlusionTextureIndex.Value];
if (string.IsNullOrEmpty(name))
{
name = CreateNameExt(parser.GLTF, occlusionTextureIndex.Value, TextureImportTypes.StandardMap);
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, parser.GLTF.images[gltfTexture.source].uri);
}
sampler = CreateSampler(parser.GLTF, occlusionTextureIndex.Value);
getOcclusionAsync = () => Task.FromResult(ToArray(parser.GLTF.GetImageBytesFromTextureIndex(parser.Storage, occlusionTextureIndex.Value)));
}
return new TextureImportParam(name, offset, scale, sampler, TextureImportTypes.StandardMap, metallicFactor, roughnessFactor, getMetallicRoughnessAsync, getOcclusionAsync, default, default, default, default);
}
public static TextureImportName CreateNameExt(glTF gltf, int textureIndex, TextureImportTypes textureType)
{
if (textureIndex < 0 || textureIndex >= gltf.textures.Count)
{
throw new ArgumentOutOfRangeException();
}
var gltfTexture = gltf.textures[textureIndex];
if (gltfTexture.source < 0 || gltfTexture.source >= gltf.images.Count)
{
throw new ArgumentOutOfRangeException();
}
var gltfImage = gltf.images[gltfTexture.source];
return new TextureImportName(textureType, gltfTexture.name, gltfImage.GetExt(), gltfImage.uri);
return new TextureImportParam(name, ".png", null, offset, scale, sampler, TextureImportTypes.StandardMap, metallicFactor, roughnessFactor, getMetallicRoughnessAsync, getOcclusionAsync, default, default, default, default);
}
public static SamplerParam CreateSampler(glTF gltf, int index)

View File

@ -147,11 +147,11 @@ namespace VRM
//
var subAssets = m_context.TextureFactory.Textures
.Where(x => x.IsUsed)
.Select(x => x.Texture)
.Select(x => (new SubAssetKey(typeof(Texture2D), x.Texture.name), x.Texture))
.ToArray();
var vrmTextures = new VRMMtoonMaterialImporter(m_context.VRM);
var dirName = $"{m_prefabPath.FileNameWithoutExtension}.Textures";
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.EnumerateAllTexturesDistinct, subAssets, _ => { }, onTextureReloaded);
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.EnumerateAllTexturesDistinct, subAssets, (_x, _y) => { }, onTextureReloaded);
}
bool SaveAsAsset(UnityEngine.Object o)

View File

@ -83,7 +83,7 @@ namespace VRM
using (var context = new VRMImporterContext(parser, map))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
foreach (var textureInfo in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
{
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
}

View File

@ -60,7 +60,7 @@ namespace VRM
using (var context = new VRMImporterContext(parser, map))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
foreach (var textureInfo in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
{
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
}

View File

@ -8,7 +8,7 @@ namespace VRM
{
public static class MToonTextureParam
{
public static TextureImportParam Create(GltfParser parser, int index, Vector2 offset, Vector2 scale, string prop, float metallicFactor, float roughnessFactor)
public static (SubAssetKey, TextureImportParam) Create(GltfParser parser, int index, Vector2 offset, Vector2 scale, string prop, float metallicFactor, float roughnessFactor)
{
switch (prop)
{

View File

@ -297,7 +297,8 @@ namespace VRM
meta.Title = gltfMeta.title;
if (gltfMeta.texture >= 0)
{
meta.Thumbnail = await TextureFactory.GetTextureAsync(GltfTextureImporter.CreateSRGB(Parser, gltfMeta.texture, Vector2.zero, Vector2.one));
var (key, param) = GltfTextureImporter.CreateSRGB(Parser, gltfMeta.texture, Vector2.zero, Vector2.one);
meta.Thumbnail = await TextureFactory.GetTextureAsync(param);
}
meta.AllowedUser = gltfMeta.allowedUser;
meta.ViolentUssage = gltfMeta.violentUssage;

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -62,7 +63,7 @@ namespace VRM
scale = new Vector2(value[2], value[3]);
}
var textureParam = MToonTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, 1, 1);
var (key, textureParam) = MToonTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, 1, 1);
param.TextureSlots.Add(kv.Key, textureParam);
}
@ -93,10 +94,10 @@ namespace VRM
return true;
}
public IEnumerable<TextureImportParam> EnumerateTexturesForMaterial(GltfParser parser, int i)
public IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesForMaterial(GltfParser parser, int i)
{
// mtoon
if (!TryCreateParam(parser, i, out MaterialImportParam param))
if (TryCreateParam(parser, i, out MaterialImportParam param))
{
// unlit
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param))
@ -108,35 +109,42 @@ namespace VRM
foreach (var kv in param.TextureSlots)
{
yield return kv.Value;
var key = new SubAssetKey(typeof(Texture2D), kv.Value.UnityObjectName);
yield return (key, kv.Value);
}
}
public IEnumerable<TextureImportParam> EnumerateAllTexturesDistinct(GltfParser parser)
public IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
var used = new HashSet<string>();
var used = new HashSet<SubAssetKey>();
Func<(SubAssetKey, TextureImportParam), bool> add = (kv) =>
{
var (key, textureInfo) = kv;
return used.Add(key);
};
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
var vrmMaterial = m_vrm.materialProperties[i];
if (vrmMaterial.shader == MToon.Utils.ShaderName)
{
// MToon
foreach (var textureInfo in EnumerateTexturesForMaterial(parser, i))
foreach (var kv in EnumerateTexturesForMaterial(parser, i))
{
if (used.Add(textureInfo.ExtractKey))
if (add(kv))
{
yield return textureInfo;
yield return kv;
}
}
}
else
{
// PBR or Unlit
foreach (var textureInfo in GltfTextureEnumerator.EnumerateTexturesForMaterial(parser, i))
foreach (var kv in GltfTextureEnumerator.EnumerateTexturesForMaterial(parser, i))
{
if (used.Add(textureInfo.ExtractKey))
if (add(kv))
{
yield return textureInfo;
yield return kv;
}
}
}
@ -145,10 +153,10 @@ namespace VRM
// thumbnail
if (m_vrm.meta != null && m_vrm.meta.texture != -1)
{
var textureInfo = GltfTextureImporter.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
if (used.Add(textureInfo.ExtractKey))
var kv = GltfTextureImporter.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
if (add(kv))
{
yield return textureInfo;
yield return kv;
}
}
}

View File

@ -29,6 +29,7 @@ namespace VRM
textures = new List<glTFTexture>
{
new glTFTexture{
name = "texture0",
source = 0,
}
},

View File

@ -39,13 +39,13 @@ namespace UniVRM10
}
// meta
importer.DrawRemapGUI<VRM10MetaObject>(new string[] { VRM10MetaObject.ExtractKey });
importer.DrawRemapGUI<VRM10MetaObject>(new SubAssetKey[] { VRM10MetaObject.SubAssetKey });
// expression avatar
importer.DrawRemapGUI<VRM10ExpressionAvatar>(new string[] { VRM10ExpressionAvatar.ExtractKey });
importer.DrawRemapGUI<VRM10ExpressionAvatar>(new SubAssetKey[] { VRM10ExpressionAvatar.SubAssetKey });
// expressions
importer.DrawRemapGUI<VRM10Expression>(vrm.Expressions.Select(x => CreateKey(x).ExtractKey));
importer.DrawRemapGUI<VRM10Expression>(vrm.Expressions.Select(x => CreateKey(x).SubAssetKey));
if (GUILayout.Button("Clear"))
{
@ -73,7 +73,7 @@ namespace UniVRM10
// meta
{
foreach (var asset in importer.GetSubAssets<VRM10MetaObject>(importer.assetPath))
foreach (var (key, asset) in importer.GetSubAssets<VRM10MetaObject>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}
@ -81,13 +81,13 @@ namespace UniVRM10
{
// expressions
foreach (var asset in importer.GetSubAssets<VRM10Expression>(importer.assetPath))
foreach (var (key, asset) in importer.GetSubAssets<VRM10Expression>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}
// expressions
foreach (var asset in importer.GetSubAssets<VRM10ExpressionAvatar>(importer.assetPath))
foreach (var (key, asset) in importer.GetSubAssets<VRM10ExpressionAvatar>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}

View File

@ -99,7 +99,7 @@ namespace UniVRM10
using (var loader = new RuntimeUnityBuilder(parser, externalObjectMap))
{
// settings TextureImporters
foreach (var textureInfo in Vrm10MToonMaterialImporter.EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in Vrm10MToonMaterialImporter.EnumerateAllTexturesDistinct(parser))
{
TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using UniGLTF;
namespace UniVRM10
{
@ -173,11 +174,11 @@ namespace UniVRM10
return 0;
}
public string ExtractKey
public SubAssetKey SubAssetKey
{
get
{
return $"Expression.{this}";
return new SubAssetKey(typeof(VRM10Expression), this.ToString());
}
}
}

View File

@ -13,7 +13,7 @@ namespace UniVRM10
[CreateAssetMenu(menuName = "VRM10/ExpressionAvatar")]
public sealed class VRM10ExpressionAvatar : ScriptableObject
{
public const string ExtractKey = "ExpressionAvatar";
public static UniGLTF.SubAssetKey SubAssetKey => new UniGLTF.SubAssetKey(typeof(VRM10ExpressionAvatar), "ExpressionAvatar");
[SerializeField]
public List<VRM10Expression> Clips = new List<VRM10Expression>();

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using MeshUtility;
using UniGLTF;
using UnityEngine;
@ -10,7 +11,7 @@ namespace UniVRM10
[CreateAssetMenu(menuName = "VRM10/MetaObject")]
public class VRM10MetaObject : ScriptableObject
{
public const string ExtractKey = "Meta";
public static SubAssetKey SubAssetKey => new SubAssetKey(typeof(VRM10MetaObject), "Meta");
[SerializeField]
public string ExporterVersion;

View File

@ -7,20 +7,6 @@ namespace UniVRM10
{
public static class ExpressionExtensions
{
/// <summary>
/// for SubAssetName
/// </summary>
/// <returns></returns>
public static string ExtractKey(this Expression expression)
{
ExpressionKey key =
(expression.Preset == ExpressionPreset.custom)
? ExpressionKey.CreateCustom(expression.Name)
: ExpressionKey.CreateFromPreset(expression.Preset)
;
return key.ExtractKey;
}
public static UniVRM10.MorphTargetBinding Build10(this MorphTargetBind bind, GameObject root, RuntimeUnityBuilder.ModelMap loader, VrmLib.Model model)
{
var libNode = model.Nodes[bind.Node.Value];

View File

@ -245,7 +245,7 @@ namespace UniVRM10
{
var src = vrm.Meta;
m_meta = ScriptableObject.CreateInstance<VRM10MetaObject>();
m_meta.name = VRM10MetaObject.ExtractKey;
m_meta.name = VRM10MetaObject.SubAssetKey.Name;
controller.Meta = m_meta;
m_meta.Name = src.Name;
m_meta.Version = src.Version;
@ -270,9 +270,9 @@ namespace UniVRM10
{
m_meta.Authors.AddRange(src.Authors);
}
if (Vrm10MToonMaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out VRMShaders.TextureImportParam param))
if (Vrm10MToonMaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv))
{
var texture = await TextureFactory.GetTextureAsync(param);
var texture = await TextureFactory.GetTextureAsync(kv.Param);
if (texture != null)
{
m_meta.Thumbnail = texture;
@ -286,14 +286,14 @@ namespace UniVRM10
controller.Expression.ExpressionAvatar = ScriptableObject.CreateInstance<VRM10ExpressionAvatar>();
m_exressionAvatar = controller.Expression.ExpressionAvatar;
m_exressionAvatar.name = VRM10ExpressionAvatar.ExtractKey;
m_exressionAvatar.name = VRM10ExpressionAvatar.SubAssetKey.Name;
foreach (var expression in vrm.Expressions)
{
var clip = ScriptableObject.CreateInstance<UniVRM10.VRM10Expression>();
clip.Preset = expression.Preset;
clip.ExpressionName = expression.Name;
clip.name = Key(expression).ExtractKey;
clip.name = Key(expression).SubAssetKey.Name;
clip.IsBinary = expression.IsBinary.GetValueOrDefault();
clip.OverrideBlink = expression.OverrideBlink;
clip.OverrideLookAt = expression.OverrideLookAt;

View File

@ -128,7 +128,7 @@ namespace UniVRM10
// base color
if (m.pbrMetallicRoughness?.baseColorTexture != null)
{
param.TextureSlots.Add("_MainTex", GltfPBRMaterial.BaseColorTexture(parser, m));
param.TextureSlots.Add("_MainTex", GltfPBRMaterial.BaseColorTexture(parser, m).Param);
}
}
@ -136,7 +136,7 @@ namespace UniVRM10
{
// normal map
param.Actions.Add(material => material.EnableKeyword("_NORMALMAP"));
var textureParam = GltfPBRMaterial.NormalTexture(parser, m);
var textureParam = GltfPBRMaterial.NormalTexture(parser, m).Param;
param.TextureSlots.Add("_BumpMap", textureParam);
param.FloatValues.Add("_BumpScale", m.normalTexture.scale);
}
@ -144,34 +144,34 @@ namespace UniVRM10
if (m.emissiveTexture != null && m.emissiveTexture.index != -1)
{
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(m.emissiveTexture);
var textureParam = GltfTextureImporter.CreateSRGB(parser, m.emissiveTexture.index, offset, scale);
var textureParam = GltfTextureImporter.CreateSRGB(parser, m.emissiveTexture.index, offset, scale).Param;
param.TextureSlots.Add("_EmissionMap", textureParam);
}
// TODO:
if (mtoon.ShadeMultiplyTexture.HasValue)
{
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.ShadeMultiplyTexture.Value, Vector2.zero, Vector2.one);
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.ShadeMultiplyTexture.Value, Vector2.zero, Vector2.one).Param;
param.TextureSlots.Add("_ShadeTexture", textureParam);
}
if (mtoon.OutlineWidthMultiplyTexture.HasValue)
{
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.OutlineWidthMultiplyTexture.Value, Vector2.zero, Vector2.one);
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.OutlineWidthMultiplyTexture.Value, Vector2.zero, Vector2.one).Param;
param.TextureSlots.Add("_OutlineWidthTexture", textureParam);
}
if (mtoon.AdditiveTexture.HasValue)
{
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.AdditiveTexture.Value, Vector2.zero, Vector2.one);
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.AdditiveTexture.Value, Vector2.zero, Vector2.one).Param;
param.TextureSlots.Add("_SphereAdd", textureParam);
}
if (mtoon.RimMultiplyTexture.HasValue)
{
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.RimMultiplyTexture.Value, Vector2.zero, Vector2.one);
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.RimMultiplyTexture.Value, Vector2.zero, Vector2.one).Param;
param.TextureSlots.Add("_RimTexture", textureParam); ;
}
if (mtoon.UvAnimationMaskTexture.HasValue)
{
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.UvAnimationMaskTexture.Value, Vector2.zero, Vector2.one);
var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.UvAnimationMaskTexture.Value, Vector2.zero, Vector2.one).Param;
param.TextureSlots.Add("_UvAnimMaskTexture", textureParam);
}
@ -184,7 +184,7 @@ namespace UniVRM10
/// <param name="parser"></param>
/// <param name="m"></param>
/// <returns></returns>
public static IEnumerable<TextureImportParam> EnumerateTexturesForMaterial(GltfParser parser, int i)
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesForMaterial(GltfParser parser, int i)
{
// mtoon
if (!TryCreateParam(parser, i, out MaterialImportParam param))
@ -199,7 +199,8 @@ namespace UniVRM10
foreach (var kv in param.TextureSlots)
{
yield return kv.Value;
var key = new SubAssetKey(typeof(Texture2D), kv.Key);
yield return (key, kv.Value);
}
}
@ -212,7 +213,7 @@ namespace UniVRM10
/// <param name="vrm"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out TextureImportParam value)
public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out (SubAssetKey, TextureImportParam) value)
{
if (vrm?.Meta == null || !vrm.Meta.ThumbnailImage.HasValue)
{
@ -223,17 +224,19 @@ namespace UniVRM10
// thumbnail
var imageIndex = vrm.Meta.ThumbnailImage.Value;
var gltfImage = parser.GLTF.images[imageIndex];
var name = new TextureImportName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.GetExt(), "");
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri);
GetTextureBytesAsync getBytesAsync = () =>
{
var bytes = parser.GLTF.GetImageBytes(parser.Storage, imageIndex);
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
};
value = new TextureImportParam(name, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
getBytesAsync, default, default,
default, default, default
);
var key = new SubAssetKey(typeof(Texture2D), name);
value = (key, param);
return true;
}
@ -242,26 +245,31 @@ namespace UniVRM10
/// </summary>
/// <param name="parser"></param>
/// <returns></returns>
public static IEnumerable<TextureImportParam> EnumerateAllTexturesDistinct(GltfParser parser)
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
{
throw new System.Exception("not vrm");
}
if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out TextureImportParam thumbnail))
if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey, TextureImportParam) thumbnail))
{
yield return thumbnail;
}
var used = new HashSet<string>();
var used = new HashSet<SubAssetKey>();
Func<(SubAssetKey, TextureImportParam), bool> add = (kv) =>
{
var (key, textureInfo) = kv;
return used.Add(key);
};
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
foreach (var textureInfo in EnumerateTexturesForMaterial(parser, i))
foreach (var kv in EnumerateTexturesForMaterial(parser, i))
{
if (used.Add(textureInfo.ExtractKey))
if (add(kv))
{
yield return textureInfo;
yield return kv;
}
}
}

View File

@ -118,9 +118,8 @@ namespace VRMShaders
public IEnumerable<TextureLoadInfo> Textures => m_textureCache.Values;
async Task<TextureLoadInfo> GetOrCreateBaseTexture(TextureImportParam param, GetTextureBytesAsync getTextureBytesAsync, RenderTextureReadWrite colorSpace, bool used)
async Task<TextureLoadInfo> GetOrCreateBaseTexture(string name, TextureImportParam param, GetTextureBytesAsync getTextureBytesAsync, RenderTextureReadWrite colorSpace, bool used)
{
var name = param.GltfName;
if (m_textureCache.TryGetValue(name, out TextureLoadInfo cacheInfo))
{
return cacheInfo;
@ -194,17 +193,9 @@ namespace VRMShaders
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(TextureImportParam param)
{
//
// ExtractKey で External とのマッチングを試みる
//
// Normal => GltfName
// Standard => ConvertedName
// sRGB => GltfName
// Linear => GltfName
//
if (param.Index0 != null && ExternalMap != null)
{
if (ExternalMap.TryGetValue(param.ExtractKey, out Texture2D external))
if (ExternalMap.TryGetValue(param.UnityObjectName, out Texture2D external))
{
return external;
}
@ -215,11 +206,11 @@ namespace VRMShaders
case TextureImportTypes.NormalMap:
// Runtime/SubAsset 用に変換する
{
if (!m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo info))
if (!m_textureCache.TryGetValue(param.UnityObjectName, out TextureLoadInfo info))
{
var baseTexture = await GetOrCreateBaseTexture(param, param.Index0, RenderTextureReadWrite.Linear, false);
var baseTexture = await GetOrCreateBaseTexture($"{param.UnityObjectName}.normal_base", param, param.Index0, RenderTextureReadWrite.Linear, false);
var converted = NormalConverter.Import(baseTexture.Texture);
converted.name = param.ConvertedName;
converted.name = param.UnityObjectName;
info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
}
@ -229,20 +220,20 @@ namespace VRMShaders
case TextureImportTypes.StandardMap:
// 変換する
{
if (!m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo info))
if (!m_textureCache.TryGetValue(param.UnityObjectName, out TextureLoadInfo info))
{
TextureLoadInfo baseTexture = default;
if (param.Index0 != null)
{
baseTexture = await GetOrCreateBaseTexture(param, param.Index0, RenderTextureReadWrite.Linear, false);
baseTexture = await GetOrCreateBaseTexture($"{param.UnityObjectName}.metallicRoughness", param, param.Index0, RenderTextureReadWrite.Linear, false);
}
TextureLoadInfo occlusionBaseTexture = default;
if (param.Index1 != null)
{
occlusionBaseTexture = await GetOrCreateBaseTexture(param, param.Index1, RenderTextureReadWrite.Linear, false);
occlusionBaseTexture = await GetOrCreateBaseTexture($"{param.UnityObjectName}.occlusion", param, param.Index1, RenderTextureReadWrite.Linear, false);
}
var converted = OcclusionMetallicRoughnessConverter.Import(baseTexture.Texture, param.MetallicFactor, param.RoughnessFactor, occlusionBaseTexture.Texture);
converted.name = param.ConvertedName;
converted.name = param.UnityObjectName;
info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(converted.name, info);
}
@ -251,14 +242,12 @@ namespace VRMShaders
default:
{
var baseTexture = await GetOrCreateBaseTexture(param, param.Index0, RenderTextureReadWrite.sRGB, true);
var baseTexture = await GetOrCreateBaseTexture(param.UnityObjectName, param, param.Index0, RenderTextureReadWrite.sRGB, true);
return baseTexture.Texture;
}
}
throw new NotImplementedException();
}
}
}

View File

@ -1,26 +1,20 @@
using System.IO;
using System;
using System.IO;
namespace VRMShaders
{
public struct TextureImportName
public static class TextureImportName
{
public readonly string GltfName;
public readonly string ConvertedName;
public readonly string Ext;
public readonly string Uri;
public readonly string ExtractKey;
public static string GetExtractKey(TextureImportTypes type, string gltfName, string convertedName, string uri)
public static string GetUnityObjectName(TextureImportTypes type, string gltfName, string uri)
{
if (type == TextureImportTypes.StandardMap)
{
// metallic, smooth, occlusion
return convertedName;
return $"{gltfName}{STANDARD_SUFFIX}";
}
else
{
if (!string.IsNullOrEmpty(uri))
if (!string.IsNullOrEmpty(uri) && !uri.StartsWith("data:", StringComparison.Ordinal))
{
// external image
return Path.GetFileNameWithoutExtension(uri);
@ -33,30 +27,9 @@ namespace VRMShaders
}
}
public TextureImportName(TextureImportTypes textureType, string gltfName, string ext, string uri)
{
GltfName = gltfName;
ConvertedName = TextureImportName.Convert(gltfName, textureType);
Ext = ext;
Uri = uri;
ExtractKey = GetExtractKey(textureType, gltfName, ConvertedName, uri);
}
public string GltfFileName => $"{GltfName}{Ext}";
public string ConvertedFileName => $"{ConvertedName}.png";
public const string NORMAL_SUFFIX = ".normal";
public const string STANDARD_SUFFIX = ".standard";
public static string Convert(string name, TextureImportTypes textureType)
{
switch (textureType)
{
case TextureImportTypes.StandardMap: return $"{name}{STANDARD_SUFFIX}";
case TextureImportTypes.NormalMap: return $"{name}{NORMAL_SUFFIX}";
default: return name;
}
}
public static string RemoveSuffix(string src)
{
if (src.EndsWith(NORMAL_SUFFIX))

View File

@ -22,17 +22,10 @@ namespace VRMShaders
public const string METALLIC_GLOSS_PROP = "_MetallicGlossMap";
public const string OCCLUSION_PROP = "_OcclusionMap";
public readonly TextureImportName Name;
public string GltfName => Name.GltfName;
public string GltfFileName => Name.GltfFileName;
public string ConvertedName => Name.ConvertedName;
public string ConvertedFileName => Name.ConvertedFileName;
public string Uri => Name.Uri;
public readonly string UnityObjectName;
public readonly string Ext;
public readonly string Uri;
public string ExtractKey => Name.ExtractKey;
public Vector2 Offset;
public Vector2 Scale;
@ -41,7 +34,7 @@ namespace VRMShaders
public readonly TextureImportTypes TextureType;
public readonly float MetallicFactor;
public readonly float RoughnessFactor;
public readonly GetTextureBytesAsync Index0;
public readonly GetTextureBytesAsync Index1;
public readonly GetTextureBytesAsync Index2;
@ -54,7 +47,7 @@ namespace VRMShaders
/// </summary>
public bool ExtractConverted => TextureType == TextureImportTypes.StandardMap;
public TextureImportParam(TextureImportName name, Vector2 offset, Vector2 scale, SamplerParam sampler, TextureImportTypes textureType, float metallicFactor, float roughnessFactor,
public TextureImportParam(string name, string ext, string uri, Vector2 offset, Vector2 scale, SamplerParam sampler, TextureImportTypes textureType, float metallicFactor, float roughnessFactor,
GetTextureBytesAsync i0,
GetTextureBytesAsync i1,
GetTextureBytesAsync i2,
@ -62,7 +55,9 @@ namespace VRMShaders
GetTextureBytesAsync i4,
GetTextureBytesAsync i5)
{
Name = name;
UnityObjectName = name;
Ext = ext;
Uri = uri;
Offset = offset;
Scale = scale;
Sampler = sampler;