UniVRM/Assets/VRMShaders/Runtime/TextureConverter.cs
2021-03-24 20:57:41 +09:00

97 lines
3.1 KiB
C#

using System;
using System.Linq;
using UnityEngine;
namespace VRMShaders
{
public static class TextureConverter
{
public delegate Color32 ColorConversion(Color32 color);
public static Texture2D Convert(Texture texture, TextureImportTypes textureType, ColorConversion colorConversion, Material convertMaterial)
{
var copyTexture = CopyTexture(texture, textureType, convertMaterial);
if (colorConversion != null)
{
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
copyTexture.Apply();
}
copyTexture.name = texture.name;
return copyTexture;
}
struct ColorSpaceScope : IDisposable
{
bool m_sRGBWrite;
public ColorSpaceScope(RenderTextureReadWrite colorSpace)
{
m_sRGBWrite = GL.sRGBWrite;
switch (colorSpace)
{
case RenderTextureReadWrite.Linear:
GL.sRGBWrite = false;
break;
case RenderTextureReadWrite.sRGB:
default:
GL.sRGBWrite = true;
break;
}
}
public ColorSpaceScope(bool sRGBWrite)
{
m_sRGBWrite = GL.sRGBWrite;
GL.sRGBWrite = sRGBWrite;
}
public void Dispose()
{
GL.sRGBWrite = m_sRGBWrite;
}
}
public static Texture2D CopyTexture(Texture src, TextureImportTypes textureType, Material material)
{
Texture2D dst = null;
RenderTextureReadWrite colorSpace = textureType.GetColorSpace();
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace);
using (var scope = new ColorSpaceScope(colorSpace))
{
if (material != null)
{
Graphics.Blit(src, renderTexture, material);
}
else
{
Graphics.Blit(src, renderTexture);
}
}
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear);
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;
if (Application.isEditor)
{
GameObject.DestroyImmediate(renderTexture);
}
else
{
GameObject.Destroy(renderTexture);
}
return dst;
}
}
}