Merge pull request #2264 from Santarh/basisu2

Can load y-flipped KHR_texture_basisu texture at runtime.
This commit is contained in:
ousttrue
2024-03-19 16:36:10 +09:00
committed by GitHub
5 changed files with 104 additions and 37 deletions

View File

@@ -0,0 +1,48 @@
using System;
using System.Threading.Tasks;
using Unity.Collections;
using UnityEngine;
#if USE_COM_UNITY_CLOUD_KTX
using KtxUnity;
#endif
namespace VRMShaders
{
public sealed class KtxTextureDeserializer : ITextureDeserializer
{
public async Task<Texture2D> LoadTextureAsync(DeserializingTextureInfo textureInfo, IAwaitCaller awaitCaller)
{
#if USE_COM_UNITY_CLOUD_KTX
if (textureInfo.ImageData == null) return null;
// NOTE: IAwaitCaller を無視するので、同期読み込みを期待する環境で同期読み込みができない
try
{
var ktxTexture = new KtxTexture();
using var nativeBytes = new NativeArray<byte>(textureInfo.ImageData, Allocator.Persistent);
var result = await ktxTexture.LoadFromBytes(
nativeBytes,
linear: textureInfo.ColorSpace == ColorSpace.Linear,
mipChain: textureInfo.UseMipmap
);
if (result is { errorCode: ErrorCode.Success })
{
result.texture.wrapModeU = textureInfo.WrapModeU;
result.texture.wrapModeV = textureInfo.WrapModeV;
result.texture.filterMode = textureInfo.FilterMode;
return result.texture;
}
return null;
}
catch (Exception e)
{
Debug.LogException(e);
return null;
}
#else
return null;
#endif
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 76c69cc9d1f84e988ca6fb6391bee3cb
timeCreated: 1710422105

View File

@@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using UnityEngine;
namespace VRMShaders
{
/// <summary>
/// Unity の ImageConversion.LoadImage を用いて PNG/JPG の読み込みを実現する
/// </summary>
public sealed class UnitySupportedImageTypeDeserializer : ITextureDeserializer
{
public async Task<Texture2D> LoadTextureAsync(DeserializingTextureInfo textureInfo, IAwaitCaller awaitCaller)
{
if (textureInfo.ImageData == null) return null;
try
{
var texture = new Texture2D(2, 2, TextureFormat.ARGB32, textureInfo.UseMipmap, textureInfo.ColorSpace == ColorSpace.Linear);
texture.LoadImage(textureInfo.ImageData);
await awaitCaller.NextFrame();
texture.wrapModeU = textureInfo.WrapModeU;
texture.wrapModeV = textureInfo.WrapModeV;
texture.filterMode = textureInfo.FilterMode;
return texture;
}
catch (Exception e)
{
Debug.LogException(e);
return null;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f9ea656b813c41caaa40318be35b9ed2
timeCreated: 1710423586

View File

@@ -1,51 +1,30 @@
using System;
using System.Threading.Tasks;
using Unity.Collections;
using System.Threading.Tasks;
using UnityEngine;
#if USE_COM_UNITY_CLOUD_KTX
using KtxUnity;
#endif
namespace VRMShaders
{
/// <summary>
/// Unity の ImageConversion.LoadImage を用いて PNG/JPG の読み込みを実現する
/// Runtime での Texture2D 生成を実現するデフォルトの実装
/// </summary>
public sealed class UnityTextureDeserializer : ITextureDeserializer
{
private readonly UnitySupportedImageTypeDeserializer _unitySupportedDeserializer = new();
private readonly KtxTextureDeserializer _ktxTextureDeserializer = new();
public async Task<Texture2D> LoadTextureAsync(DeserializingTextureInfo textureInfo, IAwaitCaller awaitCaller)
{
Texture2D texture = null;
switch (textureInfo.DataMimeType)
{
case "image/png":
case "image/jpeg":
texture = new Texture2D(2, 2, TextureFormat.ARGB32, textureInfo.UseMipmap, textureInfo.ColorSpace == ColorSpace.Linear);
if (textureInfo.ImageData != null)
{
texture.LoadImage(textureInfo.ImageData);
await awaitCaller.NextFrame();
}
texture = await _unitySupportedDeserializer.LoadTextureAsync(textureInfo, awaitCaller);
break;
case "image/jpeg":
texture = await _unitySupportedDeserializer.LoadTextureAsync(textureInfo, awaitCaller);
break;
case "image/ktx2":
texture = await _ktxTextureDeserializer.LoadTextureAsync(textureInfo, awaitCaller);
break;
#if USE_COM_UNITY_CLOUD_KTX
case "image/ktx":
var ktxTexture = new KtxTexture();
var nativeBytes = new NativeArray<byte>(textureInfo.ImageData, Allocator.Temp);
try
{
var nativeSlice = new NativeSlice<byte>(nativeBytes);
var result = await ktxTexture.LoadFromBytes(nativeSlice, textureInfo.ColorSpace == ColorSpace.Linear);
if (result != null && result.errorCode == ErrorCode.Success)
{
texture = result.texture;
}
break;
}
finally
{
nativeBytes.Dispose();
}
#endif
default:
if (string.IsNullOrEmpty(textureInfo.DataMimeType))
{
@@ -58,12 +37,12 @@ namespace VRMShaders
break;
}
if (texture != null)
if (texture == null)
{
texture.wrapModeU = textureInfo.WrapModeU;
texture.wrapModeV = textureInfo.WrapModeV;
texture.filterMode = textureInfo.FilterMode;
Debug.Log($"Failed to load texture from image data.");
texture = new Texture2D(2, 2, TextureFormat.ARGB32, textureInfo.UseMipmap, textureInfo.ColorSpace == ColorSpace.Linear);
}
return texture;
}
}