This commit is contained in:
ousttrue 2021-03-15 19:25:06 +09:00
parent 755c907791
commit f6aeef30ed
16 changed files with 201 additions and 184 deletions

View File

@ -8,7 +8,7 @@ namespace UniGLTF
public static Task<Texture2D> LoadTaskAsync(UnityPath m_assetPath,
glTF gltf, int textureIndex)
{
var colorSpace = TextureIO.GetColorSpace(gltf, textureIndex);
var colorSpace = gltf.GetColorSpace(textureIndex);
//
// texture from assets

View File

@ -14,12 +14,12 @@ namespace UniGLTF
public interface IMaterialExporter
{
glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager);
glTFMaterial ExportMaterial(Material m, TextureExporter textureManager);
}
public class MaterialExporter : IMaterialExporter
{
public virtual glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager)
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureManager)
{
var material = CreateMaterial(m);
@ -33,7 +33,7 @@ namespace UniGLTF
return material;
}
static void Export_Color(Material m, TextureExportManager textureManager, glTFMaterial material)
static void Export_Color(Material m, TextureExporter textureManager, glTFMaterial material)
{
if (m.HasProperty("_Color"))
{
@ -61,7 +61,7 @@ namespace UniGLTF
/// <param name="m"></param>
/// <param name="textureManager"></param>
/// <param name="material"></param>
static void Export_OcclusionMetallicRoughness(Material m, TextureExportManager textureManager, glTFMaterial material)
static void Export_OcclusionMetallicRoughness(Material m, TextureExporter textureManager, glTFMaterial material)
{
Texture metallicSmoothTexture = default;
float smoothness = 1.0f;
@ -124,7 +124,7 @@ namespace UniGLTF
}
}
static void Export_Normal(Material m, TextureExportManager textureManager, glTFMaterial material)
static void Export_Normal(Material m, TextureExporter textureManager, glTFMaterial material)
{
if (m.HasProperty("_BumpMap"))
{
@ -146,7 +146,7 @@ namespace UniGLTF
}
}
static void Export_Emission(Material m, TextureExportManager textureManager, glTFMaterial material)
static void Export_Emission(Material m, TextureExporter textureManager, glTFMaterial material)
{
if (m.IsKeywordEnabled("_EMISSION") == false)
return;

View File

@ -129,7 +129,7 @@ namespace UniGLTF
public static Texture2D CopyTexture(Texture src, glTFTextureTypes textureType, Material material)
{
Texture2D dst = null;
RenderTextureReadWrite colorSpace = TextureIO.GetColorSpace(textureType);
RenderTextureReadWrite colorSpace = textureType.GetColorSpace();
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace);
using (var scope = new ColorSpaceScope(colorSpace))

View File

@ -1,118 +0,0 @@
using System;
using System.Linq;
using UnityEngine;
namespace UniGLTF
{
public class TextureIO
{
public static RenderTextureReadWrite GetColorSpace(glTFTextureTypes textureType)
{
switch (textureType)
{
case glTFTextureTypes.SRGB:
return RenderTextureReadWrite.sRGB;
case glTFTextureTypes.OcclusionMetallicRoughness:
case glTFTextureTypes.Normal:
return RenderTextureReadWrite.Linear;
default:
throw new NotImplementedException();
}
}
public static RenderTextureReadWrite GetColorSpace(glTF gltf, int textureIndex)
{
if (TextureIO.TryGetglTFTextureType(gltf, textureIndex, out glTFTextureTypes textureType))
{
return GetColorSpace(textureType);
}
else
{
return RenderTextureReadWrite.sRGB;
}
}
public static bool TryGetglTFTextureType(glTF glTf, int textureIndex, out glTFTextureTypes textureType)
{
foreach (var material in glTf.materials)
{
var textureInfo = material.GetTextures().FirstOrDefault(x => (x != null) && x.index == textureIndex);
if (textureInfo != null)
{
textureType = textureInfo.TextureType;
return true;
}
}
// textureIndex is not used by Material.
textureType = default;
return false;
}
static (Byte[] bytes, string mine) GetBytesWithMime(Texture2D texture)
{
#if UNITY_EDITOR
var path = UnityPath.FromAsset(texture);
if (path.IsUnderAssetsFolder)
{
if (path.Extension == ".png")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/png"
);
}
if (path.Extension == ".jpg")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/jpeg"
);
}
}
#endif
return
(
texture.EncodeToPNG(),
"image/png"
);
}
static public int ExportTexture(glTF gltf, int bufferIndex, Texture2D texture)
{
var bytesWithMime = GetBytesWithMime(texture);
// add view
var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE);
var viewIndex = gltf.AddBufferView(view);
// add image
var imageIndex = gltf.images.Count;
gltf.images.Add(new glTFImage
{
name = GetTextureParam.RemoveSuffix(texture.name),
bufferView = viewIndex,
mimeType = bytesWithMime.mine,
});
// add sampler
var samplerIndex = gltf.samplers.Count;
var sampler = TextureSamplerUtil.Export(texture);
gltf.samplers.Add(sampler);
// add texture
gltf.textures.Add(new glTFTexture
{
sampler = samplerIndex,
source = imageIndex,
});
return imageIndex;
}
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Linq;
using UnityEngine;
namespace UniGLTF
{
public static class ColorSpace
{
public static RenderTextureReadWrite GetColorSpace(this glTFTextureTypes textureType)
{
switch (textureType)
{
case glTFTextureTypes.SRGB:
return RenderTextureReadWrite.sRGB;
case glTFTextureTypes.OcclusionMetallicRoughness:
case glTFTextureTypes.Normal:
return RenderTextureReadWrite.Linear;
default:
throw new NotImplementedException();
}
}
public static bool TryGetglTFTextureType(this glTF glTf, int textureIndex, out glTFTextureTypes textureType)
{
foreach (var material in glTf.materials)
{
var textureInfo = material.GetTextures().FirstOrDefault(x => (x != null) && x.index == textureIndex);
if (textureInfo != null)
{
textureType = textureInfo.TextureType;
return true;
}
}
// textureIndex is not used by Material.
textureType = default;
return false;
}
public static RenderTextureReadWrite GetColorSpace(this glTF gltf, int textureIndex)
{
if (TryGetglTFTextureType(gltf, textureIndex, out glTFTextureTypes textureType))
{
return GetColorSpace(textureType);
}
else
{
return RenderTextureReadWrite.sRGB;
}
}
}
}

