178 lines
8.1 KiB
C#
178 lines
8.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using NUnit.Framework;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using VRMShaders;
|
|
|
|
namespace UniGLTF
|
|
{
|
|
public sealed class EditorTextureSerializerTests
|
|
{
|
|
private static readonly string AssetPath = "Assets/UniGLTF/Tests/UniGLTF";
|
|
private static readonly string SrgbGrayImageName = "4x4_gray_import_as_srgb";
|
|
private static readonly string LinearGrayImageName = "4x4_gray_import_as_linear";
|
|
private static readonly string NormalMapGrayImageName = "4x4_gray_import_as_normal_map";
|
|
private static readonly Texture2D SrgbGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{SrgbGrayImageName}.png");
|
|
private static readonly Texture2D LinearGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{LinearGrayImageName}.png");
|
|
private static readonly Texture2D NormalMapGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{NormalMapGrayImageName}.png");
|
|
private static readonly Color32 JustGray = new Color32(127, 127, 127, 255);
|
|
private static readonly Color32 SrgbGrayInSrgb = JustGray;
|
|
private static readonly Color32 SrgbGrayInLinear = ((Color)SrgbGrayInSrgb).linear;
|
|
private static readonly Color32 LinearGrayInLinear = JustGray;
|
|
private static readonly Color32 LinearGrayInSrgb = ((Color)LinearGrayInLinear).gamma;
|
|
private static readonly Color32 NormalizedLinearGrayInLinear = new Color32(127, 127, 255, 255);
|
|
|
|
[Test]
|
|
public void InputAssetsRawImage()
|
|
{
|
|
Assert.AreEqual(SrgbGrayInSrgb, GetFirstPixelInTexture2D(SrgbGrayTex));
|
|
|
|
// Image color space is sRGB even though Texture color space was Linear.
|
|
Assert.AreEqual(SrgbGrayInSrgb, GetFirstPixelInTexture2D(LinearGrayTex));
|
|
}
|
|
|
|
[Test]
|
|
public void CopyToSrgbRenderTexture()
|
|
{
|
|
var srgbRt = RenderTexture.GetTemporary(4, 4, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
|
|
|
Graphics.Blit(SrgbGrayTex, srgbRt);
|
|
Assert.AreEqual(SrgbGrayInSrgb, GetFirstPixelInRenderTexture(srgbRt));
|
|
|
|
Graphics.Blit(LinearGrayTex, srgbRt);
|
|
Assert.AreEqual(LinearGrayInSrgb, GetFirstPixelInRenderTexture(srgbRt));
|
|
|
|
RenderTexture.ReleaseTemporary(srgbRt);
|
|
}
|
|
|
|
[Test]
|
|
public void CopyToLinearRenderTexture()
|
|
{
|
|
var linearRt = RenderTexture.GetTemporary(4, 4, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
|
|
Graphics.Blit(SrgbGrayTex, linearRt);
|
|
Assert.AreEqual(SrgbGrayInLinear, GetFirstPixelInRenderTexture(linearRt));
|
|
|
|
Graphics.Blit(LinearGrayTex, linearRt);
|
|
Assert.AreEqual(LinearGrayInLinear, GetFirstPixelInRenderTexture(linearRt));
|
|
|
|
RenderTexture.ReleaseTemporary(linearRt);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignSrgbImageToSrgbTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_MainTex");
|
|
Assert.AreEqual(SrgbGrayInSrgb, GetFirstPixelInTexture2D(exportedTex));
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignLinearImageToSrgbTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_MainTex");
|
|
Assert.AreEqual(LinearGrayInSrgb, GetFirstPixelInTexture2D(exportedTex));
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignSrgbImageToLinearTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_OcclusionMap");
|
|
// R channel is occlusion in glTF spec.
|
|
Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignLinearImageToLinearTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_OcclusionMap");
|
|
// R channel is occlusion in glTF spec.
|
|
Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignLinearImageToNormalTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_BumpMap");
|
|
Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex));
|
|
// B channel is different from 127. Because it will be normalized as normal vector.
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
[Test]
|
|
public void AssignLinearImageAsNormalMapSettingsToNormalTextureProperty()
|
|
{
|
|
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(NormalMapGrayTex, NormalMapGrayImageName, "_BumpMap");
|
|
Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex));
|
|
// B channel is different from 127. Because it will be normalized as normal vector.
|
|
UnityEngine.Object.DestroyImmediate(exportedTex);
|
|
}
|
|
|
|
private static Texture2D AssignTextureToMaterialPropertyAndExportAndExtract(Texture2D srcTex, string srcImageName, string propertyName)
|
|
{
|
|
// Prepare
|
|
var root = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
|
var mat = new Material(Shader.Find("Standard"));
|
|
mat.SetTexture(propertyName, srcTex);
|
|
root.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
|
|
|
// Export glTF
|
|
var data = new ExportingGltfData();
|
|
using (var exporter = new gltfExporter(data, new GltfExportSettings
|
|
{
|
|
InverseAxis = Axes.X,
|
|
ExportOnlyBlendShapePosition = false,
|
|
UseSparseAccessorForMorphTarget = false,
|
|
DivideVertexBuffer = false,
|
|
}))
|
|
{
|
|
exporter.Prepare(root);
|
|
exporter.Export(new EditorTextureSerializer());
|
|
}
|
|
var gltf = data.Gltf;
|
|
Assert.AreEqual(1, gltf.images.Count);
|
|
var exportedImage = gltf.images[0];
|
|
Assert.AreEqual("image/png", exportedImage.mimeType);
|
|
Assert.AreEqual(srcImageName, exportedImage.name);
|
|
|
|
UnityEngine.Object.DestroyImmediate(mat);
|
|
UnityEngine.Object.DestroyImmediate(root);
|
|
|
|
using (var parsed = GltfData.CreateFromGltfDataForTest(gltf, data.BinBytes))
|
|
{
|
|
// Extract Image to Texture2D
|
|
var exportedBytes = parsed.GetBytesFromBufferView(exportedImage.bufferView).ToArray();
|
|
var exportedTexture = new Texture2D(2, 2, TextureFormat.ARGB32, mipChain: false, linear: false);
|
|
Assert.IsTrue(exportedTexture.LoadImage(exportedBytes)); // Always true ?
|
|
Assert.AreEqual(srcTex.width, exportedTexture.width);
|
|
Assert.AreEqual(srcTex.height, exportedTexture.height);
|
|
|
|
return exportedTexture;
|
|
}
|
|
}
|
|
|
|
private static Color32 GetFirstPixelInTexture2D(Texture2D tex)
|
|
{
|
|
return tex.GetPixels32()[0];
|
|
}
|
|
|
|
private static Color32 GetFirstPixelInRenderTexture(RenderTexture rt)
|
|
{
|
|
// This function copies memory values and just read, so Texture2D's color space is not important.
|
|
var srgbTex = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, mipChain: false, linear: false);
|
|
RenderTexture.active = rt;
|
|
srgbTex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
|
|
srgbTex.Apply();
|
|
RenderTexture.active = null;
|
|
var pixel = GetFirstPixelInTexture2D(srgbTex);
|
|
UnityEngine.Object.DestroyImmediate(srgbTex);
|
|
return pixel;
|
|
}
|
|
}
|
|
}
|