Merge pull request #984 from Santarh/importWihtoutAlpha

Export textures without alpha channel if the texture was linear, normal, or metallic-roughness.
This commit is contained in:
ousttrue 2021-05-27 18:40:05 +09:00 committed by GitHub
commit b67d2f4564
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 57 deletions

View File

@ -36,14 +36,14 @@ namespace VRMShaders
// ConvertToNormalValueFromRawColorWhenCompressionIsRequired
public static Texture2D Import(Texture2D texture)
{
return TextureConverter.Convert(texture, ColorSpace.Linear, null, Encoder);
return TextureConverter.CopyTexture(texture, ColorSpace.Linear, false, Encoder);
}
// Unity texture to GLTF data
// ConvertToRawColorWhenNormalValueIsCompressed
public static Texture2D Export(Texture texture)
{
return TextureConverter.Convert(texture, ColorSpace.Linear, null, Decoder);
return TextureConverter.CopyTexture(texture, ColorSpace.Linear, false, Decoder);
}
}
}

View File

@ -26,11 +26,12 @@ namespace VRMShaders
public static Texture2D Import(Texture2D metallicRoughnessTexture,
float metallicFactor, float roughnessFactor, Texture2D occlusionTexture)
{
// TODO: Replace with Shader implementation
if (metallicRoughnessTexture != null && occlusionTexture != null)
{
if (metallicRoughnessTexture == occlusionTexture)
{
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
for (int i = 0; i < metallicRoughnessPixels.Length; ++i)
{
@ -43,9 +44,9 @@ namespace VRMShaders
}
else
{
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null);
var occlusionPixels = copyOcclusion.GetPixels32();
if (metallicRoughnessPixels.Length != occlusionPixels.Length)
{
@ -58,12 +59,13 @@ namespace VRMShaders
copyMetallicRoughness.SetPixels32(metallicRoughnessPixels);
copyMetallicRoughness.Apply();
copyMetallicRoughness.name = metallicRoughnessTexture.name;
DestroyTexture(copyOcclusion);
return copyMetallicRoughness;
}
}
else if (metallicRoughnessTexture != null)
{
var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(x, metallicFactor, roughnessFactor, default)).ToArray());
copyTexture.Apply();
copyTexture.name = metallicRoughnessTexture.name;
@ -71,7 +73,7 @@ namespace VRMShaders
}
else if (occlusionTexture != null)
{
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, true, null);
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(default, metallicFactor, roughnessFactor, x)).ToArray());
copyTexture.Apply();
copyTexture.name = occlusionTexture.name;
@ -98,22 +100,26 @@ namespace VRMShaders
public static Texture2D Export(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture)
{
// TODO: Replace with Shader implementation
if (metallicSmoothTexture != null && occlusionTexture != null)
{
if (metallicSmoothTexture == occlusionTexture)
{
var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null);
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(x, smoothness, x)).ToArray());
copyTexture.Apply();
copyTexture.name = metallicSmoothTexture.name;
return copyTexture;
var dst = TextureConverter.CreateEmptyTextureWithSettings(metallicSmoothTexture, ColorSpace.Linear, false);
var linearTexture = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, true, null);
dst.SetPixels32(linearTexture.GetPixels32().Select(x => ExportPixel(x, smoothness, x)).ToArray());
dst.Apply();
dst.name = metallicSmoothTexture.name;
DestroyTexture(linearTexture);
return dst;
}
else
{
var copyMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null);
var metallicSmoothPixels = copyMetallicSmooth.GetPixels32();
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
var occlusionPixels = copyOcclusion.GetPixels32();
var dst = TextureConverter.CreateEmptyTextureWithSettings(metallicSmoothTexture, ColorSpace.Linear, false);
var linearMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, true, null);
var metallicSmoothPixels = linearMetallicSmooth.GetPixels32();
var linearOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null);
var occlusionPixels = linearOcclusion.GetPixels32();
if (metallicSmoothPixels.Length != occlusionPixels.Length)
{
throw new NotImplementedException();
@ -122,27 +128,33 @@ namespace VRMShaders
{
metallicSmoothPixels[i] = ExportPixel(metallicSmoothPixels[i], smoothness, occlusionPixels[i]);
}
copyMetallicSmooth.SetPixels32(metallicSmoothPixels);
copyMetallicSmooth.Apply();
copyMetallicSmooth.name = metallicSmoothTexture.name;
return copyMetallicSmooth;
dst.SetPixels32(metallicSmoothPixels);
dst.Apply();
dst.name = metallicSmoothTexture.name;
DestroyTexture(linearMetallicSmooth);
DestroyTexture(linearOcclusion);
return dst;
}
}
else if (metallicSmoothTexture)
{
var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null);
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(x, smoothness, default)).ToArray());
copyTexture.Apply();
copyTexture.name = metallicSmoothTexture.name;
return copyTexture;
var dst = TextureConverter.CreateEmptyTextureWithSettings(metallicSmoothTexture, ColorSpace.Linear, false);
var linearMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, true, null);
dst.SetPixels32(linearMetallicSmooth.GetPixels32().Select(x => ExportPixel(x, smoothness, default)).ToArray());
dst.Apply();
dst.name = metallicSmoothTexture.name;
DestroyTexture(linearMetallicSmooth);
return dst;
}
else if (occlusionTexture)
{
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(default, smoothness, x)).ToArray());
copyTexture.Apply();
copyTexture.name = occlusionTexture.name;
return copyTexture;
var dst = TextureConverter.CreateEmptyTextureWithSettings(metallicSmoothTexture, ColorSpace.Linear, false);
var linearOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null);
dst.SetPixels32(linearOcclusion.GetPixels32().Select(x => ExportPixel(default, smoothness, x)).ToArray());
dst.Apply();
dst.name = occlusionTexture.name;
DestroyTexture(linearOcclusion);
return dst;
}
else
{
@ -162,5 +174,17 @@ namespace VRMShaders
return dst;
}
private static void DestroyTexture(Texture obj)
{
if (Application.isPlaying)
{
UnityEngine.Object.Destroy(obj);
}
else
{
UnityEngine.Object.DestroyImmediate(obj);
}
}
}
}