View File

@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: 435499f173753ac418331fe0f967b789
timeCreated: 1541561421
licenseType: Free
guid: 1a3edb24329fd454db97cac12f30c0d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

View File

@ -36,7 +36,7 @@ namespace UniGLTF
//
// texture from image(png etc) bytes
//
var colorSpace = TextureIO.GetColorSpace(gltf, textureIndex);
var colorSpace = gltf.GetColorSpace(textureIndex);
var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear);
texture.name = gltf.textures[textureIndex].name;
if (imageBytes != null)

View File

@ -11,7 +11,7 @@ namespace UniGLTF
/// <summary>
/// glTF にエクスポートする Texture2D を蓄えて index を確定させる
/// </summary>
public class TextureExportManager
public class TextureExporter
{
struct ExportKey
{
@ -29,11 +29,31 @@ namespace UniGLTF
}
}
Dictionary<ExportKey, int> m_exportMap = new Dictionary<ExportKey, int>();
List<Texture2D> m_exported = new List<Texture2D>();
public IReadOnlyList<Texture2D> Exported => m_exported;
/// <summary>
/// Export する Texture2D のリスト。これが gltf.textures になる
/// </summary>
/// <typeparam name="Texture2D"></typeparam>
/// <returns></returns>
public readonly List<Texture2D> Exported = new List<Texture2D>();
static bool CopyIfMaxTextureSizeIsSmaller(Texture src/*, glTFTextureTypes textureType, out Texture2D dst*/)
/// <summary>
/// Texture の export index を得る
/// </summary>
/// <param name="src"></param>
/// <param name="textureType"></param>
/// <returns></returns>
public int GetTextureIndex(Texture src, glTFTextureTypes textureType)
{
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;
@ -47,27 +67,32 @@ namespace UniGLTF
var originalSize = Mathf.Max(originalWidth, originalHeight);
if (textureImporter.maxTextureSize < originalSize)
{
// export resized texture.
// this has textureImporter.maxTextureSize
// dst = TextureConverter.CopyTexture(src, textureType, null);
return true;
}
}
#endif
// dst = default;
return false;
}
/// <summary>
/// Texture の export index を得る
/// 元の Asset が存在して、 TextureImporter に設定された画像サイズが小さくない
/// </summary>
/// <param name="src"></param>
/// <param name="textureType"></param>
/// <param name="texture2D"></param>
/// <returns></returns>
public int GetTextureIndex(Texture src, glTFTextureTypes textureType)
static bool UseAsset(Texture2D texture2D)
{
return m_exportMap[new ExportKey(src, textureType)];
#if UNITY_EDITOR
if (texture2D != null && !string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(texture2D)))
{
if (CopyIfMaxTextureSizeIsSmaller(texture2D))
{
return false;
}
return true;
}
#endif
return false;
}
/// <summary>
@ -89,8 +114,9 @@ namespace UniGLTF
}
// get Texture2D
index = m_exported.Count;
if (src is Texture2D texture2D && !CopyIfMaxTextureSizeIsSmaller(src))
index = Exported.Count;
var texture2D = src as Texture2D;
if (UseAsset(texture2D))
{
// do nothing
}
@ -98,7 +124,7 @@ namespace UniGLTF
{
texture2D = TextureConverter.CopyTexture(src, glTFTextureTypes.SRGB, null);
}
m_exported.Add(texture2D);
Exported.Add(texture2D);
m_exportMap.Add(new ExportKey(src, glTFTextureTypes.SRGB), index);
return index;
@ -131,10 +157,10 @@ namespace UniGLTF
//
// Unity と glTF で互換性が無いので必ず変換が必用
//
index = m_exported.Count;
index = Exported.Count;
var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture);
m_exported.Add(texture2D);
Exported.Add(texture2D);
m_exportMap.Add(new ExportKey(metallicSmoothTexture, glTFTextureTypes.OcclusionMetallicRoughness), index);
if (occlusionTexture != metallicSmoothTexture && occlusionTexture != null)
{
@ -144,25 +170,6 @@ namespace UniGLTF
return index;
}
static bool UseNormalAsset(Texture src, out Texture2D texture2D)
{
#if UNITY_EDITOR
// asset として存在して textureImporter.textureType = TextureImporterType.NormalMap
texture2D = src as Texture2D;
if (texture2D != null && !string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(src)))
{
if (CopyIfMaxTextureSizeIsSmaller(src))
{
return false;
}
return true;
}
#endif
texture2D = default;
return false;
}
/// <summary>
/// Normal のテクスチャを変換する
/// </summary>
@ -182,9 +189,9 @@ namespace UniGLTF
}
// get Texture2D
index = m_exported.Count;
Texture2D texture2D = default;
if (UseNormalAsset(src, out texture2D))
index = Exported.Count;
var texture2D = src as Texture2D;
if (UseAsset(texture2D))
{
// EditorAsset を使うので変換不要
}
@ -194,10 +201,88 @@ namespace UniGLTF
texture2D = NormalConverter.Export(src);
}
m_exported.Add(texture2D);
Exported.Add(texture2D);
m_exportMap.Add(new ExportKey(src, glTFTextureTypes.Normal), index);
return index;
}
/// <summary>
/// 画像のバイト列を得る
/// </summary>
/// <param name="bytes"></param>
/// <param name="texture"></param>
/// <returns></returns>
static (Byte[] bytes, string mine) GetBytesWithMime(Texture2D texture)
{
#if UNITY_EDITOR
var path = UnityPath.FromAsset(texture);
if (path.IsUnderAssetsFolder)
{
if (path.Extension == ".png")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/png"
);
}
if (path.Extension == ".jpg")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/jpeg"
);
}
}
#endif
return
(
texture.EncodeToPNG(),
"image/png"
);
}
/// <summary>
///
/// </summary>
/// <param name="gltf"></param>
/// <param name="bufferIndex"></param>
/// <param name="texture"></param>
/// <returns></returns>
static public int ExportTexture(glTF gltf, int bufferIndex, Texture2D texture)
{
var bytesWithMime = GetBytesWithMime(texture);
// add view
var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE);
var viewIndex = gltf.AddBufferView(view);
// add image
var imageIndex = gltf.images.Count;
gltf.images.Add(new glTFImage
{
name = GetTextureParam.RemoveSuffix(texture.name),
bufferView = viewIndex,
mimeType = bytesWithMime.mine,
});
// add sampler
var samplerIndex = gltf.samplers.Count;
var sampler = TextureSamplerUtil.Export(texture);
gltf.samplers.Add(sampler);
// add texture
var textureIndex = gltf.textures.Count;
gltf.textures.Add(new glTFTexture
{
sampler = samplerIndex,
source = imageIndex,
});
return textureIndex;
}
}
}

