mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-16 15:48:22 -05:00
Image の MimeType を ITextureDeserializer に伝達する
This commit is contained in:
@@ -314,18 +314,18 @@ namespace UniGLTF
|
||||
return result;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> GetBytesFromImage(int imageIndex)
|
||||
public (ArraySegment<byte> binary, string mimeType)? GetBytesFromImage(int imageIndex)
|
||||
{
|
||||
if (imageIndex < 0 || imageIndex >= GLTF.images.Count) return new ArraySegment<byte>();
|
||||
if (imageIndex < 0 || imageIndex >= GLTF.images.Count) return default;
|
||||
|
||||
var image = GLTF.images[imageIndex];
|
||||
if (string.IsNullOrEmpty(image.uri))
|
||||
{
|
||||
return GetBytesFromBufferView(image.bufferView);
|
||||
return (GetBytesFromBufferView(image.bufferView), image.mimeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetBytesFromUri(image.uri);
|
||||
return (GetBytesFromUri(image.uri), image.mimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace UniGLTF
|
||||
{
|
||||
var (offset, scale) =
|
||||
GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
|
||||
var (key, textureParam) = GltfTextureImporter.CreateSRGB(data,
|
||||
var (key, textureParam) = GltfTextureImporter.CreateSrgb(data,
|
||||
src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
|
||||
textureSlots.Add("_MainTex", textureParam);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace UniGLTF
|
||||
public static (SubAssetKey, TextureDescriptor) BaseColorTexture(GltfData data, glTFMaterial src)
|
||||
{
|
||||
var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
|
||||
return GltfTextureImporter.CreateSRGB(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
|
||||
return GltfTextureImporter.CreateSrgb(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
|
||||
}
|
||||
|
||||
public static (SubAssetKey, TextureDescriptor) StandardTexture(GltfData data, glTFMaterial src)
|
||||
@@ -84,7 +84,7 @@ namespace UniGLTF
|
||||
public static (SubAssetKey, TextureDescriptor) EmissiveTexture(GltfData data, glTFMaterial src)
|
||||
{
|
||||
var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.emissiveTexture);
|
||||
return GltfTextureImporter.CreateSRGB(data, src.emissiveTexture.index, offset, scale);
|
||||
return GltfTextureImporter.CreateSrgb(data, src.emissiveTexture.index, offset, scale);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,32 +11,48 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public static class GltfTextureImporter
|
||||
{
|
||||
public static Byte[] ToArray(ArraySegment<byte> bytes)
|
||||
/// <summary>
|
||||
/// glTF の Texture が存在せず Image のみのものを、Texture として扱いたい場合の関数.
|
||||
/// </summary>
|
||||
public static (SubAssetKey, TextureDescriptor) CreateSrgbFromOnlyImage(GltfData data, int imageIndex, string uniqueName, string uri)
|
||||
{
|
||||
if (bytes.Array == null)
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length)
|
||||
{
|
||||
return bytes.Array;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte[] result = new byte[bytes.Count];
|
||||
Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length);
|
||||
return result;
|
||||
}
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, uniqueName, uri);
|
||||
var texDesc = new TextureDescriptor(
|
||||
uniqueName,
|
||||
string.Empty,
|
||||
uri,
|
||||
Vector2.zero,
|
||||
Vector2.one,
|
||||
default,
|
||||
TextureImportTypes.sRGB,
|
||||
default,
|
||||
default,
|
||||
() =>
|
||||
{
|
||||
var imageBytes = data.GetBytesFromImage(imageIndex);
|
||||
return Task.FromResult<(byte[], string)?>((ToArray(imageBytes?.binary ?? default), null));
|
||||
},
|
||||
default, default, default, default, default);
|
||||
return (texDesc.SubAssetKey, texDesc);
|
||||
}
|
||||
|
||||
public static (SubAssetKey, TextureDescriptor) CreateSRGB(GltfData data, int textureIndex, Vector2 offset, Vector2 scale)
|
||||
public static (SubAssetKey, TextureDescriptor) CreateSrgb(GltfData data, int textureIndex, Vector2 offset, Vector2 scale)
|
||||
{
|
||||
var gltfTexture = data.GLTF.textures[textureIndex];
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
var param = new TextureDescriptor(
|
||||
name,
|
||||
gltfImage.GetExt(),
|
||||
gltfImage.uri,
|
||||
offset, scale,
|
||||
sampler,
|
||||
TextureImportTypes.sRGB,
|
||||
default,
|
||||
default,
|
||||
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
|
||||
default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
|
||||
@@ -46,8 +62,18 @@ namespace UniGLTF
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.Linear, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.Linear, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
var param = new TextureDescriptor(
|
||||
name,
|
||||
gltfImage.GetExt(),
|
||||
gltfImage.uri,
|
||||
offset,
|
||||
scale,
|
||||
sampler,
|
||||
TextureImportTypes.Linear,
|
||||
default,
|
||||
default,
|
||||
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
|
||||
default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
|
||||
@@ -57,8 +83,18 @@ namespace UniGLTF
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.NormalMap, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.NormalMap, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
var param = new TextureDescriptor(
|
||||
name,
|
||||
gltfImage.GetExt(),
|
||||
gltfImage.uri,
|
||||
offset,
|
||||
scale,
|
||||
sampler,
|
||||
TextureImportTypes.NormalMap,
|
||||
default,
|
||||
default,
|
||||
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
|
||||
default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
|
||||
@@ -73,7 +109,7 @@ namespace UniGLTF
|
||||
var gltfTexture = data.GLTF.textures[metallicRoughnessTextureIndex.Value];
|
||||
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri);
|
||||
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, metallicRoughnessTextureIndex.Value);
|
||||
getMetallicRoughnessAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, metallicRoughnessTextureIndex.Value)));
|
||||
getMetallicRoughnessAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, metallicRoughnessTextureIndex.Value));
|
||||
}
|
||||
|
||||
GetTextureBytesAsync getOcclusionAsync = default;
|
||||
@@ -85,10 +121,22 @@ namespace UniGLTF
|
||||
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri);
|
||||
}
|
||||
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, occlusionTextureIndex.Value);
|
||||
getOcclusionAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, occlusionTextureIndex.Value)));
|
||||
getOcclusionAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, occlusionTextureIndex.Value));
|
||||
}
|
||||
|
||||
var texDesc = new TextureDescriptor(name, ".png", null, offset, scale, sampler, TextureImportTypes.StandardMap, metallicFactor, roughnessFactor, getMetallicRoughnessAsync, getOcclusionAsync, default, default, default, default);
|
||||
var texDesc = new TextureDescriptor(
|
||||
name,
|
||||
".png",
|
||||
null,
|
||||
offset,
|
||||
scale,
|
||||
sampler,
|
||||
TextureImportTypes.StandardMap,
|
||||
metallicFactor,
|
||||
roughnessFactor,
|
||||
getMetallicRoughnessAsync,
|
||||
getOcclusionAsync,
|
||||
default, default, default, default);
|
||||
return (texDesc.SubAssetKey, texDesc);
|
||||
}
|
||||
|
||||
@@ -124,7 +172,7 @@ namespace UniGLTF
|
||||
return (offset, scale);
|
||||
}
|
||||
|
||||
public static ArraySegment<byte> GetImageBytesFromTextureIndex(GltfData data, int textureIndex)
|
||||
public static (byte[] binary, string mimeType)? GetImageBytesFromTextureIndex(GltfData data, int textureIndex)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
@@ -140,20 +188,45 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
return data.GetBytesFromImage(imageIndex);
|
||||
if (!imageIndex.HasValue) return default;
|
||||
|
||||
var imageBytes = data.GetBytesFromImage(imageIndex.Value);
|
||||
return (ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: Editor の場合は通常通り読み込む.
|
||||
return data.GetBytesFromImage(GetImageIndexFromTexture(data, textureIndex));
|
||||
var imageIndex = GetImageIndexFromTexture(data, textureIndex);
|
||||
if (!imageIndex.HasValue) return default;
|
||||
|
||||
var imageBytes = data.GetBytesFromImage(imageIndex.Value);
|
||||
return (ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetImageIndexFromTexture(GltfData data, int textureIndex)
|
||||
private static int? GetImageIndexFromTexture(GltfData data, int textureIndex)
|
||||
{
|
||||
if (textureIndex < 0 || textureIndex >= data.GLTF.textures.Count) return -1;
|
||||
if (textureIndex < 0 || textureIndex >= data.GLTF.textures.Count) return default;
|
||||
|
||||
return data.GLTF.textures[textureIndex].source;
|
||||
}
|
||||
|
||||
private static byte[] ToArray(ArraySegment<byte> bytes)
|
||||
{
|
||||
if (bytes.Array == null)
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length)
|
||||
{
|
||||
return bytes.Array;
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = new byte[bytes.Count];
|
||||
Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace VRM
|
||||
meta.Title = gltfMeta.title;
|
||||
if (gltfMeta.texture >= 0)
|
||||
{
|
||||
var (key, param) = GltfTextureImporter.CreateSRGB(Data, gltfMeta.texture, Vector2.zero, Vector2.one);
|
||||
var (key, param) = GltfTextureImporter.CreateSrgb(Data, gltfMeta.texture, Vector2.zero, Vector2.one);
|
||||
meta.Thumbnail = await TextureFactory.GetTextureAsync(param, awaitCaller) as Texture2D;
|
||||
}
|
||||
meta.AllowedUser = gltfMeta.allowedUser;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace VRM
|
||||
texture = GltfTextureImporter.CreateNormal(data, textureIdx, offset, scale);
|
||||
break;
|
||||
default:
|
||||
texture = GltfTextureImporter.CreateSRGB(data, textureIdx, offset, scale);
|
||||
texture = GltfTextureImporter.CreateSrgb(data, textureIdx, offset, scale);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace VRM
|
||||
{
|
||||
if (vrm.meta.texture > -1)
|
||||
{
|
||||
texture = GltfTextureImporter.CreateSRGB(data, vrm.meta.texture, Vector2.zero, Vector2.one);
|
||||
texture = GltfTextureImporter.CreateSrgb(data, vrm.meta.texture, Vector2.zero, Vector2.one);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace UniVRM10
|
||||
try
|
||||
{
|
||||
var (offset, scale) = GetTextureOffsetAndScale(info);
|
||||
pair = GltfTextureImporter.CreateSRGB(data, info.index, offset, scale);
|
||||
pair = GltfTextureImporter.CreateSrgb(data, info.index, offset, scale);
|
||||
return true;
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
|
||||
@@ -106,18 +106,7 @@ namespace UniVRM10
|
||||
}
|
||||
var uniqueName = GlbLowLevelParser.FixNameUnique(used, imageName);
|
||||
|
||||
var objectName = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, uniqueName, gltfImage.uri);
|
||||
|
||||
GetTextureBytesAsync getThumbnailImageBytesAsync = () =>
|
||||
{
|
||||
var bytes = data.GetBytesFromImage(imageIndex);
|
||||
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
|
||||
};
|
||||
var texDesc = new TextureDescriptor(objectName, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
|
||||
getThumbnailImageBytesAsync, default, default,
|
||||
default, default, default
|
||||
);
|
||||
value = (texDesc.SubAssetKey, texDesc);
|
||||
value = GltfTextureImporter.CreateSrgbFromOnlyImage(data, imageIndex, uniqueName, gltfImage.uri);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ namespace VRMShaders
|
||||
/// </summary>
|
||||
public byte[] ImageData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Texture の mimeType
|
||||
/// </summary>
|
||||
public string DataMimeType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Texture に求められる色空間
|
||||
/// </summary>
|
||||
@@ -37,9 +42,10 @@ namespace VRMShaders
|
||||
/// </summary>
|
||||
public TextureWrapMode WrapModeV { get; }
|
||||
|
||||
internal DeserializingTextureInfo(byte[] imageData, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV)
|
||||
internal DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV)
|
||||
{
|
||||
ImageData = imageData;
|
||||
DataMimeType = dataMimeType;
|
||||
ColorSpace = colorSpace;
|
||||
UseMipmap = useMipmap;
|
||||
FilterMode = filterMode;
|
||||
@@ -47,9 +53,10 @@ namespace VRMShaders
|
||||
WrapModeV = wrapModeV;
|
||||
}
|
||||
|
||||
internal DeserializingTextureInfo(byte[] imageData, ColorSpace colorSpace, SamplerParam samplerParam)
|
||||
internal DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, SamplerParam samplerParam)
|
||||
{
|
||||
ImageData = imageData;
|
||||
DataMimeType = dataMimeType;
|
||||
ColorSpace = colorSpace;
|
||||
UseMipmap = samplerParam.EnableMipMap;
|
||||
FilterMode = samplerParam.FilterMode;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace VRMShaders
|
||||
/// File.WriteAllBytes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public delegate Task<byte[]> GetTextureBytesAsync();
|
||||
public delegate Task<(byte[] binary, string mimeType)?> GetTextureBytesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 入力 glTF ファイルを Import した結果生成される、UnityEngine.Texture のアセット 1 つを確定させる Import 情報。
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace VRMShaders
|
||||
// https://docs.unity3d.com/2018.4/Documentation/Manual/StandardShaderMaterialParameterNormalMap.html
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler),
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
@@ -96,14 +96,14 @@ namespace VRMShaders
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
metallicRoughnessTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler),
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler),
|
||||
awaitCaller);
|
||||
}
|
||||
if (texDesc.Index1 != null)
|
||||
{
|
||||
var data1 = await texDesc.Index1();
|
||||
occlusionTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data1, ColorSpace.Linear, texDesc.Sampler),
|
||||
new DeserializingTextureInfo(data1?.binary, data1?.mimeType, ColorSpace.Linear, texDesc.Sampler),
|
||||
awaitCaller);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace VRMShaders
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0, ColorSpace.sRGB, texDesc.Sampler),
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.sRGB, texDesc.Sampler),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
@@ -133,7 +133,7 @@ namespace VRMShaders
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler),
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
|
||||
Reference in New Issue
Block a user