mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-31 06:56:40 -05:00
Export Texture with specified Color Space.
This commit is contained in:
parent
72a922ded9
commit
b8f2d37ccf
|
|
@ -21,9 +21,9 @@ namespace UniGLTF
|
|||
/// <param name="bufferIndex"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <returns>gltf texture index</returns>
|
||||
public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, Func<Texture2D, (byte[] bytes, string mime)> getTextureBytes)
|
||||
public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, ColorSpace textureColorSpace, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes)
|
||||
{
|
||||
var bytesWithMime = getTextureBytes(texture);
|
||||
var bytesWithMime = getTextureBytes(texture, textureColorSpace);
|
||||
|
||||
// add view
|
||||
var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE);
|
||||
|
|
|
|||
|
|
@ -214,12 +214,21 @@ namespace UniGLTF
|
|||
return false;
|
||||
}
|
||||
|
||||
public virtual void ExportExtensions(Func<Texture2D, (byte[], string)> getTextureBytes)
|
||||
public virtual void ExportExtensions(GetBytesWithMimeFromTexture2D getTextureBytes)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture, bool> useAsset, Func<Texture2D, (byte[], string)> getTextureBytes)
|
||||
/// <summary>
|
||||
/// Texture2D から実際のバイト列を取得するデリゲート。
|
||||
///
|
||||
/// textureColorSpace は Texture2D をコピーする際に用いる。
|
||||
/// Texture2D 単体では、色空間を知ることができないため。
|
||||
/// 一般には、その Texture2D がアサインされる glTF のプロパティの仕様が定める色空間と一致する。
|
||||
/// </summary>
|
||||
public delegate (byte[] bytes, string mime) GetBytesWithMimeFromTexture2D(Texture2D texture, ColorSpace textureColorSpace);
|
||||
|
||||
public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture, bool> useAsset, GetBytesWithMimeFromTexture2D getTextureBytes)
|
||||
{
|
||||
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
|
||||
var bufferIndex = glTF.AddBuffer(bytesBuffer);
|
||||
|
|
@ -362,8 +371,8 @@ namespace UniGLTF
|
|||
// Extension で Texture が増える場合があるので最後に呼ぶ
|
||||
for (int i = 0; i < TextureManager.Exported.Count; ++i)
|
||||
{
|
||||
var unityTexture = TextureManager.Exported[i];
|
||||
glTF.PushGltfTexture(bufferIndex, unityTexture, getTextureBytes);
|
||||
var (unityTexture, colorSpace) = TextureManager.Exported[i];
|
||||
glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, getTextureBytes);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace UniGLTF
|
|||
var materialExporter = new MaterialExporter();
|
||||
materialExporter.ExportMaterial(material, textureManager);
|
||||
|
||||
var convTex0 = textureManager.Exported[0];
|
||||
var (convTex0, colorSpace) = textureManager.Exported[0];
|
||||
var sampler = TextureSamplerUtil.Export(convTex0);
|
||||
|
||||
Assert.AreEqual(glWrap.CLAMP_TO_EDGE, sampler.wrapS);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using UniGLTF;
|
||||
using UniJSON;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
|
||||
namespace VRM
|
||||
|
|
@ -14,7 +15,7 @@ namespace VRM
|
|||
return new VRMMaterialExporter();
|
||||
}
|
||||
|
||||
public static glTF Export(MeshExportSettings configuration, GameObject go, Func<Texture, bool> useAsset, Func<Texture2D, (byte[], string)> getTextureBytes)
|
||||
public static glTF Export(MeshExportSettings configuration, GameObject go, Func<Texture, bool> useAsset, GetBytesWithMimeFromTexture2D getTextureBytes)
|
||||
{
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new VRMExporter(gltf))
|
||||
|
|
@ -32,7 +33,7 @@ namespace VRM
|
|||
gltf.extensionsUsed.Add(glTF_VRM_extensions.ExtensionName);
|
||||
}
|
||||
|
||||
public override void ExportExtensions(Func<Texture2D, (byte[], string)> getTextureBytes)
|
||||
public override void ExportExtensions(GetBytesWithMimeFromTexture2D getTextureBytes)
|
||||
{
|
||||
// avatar
|
||||
var animator = Copy.GetComponent<Animator>();
|
||||
|
|
@ -110,7 +111,7 @@ namespace VRM
|
|||
VRM.meta.title = meta.Title;
|
||||
if (meta.Thumbnail != null)
|
||||
{
|
||||
VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, getTextureBytes);
|
||||
VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, ColorSpace.sRGB, getTextureBytes);
|
||||
}
|
||||
|
||||
VRM.meta.licenseType = meta.LicenseType;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ namespace UniVRM10
|
|||
return new float[] { -v.x, v.y, v.z };
|
||||
}
|
||||
|
||||
public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, Func<Texture2D, (byte[], string)> getTextureBytes, VRM10MetaObject metaObject = null)
|
||||
public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes, VRM10MetaObject metaObject = null)
|
||||
{
|
||||
ExportAsset(model);
|
||||
|
||||
|
|
@ -180,8 +180,8 @@ namespace UniVRM10
|
|||
// Extension で Texture が増える場合があるので最後に呼ぶ
|
||||
for (int i = 0; i < m_textureExporter.Exported.Count; ++i)
|
||||
{
|
||||
var unityTexture = m_textureExporter.Exported[i];
|
||||
Storage.Gltf.PushGltfTexture(0, unityTexture, getTextureBytes);
|
||||
var (unityTexture, texColorSpace) = m_textureExporter.Exported[i];
|
||||
Storage.Gltf.PushGltfTexture(0, unityTexture, texColorSpace, getTextureBytes);
|
||||
}
|
||||
|
||||
if (thumbnailTextureIndex.HasValue)
|
||||
|
|
@ -775,7 +775,7 @@ namespace UniVRM10
|
|||
/// <param name="go"></param>
|
||||
/// <param name="getTextureBytes"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] Export(GameObject go, Func<Texture2D, (byte[], string)> getTextureBytes = null)
|
||||
public static byte[] Export(GameObject go, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes = null)
|
||||
{
|
||||
if (getTextureBytes == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.IO;
|
|||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
|
|
@ -107,14 +108,14 @@ namespace VRMShaders
|
|||
return false;
|
||||
}
|
||||
|
||||
public static (byte[], string) GetTextureBytesWithMime(Texture2D texture)
|
||||
public static (byte[], string) GetTextureBytesWithMime(Texture2D texture, ColorSpace colorSpace)
|
||||
{
|
||||
if (TryGetBytesWithMime(texture, out byte[] bytes, out string mime))
|
||||
{
|
||||
return (bytes, mime);
|
||||
}
|
||||
|
||||
return TextureExporter.GetTextureBytesWithMime(texture);
|
||||
return TextureExporter.GetTextureBytesWithMime(texture, colorSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
|
||||
namespace VRMShaders
|
||||
|
|
@ -22,10 +23,27 @@ namespace VRMShaders
|
|||
}
|
||||
|
||||
public static Texture2D CopyTexture(Texture src, TextureImportTypes textureType, Material material)
|
||||
{
|
||||
return CopyTexture(src, textureType.GetColorSpace(), material);
|
||||
}
|
||||
|
||||
public static Texture2D CopyTexture(Texture src, ColorSpace colorSpace, Material material)
|
||||
{
|
||||
Texture2D dst = null;
|
||||
RenderTextureReadWrite colorSpace = textureType.GetColorSpace();
|
||||
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace);
|
||||
RenderTextureReadWrite readWrite;
|
||||
switch (colorSpace)
|
||||
{
|
||||
case ColorSpace.sRGB:
|
||||
readWrite = RenderTextureReadWrite.sRGB;
|
||||
break;
|
||||
case ColorSpace.Linear:
|
||||
readWrite = RenderTextureReadWrite.Linear;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null);
|
||||
}
|
||||
|
||||
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, readWrite);
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
|
|
@ -36,7 +54,7 @@ namespace VRMShaders
|
|||
Graphics.Blit(src, renderTexture);
|
||||
}
|
||||
|
||||
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear);
|
||||
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, readWrite == RenderTextureReadWrite.Linear);
|
||||
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
|
||||
dst.name = src.name;
|
||||
dst.anisoLevel = src.anisoLevel;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
|
||||
namespace VRMShaders
|
||||
|
|
@ -55,7 +56,7 @@ namespace VRMShaders
|
|||
/// </summary>
|
||||
/// <typeparam name="Texture2D"></typeparam>
|
||||
/// <returns></returns>
|
||||
public readonly List<Texture2D> Exported = new List<Texture2D>();
|
||||
public readonly List<(Texture2D, ColorSpace)> Exported = new List<(Texture2D, ColorSpace)>();
|
||||
|
||||
/// <summary>
|
||||
/// Texture の export index を得る
|
||||
|
|
@ -101,7 +102,7 @@ namespace VRMShaders
|
|||
{
|
||||
texture2D = TextureConverter.CopyTexture(src, TextureImportTypes.sRGB, null);
|
||||
}
|
||||
Exported.Add(texture2D);
|
||||
Exported.Add((texture2D, ColorSpace.sRGB));
|
||||
m_exportMap.Add(new ExportKey(src, ConvertTypes.None), index);
|
||||
|
||||
return index;
|
||||
|
|
@ -114,7 +115,33 @@ namespace VRMShaders
|
|||
/// <returns></returns>
|
||||
public int ExportLinear(Texture src)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (src == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var exportKey = new ExportKey(src, ConvertTypes.None);
|
||||
|
||||
// search cache
|
||||
if (m_exportMap.TryGetValue(exportKey, out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
index = Exported.Count;
|
||||
var texture2d = src as Texture2D;
|
||||
if (m_useAsset(texture2d))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
texture2d = TextureConverter.CopyTexture(src, TextureImportTypes.Linear, null);
|
||||
}
|
||||
Exported.Add((texture2d, ColorSpace.Linear));
|
||||
m_exportMap.Add(exportKey, index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -147,7 +174,7 @@ namespace VRMShaders
|
|||
index = Exported.Count;
|
||||
var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture);
|
||||
|
||||
Exported.Add(texture2D);
|
||||
Exported.Add((texture2D, ColorSpace.Linear));
|
||||
if (metallicSmoothTexture != null)
|
||||
{
|
||||
m_exportMap.Add(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), index);
|
||||
|
|
@ -191,7 +218,7 @@ namespace VRMShaders
|
|||
texture2D = NormalConverter.Export(src);
|
||||
}
|
||||
|
||||
Exported.Add(texture2D);
|
||||
Exported.Add((texture2D, ColorSpace.Linear));
|
||||
m_exportMap.Add(new ExportKey(src, ConvertTypes.Normal), index);
|
||||
|
||||
return index;
|
||||
|
|
@ -200,9 +227,7 @@ namespace VRMShaders
|
|||
/// <summary>
|
||||
/// 画像のバイト列を得る
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <returns></returns>
|
||||
public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture)
|
||||
public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture, ColorSpace colorSpace)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -211,22 +236,38 @@ namespace VRMShaders
|
|||
{
|
||||
return (png, "image/png");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。
|
||||
return CopyTextureAndGetBytesWithMime(texture, colorSpace);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
// fail to EncodeToPng
|
||||
// System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.
|
||||
// example, ".DDS" Texture object in Editor.
|
||||
Debug.LogWarning(ex);
|
||||
|
||||
// Read/Write が許可されていない Texture2D オブジェクトはこの関数に渡されるべきではない。
|
||||
// なぜなら Texture2D の色空間は、対応する glTF プロパティ指定の色空間と一致していなければならないが
|
||||
// Read/Write が許可されていない場合、その条件を守って変換することができないからである。
|
||||
// したがって、この関数に渡す前に glTF プロパティ指定の色空間を加味して Copy Texture して、それを渡すべきである。
|
||||
|
||||
throw;
|
||||
// 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。
|
||||
return CopyTextureAndGetBytesWithMime(texture, colorSpace);
|
||||
}
|
||||
}
|
||||
|
||||
private static (byte[] bytes, string mime) CopyTextureAndGetBytesWithMime(Texture2D texture, ColorSpace colorSpace)
|
||||
{
|
||||
var copiedTex = TextureConverter.CopyTexture(texture, colorSpace, null);
|
||||
var bytes = copiedTex.EncodeToPNG();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
UnityEngine.Object.Destroy(copiedTex);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(copiedTex);
|
||||
}
|
||||
|
||||
throw new ArgumentException("Invalid Texture2D");
|
||||
return (bytes, "image/png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
|
|
@ -31,16 +32,16 @@ namespace VRMShaders
|
|||
|
||||
public static class TextureImportTypesExtensions
|
||||
{
|
||||
public static RenderTextureReadWrite GetColorSpace(this TextureImportTypes textureType)
|
||||
public static ColorSpace GetColorSpace(this TextureImportTypes textureType)
|
||||
{
|
||||
switch (textureType)
|
||||
{
|
||||
case TextureImportTypes.sRGB:
|
||||
return RenderTextureReadWrite.sRGB;
|
||||
return ColorSpace.sRGB;
|
||||
case TextureImportTypes.Linear:
|
||||
case TextureImportTypes.StandardMap:
|
||||
case TextureImportTypes.NormalMap:
|
||||
return RenderTextureReadWrite.Linear;
|
||||
return ColorSpace.Linear;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user