View File

@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: eca1330a83e17a14eb99fc6ea1697922
timeCreated: 1533533316
licenseType: Free
guid: 65fdfff6cc4b1e14a882259e903fc830
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f3929edbda61f9346906bfab93411b98
guid: 62f23c5ca623a9f4083c25a63b2c82af
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -47,7 +47,7 @@ namespace UniGLTF
private set;
}
public TextureExportManager TextureManager;
public TextureExporter TextureManager;
protected virtual IMaterialExporter CreateMaterialExporter()
{
@ -180,7 +180,7 @@ namespace UniGLTF
#region Materials and Textures
Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
TextureManager = new TextureExportManager();
TextureManager = new TextureExporter();
var materialExporter = CreateMaterialExporter();
glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();
@ -188,7 +188,7 @@ namespace UniGLTF
for (int i = 0; i < TextureManager.Exported.Count; ++i)
{
var unityTexture = TextureManager.Exported[i];
TextureIO.ExportTexture(glTF, bufferIndex, unityTexture);
TextureExporter.ExportTexture(glTF, bufferIndex, unityTexture);
}
#endregion

View File

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

View File

@ -14,7 +14,7 @@ namespace UniGLTF
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
};
var textureManager = new TextureExportManager();
var textureManager = new TextureExporter();
var material = new Material(Shader.Find("Standard"));
material.mainTexture = tex0;

View File

@ -10,7 +10,7 @@ namespace VRM.Samples
{
var material = Resources.Load<Material>(resourceName);
var exporter = new VRMMaterialExporter();
var textureManager = new UniGLTF.TextureExportManager();
var textureManager = new UniGLTF.TextureExporter();
var exported = exporter.ExportMaterial(material, textureManager);
// parse glTFExtensionExport to glTFExtensionImport

View File

@ -112,7 +112,7 @@ namespace VRM
VRM.meta.title = meta.Title;
if (meta.Thumbnail != null)
{
VRM.meta.texture = TextureIO.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail);
VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail);
}
VRM.meta.licenseType = meta.LicenseType;
@ -137,7 +137,7 @@ namespace VRM
VRM.meta.title = meta.Title;
if (meta.Thumbnail != null)
{
VRM.meta.texture = TextureIO.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail);
VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail);
}
// ussage permission