移動 VRMShaders.TextureExporter

#726 separate AssetTextureUtil
This commit is contained in:
ousttrue
2021-04-02 18:14:27 +09:00
parent 9339733ff6
commit d28f700997
21 changed files with 148 additions and 98 deletions

View File

@@ -0,0 +1,55 @@
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace UniGLTF
{
public static class AssetTextureUtil
{
/// <summary>
/// TextureImporter.maxTextureSize が元のテクスチャーより小さいか否かの判定
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static bool CopyIfMaxTextureSizeIsSmaller(Texture src)
{
var textureImporter = AssetImporter.GetAtPath(UnityPath.FromAsset(src).Value) as TextureImporter;
// private メソッド TextureImporter.GetWidthAndHeight を無理やり呼ぶ
var getSizeMethod = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
if (textureImporter != null && getSizeMethod != null)
{
var args = new object[2] { 0, 0 };
getSizeMethod.Invoke(textureImporter, args);
var originalWidth = (int)args[0];
var originalHeight = (int)args[1];
var originalSize = Mathf.Max(originalWidth, originalHeight);
if (textureImporter.maxTextureSize < originalSize)
{
return true;
}
}
return false;
}
/// <summary>
/// 元の Asset が存在して、 TextureImporter に設定された画像サイズが小さくない
/// </summary>
/// <param name="src"></param>
/// <param name="texture2D"></param>
/// <returns></returns>
public static bool UseAsset(Texture texture)
{
if (texture != null && !string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(texture)))
{
if (CopyIfMaxTextureSizeIsSmaller(texture))
{
return false;
}
return true;
}
return false;
}
}
}

View File

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

View File