View File

@ -41,7 +41,8 @@ namespace UniGLTF
private static (byte[] bytes, string mime) CopyTextureAndGetBytesWithMime(Texture2D texture, ColorSpace colorSpace)
{
var copiedTex = TextureConverter.CopyTexture(texture, colorSpace, null);
var needsAlpha = texture.format != TextureFormat.RGB24;
var copiedTex = TextureConverter.CopyTexture(texture, colorSpace, needsAlpha, null);
var bytes = copiedTex.EncodeToPNG();
if (Application.isPlaying)
{

View File

@ -8,23 +8,24 @@ namespace VRMShaders
{
public static class TextureConverter
{
public delegate Color32 ColorConversion(Color32 color);
public static Texture2D Convert(Texture texture, ColorSpace dstColorSpace, ColorConversion colorConversion, Material convertMaterial)
public static Texture2D CreateEmptyTextureWithSettings(Texture src, ColorSpace dstColorSpace, bool dstNeedsAlpha)
{
var copyTexture = CopyTexture(texture, dstColorSpace, convertMaterial);
if (colorConversion != null)
{
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
copyTexture.Apply();
}
copyTexture.name = texture.name;
return copyTexture;
var texFormat = dstNeedsAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24;
var dst = new Texture2D(src.width, src.height, texFormat, src.HasMipMap(), dstColorSpace == ColorSpace.Linear);
dst.name = src.name;
dst.anisoLevel = src.anisoLevel;
dst.filterMode = src.filterMode;
dst.mipMapBias = src.mipMapBias;
dst.wrapMode = src.wrapMode;
dst.wrapModeU = src.wrapModeU;
dst.wrapModeV = src.wrapModeV;
dst.wrapModeW = src.wrapModeW;
return dst;
}
public static Texture2D CopyTexture(Texture src, ColorSpace dstColorSpace, Material material)
public static Texture2D CopyTexture(Texture src, ColorSpace dstColorSpace, bool dstNeedsAlpha, Material material)
{
Texture2D dst = null;
RenderTextureReadWrite readWrite;
switch (dstColorSpace)
{
@ -49,16 +50,8 @@ namespace VRMShaders
Graphics.Blit(src, renderTexture);
}
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, src.HasMipMap(), readWrite == RenderTextureReadWrite.Linear);
var dst = CreateEmptyTextureWithSettings(src, dstColorSpace, dstNeedsAlpha);
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
dst.name = src.name;
dst.anisoLevel = src.anisoLevel;
dst.filterMode = src.filterMode;
dst.mipMapBias = src.mipMapBias;
dst.wrapMode = src.wrapMode;
dst.wrapModeU = src.wrapModeU;
dst.wrapModeV = src.wrapModeV;
dst.wrapModeW = src.wrapModeW;
dst.Apply();
RenderTexture.active = null;

View File

@ -79,7 +79,7 @@ namespace VRMShaders
}
else
{
texture2D = TextureConverter.CopyTexture(src, ColorSpace.sRGB, null);
texture2D = TextureConverter.CopyTexture(src, ColorSpace.sRGB, true, null);
}
m_exported.Add((texture2D, ColorSpace.sRGB));
m_exportMap.Add(new ExportKey(src, ExportTypes.Srgb), index);
@ -110,7 +110,7 @@ namespace VRMShaders
}
else
{
texture2d = TextureConverter.CopyTexture(src, ColorSpace.Linear, null);
texture2d = TextureConverter.CopyTexture(src, ColorSpace.Linear, false, null);
}
m_exported.Add((texture2d, ColorSpace.Linear));
m_exportMap.Add(exportKey, index);

View File

@ -36,7 +36,7 @@ namespace VRMShaders
{
var nonReadableTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable.png");
Assert.False(nonReadableTex.isReadable);
var copiedTex = TextureConverter.CopyTexture(nonReadableTex, ColorSpace.sRGB, null);
var copiedTex = TextureConverter.CopyTexture(nonReadableTex, ColorSpace.sRGB, true, null);
var pixels = copiedTex.GetPixels32(miplevel: 0);
Assert.AreEqual(pixels.Length, PngTextureValues.Length);
for (var idx = 0; idx < pixels.Length; ++idx)
@ -50,7 +50,7 @@ namespace VRMShaders
{
var compressedTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable_compressed.dds");
Assert.False(compressedTex.isReadable);
var copiedTex = TextureConverter.CopyTexture(compressedTex, ColorSpace.sRGB, null);
var copiedTex = TextureConverter.CopyTexture(compressedTex, ColorSpace.sRGB, true, null);
var pixels = copiedTex.GetPixels32(miplevel: 0);
Assert.AreEqual(pixels.Length, DdsTextureValues.Length);
for (var idx = 0; idx < pixels.Length; ++idx)
@ -58,5 +58,25 @@ namespace VRMShaders
Assert.AreEqual(DdsTextureValues[idx], pixels[idx]);
}
}
[Test]
public void CopyAttributes()
{
var src = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable.png");
var dst = TextureConverter.CopyTexture(src, ColorSpace.sRGB, false, null);
Assert.AreEqual(src.name, dst.name);
Assert.AreEqual(src.anisoLevel, dst.anisoLevel);
Assert.AreEqual(src.filterMode, dst.filterMode);
Assert.AreEqual(src.mipMapBias, dst.mipMapBias);
Assert.AreEqual(src.wrapMode, dst.wrapMode);
Assert.AreEqual(src.wrapModeU, dst.wrapModeU);
Assert.AreEqual(src.wrapModeV, dst.wrapModeV);
Assert.AreEqual(src.wrapModeW, dst.wrapModeW);
Assert.AreEqual(src.mipmapCount, dst.mipmapCount);
Assert.AreEqual(src.width, dst.width);
Assert.AreEqual(src.height, dst.height);
Assert.AreEqual(src.format, dst.format);
Assert.AreEqual(src.imageContentsHash, dst.imageContentsHash);
}
}
}