@@ -35,7 +35,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf, inverseAxis))
{
exporter.Prepare(go);
exporter.Export(settings);
exporter.Export(settings, AssetTextureUtil.UseAsset);
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Linq;
using UniGLTF.UniUnlit;
using UnityEngine;
using VRMShaders;
namespace UniGLTF

View File

@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using VRMShaders;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
namespace VRMShaders
{
/// <summary>
/// glTF にエクスポートする Texture2D を蓄えて index を確定させる。
@@ -15,12 +11,29 @@ namespace UniGLTF
/// </summary>
public class TextureExporter
{
Func<Texture, bool> m_useAsset;
public TextureExporter(Func<Texture, bool> useAsset)
{
m_useAsset = useAsset;
}
public enum ConvertTypes
{
// 無変換
None,
// Unity Standard様式 から glTF PBR様式への変換
OcclusionMetallicRoughness,
// Assetを使うときはそのバイト列を無変換で、それ以外は DXT5nm 形式からのデコードを行う
Normal,
}
struct ExportKey
{
public readonly Texture Src;
public readonly glTFTextureTypes TextureType;
public readonly ConvertTypes TextureType;
public ExportKey(Texture src, glTFTextureTypes type)
public ExportKey(Texture src, ConvertTypes type)
{
if (src == null)
{
@@ -45,7 +58,7 @@ namespace UniGLTF
/// <param name="src"></param>
/// <param name="textureType"></param>
/// <returns></returns>
public int GetTextureIndex(Texture src, glTFTextureTypes textureType)
public int GetTextureIndex(Texture src, ConvertTypes textureType)
{
if (src == null)
{
@@ -54,53 +67,6 @@ namespace UniGLTF
return m_exportMap[new ExportKey(src, textureType)];
}
/// <summary>
/// TextureImporter.maxTextureSize が元のテクスチャーより小さいか否かの判定
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
static bool CopyIfMaxTextureSizeIsSmaller(Texture src)
{
#if UNITY_EDITOR
var textureImporter = AssetImporter.GetAtPath(UnityPath.FromAsset(src).Value) as TextureImporter;
var getSizeMethod = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
if (textureImporter != null && getSizeMethod != null)
{
var args = new object[2] { 0, 0 };
getSizeMethod.Invoke(textureImporter, args);
var originalWidth = (int)args[0];
var originalHeight = (int)args[1];
var originalSize = Mathf.Max(originalWidth, originalHeight);
if (textureImporter.maxTextureSize < originalSize)
{
return true;
}
}
#endif
return false;
}
/// <summary>
/// 元の Asset が存在して、 TextureImporter に設定された画像サイズが小さくない
/// </summary>
/// <param name="src"></param>
/// <param name="texture2D"></param>
/// <returns></returns>
static bool UseAsset(Texture2D texture2D)
{
#if UNITY_EDITOR
if (texture2D != null && !string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(texture2D)))
{
if (CopyIfMaxTextureSizeIsSmaller(texture2D))
{
return false;
}
return true;
}
#endif
return false;
}
/// <summary>
/// sRGBなテクスチャーを処理し、index を確定させる
/// </summary>
@@ -114,7 +80,7 @@ namespace UniGLTF
}
// cache
if (m_exportMap.TryGetValue(new ExportKey(src, glTFTextureTypes.SRGB), out var index))
if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.None), out var index))
{
return index;
}
@@ -122,7 +88,7 @@ namespace UniGLTF
// get Texture2D
index = Exported.Count;
var texture2D = src as Texture2D;
if (UseAsset(texture2D))
if (m_useAsset(texture2D))
{
// do nothing
}
@@ -131,7 +97,7 @@ namespace UniGLTF
texture2D = TextureConverter.CopyTexture(src, TextureImportTypes.sRGB, null);
}
Exported.Add(texture2D);
m_exportMap.Add(new ExportKey(src, glTFTextureTypes.SRGB), index);
m_exportMap.Add(new ExportKey(src, ConvertTypes.None), index);
return index;
}
@@ -161,11 +127,11 @@ namespace UniGLTF
}
// cache
if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, glTFTextureTypes.OcclusionMetallicRoughness), out var index))
if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), out var index))
{
return index;
}
if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, glTFTextureTypes.OcclusionMetallicRoughness), out index))
if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, ConvertTypes.OcclusionMetallicRoughness), out index))
{
return index;
}
@@ -179,11 +145,11 @@ namespace UniGLTF
Exported.Add(texture2D);
if (metallicSmoothTexture != null)
{
m_exportMap.Add(new ExportKey(metallicSmoothTexture, glTFTextureTypes.OcclusionMetallicRoughness), index);
m_exportMap.Add(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), index);
}
if (occlusionTexture != null && occlusionTexture != metallicSmoothTexture)
{
m_exportMap.Add(new ExportKey(occlusionTexture, glTFTextureTypes.OcclusionMetallicRoughness), index);
m_exportMap.Add(new ExportKey(occlusionTexture, ConvertTypes.OcclusionMetallicRoughness), index);
}
return index;
@@ -202,7 +168,7 @@ namespace UniGLTF
}
// cache
if (m_exportMap.TryGetValue(new ExportKey(src, glTFTextureTypes.Normal), out var index))
if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.Normal), out var index))
{
return index;
}
@@ -210,7 +176,7 @@ namespace UniGLTF
// get Texture2D
index = Exported.Count;
var texture2D = src as Texture2D;
if (UseAsset(texture2D))
if (m_useAsset(texture2D))
{
// EditorAsset を使うので変換不要
}
@@ -221,7 +187,7 @@ namespace UniGLTF
}
Exported.Add(texture2D);
m_exportMap.Add(new ExportKey(src, glTFTextureTypes.Normal), index);
m_exportMap.Add(new ExportKey(src, ConvertTypes.Normal), index);
return index;
}

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using VRMShaders;
namespace UniGLTF
{
@@ -173,7 +173,7 @@ namespace UniGLTF
}
public virtual void Export(MeshExportSettings meshExportSettings)
public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture, bool> useAsset)
{
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
var bufferIndex = glTF.AddBuffer(bytesBuffer);
@@ -185,7 +185,7 @@ namespace UniGLTF
#region Materials and Textures
Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
TextureManager = new TextureExporter();
TextureManager = new TextureExporter(useAsset);
var materialExporter = CreateMaterialExporter();
glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

View File

@@ -18,7 +18,7 @@ namespace UniGLTF
filterMode = FilterMode.Bilinear,
};
var textureManager = new TextureExporter();
var textureManager = new TextureExporter(AssetTextureUtil.UseAsset);
var srcMaterial = new Material(Shader.Find("Standard"));
var offset = new Vector2(0.3f, 0.2f);
@@ -242,7 +242,7 @@ namespace UniGLTF
material.SetColor("_EmissionColor", new Color(0, 1, 2, 1));
material.EnableKeyword("_EMISSION");
var materialExporter = new MaterialExporter();
var textureExportManager = new TextureExporter();
var textureExportManager = new TextureExporter(AssetTextureUtil.UseAsset);
var gltfMaterial = materialExporter.ExportMaterial(material, textureExportManager);
Assert.AreEqual(gltfMaterial.emissiveFactor, new float[] { 0, 0.5f, 1 });

View File

@@ -15,7 +15,7 @@ namespace UniGLTF
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
};
var textureManager = new TextureExporter();
var textureManager = new TextureExporter(AssetTextureUtil.UseAsset);
var material = new Material(Shader.Find("Standard"));
material.mainTexture = tex0;
@@ -58,16 +58,16 @@ namespace UniGLTF
var occlusion = new Texture2D(4, 4, TextureFormat.ARGB32, false, true);
{
var exporter = new TextureExporter();
var exporter = new TextureExporter(AssetTextureUtil.UseAsset);
Assert.AreEqual(-1, exporter.ExportMetallicSmoothnessOcclusion(null, 0, null));
}
{
var exporter = new TextureExporter();
var exporter = new TextureExporter(AssetTextureUtil.UseAsset);
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion));
Assert.AreEqual(1, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null));
}
{
var exporter = new TextureExporter();
var exporter = new TextureExporter(AssetTextureUtil.UseAsset);
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, occlusion));
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion));
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null));

View File

@@ -106,7 +106,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(MeshExportSettings.Default);
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.UseAsset);
// remove empty buffer
gltf.buffers.Clear();
@@ -298,7 +298,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(CreateSimpleScene());
exporter.Export(MeshExportSettings.Default);
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.UseAsset);
}
var expected = gltf.ToJson().ParseAsJson();
@@ -534,7 +534,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(UniGLTF.MeshExportSettings.Default);
exporter.Export(UniGLTF.MeshExportSettings.Default, AssetTextureUtil.UseAsset);
json = gltf.ToJson();
}

View File

@@ -6,7 +6,9 @@
"MeshUtility",
"UniGLTF",
"UniVRM.Editor",
"VRM.Tests"
"VRM.Tests",
"VRMShaders",
"UniGLTF.Editor"
],
"optionalUnityReferences": [
"TestAssemblies"

View File

@@ -169,7 +169,7 @@ namespace VRM.Samples
*/
importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root, AssetTextureUtil.UseAsset);
// TODO: Check contents in JSON
/*var exportJson = */

View File

@@ -1,6 +1,7 @@
using NUnit.Framework;
using UniGLTF;
using UnityEngine;
using VRMShaders;
namespace VRM.Samples
{
@@ -10,7 +11,7 @@ namespace VRM.Samples
{
var material = Resources.Load<Material>(resourceName);
var exporter = new VRMMaterialExporter();
var textureManager = new UniGLTF.TextureExporter();
var textureManager = new TextureExporter(AssetTextureUtil.UseAsset);
var exported = exporter.ExportMaterial(material, textureManager);
// parse glTFExtensionExport to glTFExtensionImport

View File

@@ -95,7 +95,7 @@ namespace VRM.Samples
return;
}
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, m_model);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, m_model, _ => false);
var bytes = vrm.ToGlbBytes();
File.WriteAllBytes(path, bytes);
Debug.LogFormat("export to {0}", path);

View File

@@ -3,7 +3,8 @@
"references": [
"VRM",
"UniHumanoid",
"UniGLTF"
"UniGLTF",
"VRMShaders"
],
"optionalUnityReferences": [],
"includePlatforms": [],

View File

@@ -224,7 +224,7 @@ namespace VRM
using (var exporter = new VRMExporter(gltf))
{
exporter.Prepare(target);
exporter.Export(settings.MeshExportSettings);
exporter.Export(settings.MeshExportSettings, AssetTextureUtil.UseAsset);
}
var bytes = gltf.ToGlbBytes();
File.WriteAllBytes(path, bytes);

View File

@@ -14,13 +14,13 @@ namespace VRM
return new VRMMaterialExporter();
}
public static glTF Export(MeshExportSettings configuration, GameObject go)
public static glTF Export(MeshExportSettings configuration, GameObject go, Func<Texture, bool> useAsset)
{
var gltf = new glTF();
using (var exporter = new VRMExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(configuration);
exporter.Export(configuration, useAsset);
}
return gltf;
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using UniGLTF;
using UniGLTF.ShaderPropExporter;
using UnityEngine;
using VRMShaders;
namespace VRM
{

View File

@@ -1,6 +1,7 @@
using NUnit.Framework;
using UniGLTF;
using UnityEngine;
using VRMShaders;
namespace VRM
{
@@ -15,7 +16,7 @@ namespace VRM
filterMode = FilterMode.Bilinear,
};
var textureManager = new TextureExporter();
var textureManager = new TextureExporter(AssetTextureUtil.UseAsset);
var srcMaterial = new Material(Shader.Find("VRM/MToon"));
var offset = new Vector2(0.3f, 0.2f);

View File

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

View File

@@ -105,7 +105,7 @@ namespace VRM
try
{
// export
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, go);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, go, AssetTextureUtil.UseAsset);
// re import
if (vrm != null)

View File

@@ -124,7 +124,10 @@ namespace UniVRM10
break;
default:
throw new NotImplementedException($"{kv.Key}: {kv.Value}");
#if VRM_DEVELOP
Debug.LogWarning($"vectorProperties: {kv.Key}: {kv.Value}");
#endif
break;
}
}
@@ -225,7 +228,10 @@ namespace UniVRM10
break;
default:
throw new NotImplementedException($"floatProperties: {kv.Key} is unknown");
#if VRM_DEVELOP
Debug.LogWarning($"floatProperties: {kv.Key} is unknown");
#endif
break;
}
}
@@ -247,7 +253,10 @@ namespace UniVRM10
case "_OutlineWidthTexture": map.OutlineWidthTexture = index; break;
case "_UvAnimMaskTexture": map.UvAnimMaskTexture = index; break;
default:
throw new NotImplementedException($"textureProperties: {kv.Key} is unknown");
#if VRM_DEVELOP
Debug.LogWarning($"textureProperties: {kv.Key} is unknown");
#endif
break;
}
}
@@ -313,7 +322,10 @@ namespace UniVRM10
{
index = mtoon.TextureIndexMap.MainTex.Value
};
var value = mtoon.OffsetScale["_MainTex"];
if (!mtoon.OffsetScale.TryGetValue("_MainTex", out float[] value))
{
value = new float[] { 0, 0, 1, 1 };
}
glTF_KHR_texture_transform.Serialize(
gltfMaterial.pbrMetallicRoughness.baseColorTexture,
(value[0], value[1]),