mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-15 15:11:43 -05:00
192 lines
6.0 KiB
C#
192 lines
6.0 KiB
C#
using System;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
|
|
namespace UniGLTF
|
|
{
|
|
public interface ITextureConverter
|
|
{
|
|
Texture2D GetImportTexture(Texture2D texture);
|
|
Texture2D GetExportTexture(Texture2D texture);
|
|
}
|
|
|
|
public static class TextureConverter
|
|
{
|
|
public delegate Color32 ColorConversion(Color32 color);
|
|
|
|
public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial)
|
|
{
|
|
var copyTexture = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial);
|
|
if (colorConversion != null)
|
|
{
|
|
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
|
|
copyTexture.Apply();
|
|
}
|
|
copyTexture.name = texture.name;
|
|
return copyTexture;
|
|
}
|
|
|
|
public static void AppendTextureExtension(Texture texture, string extension)
|
|
{
|
|
if (!texture.name.EndsWith(extension))
|
|
{
|
|
texture.name = texture.name + extension;
|
|
}
|
|
}
|
|
|
|
public static void RemoveTextureExtension(Texture texture, string extension)
|
|
{
|
|
if (texture.name.EndsWith(extension))
|
|
{
|
|
texture.name = texture.name.Replace(extension, "");
|
|
}
|
|
}
|
|
}
|
|
|
|
class MetallicRoughnessConverter : ITextureConverter
|
|
{
|
|
private const string m_extension = ".metallicRoughness";
|
|
|
|
private float _smoothness;
|
|
|
|
public MetallicRoughnessConverter(float smoothness)
|
|
{
|
|
_smoothness = smoothness;
|
|
}
|
|
|
|
public Texture2D GetImportTexture(Texture2D texture)
|
|
{
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null);
|
|
TextureConverter.AppendTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
|
|
public Texture2D GetExportTexture(Texture2D texture)
|
|
{
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Export, null);
|
|
TextureConverter.RemoveTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
|
|
public Color32 Import(Color32 src)
|
|
{
|
|
// Roughness(glTF): dst.g -> Smoothness(Unity): src.a (with conversion)
|
|
// Metallic(glTF) : dst.b -> Metallic(Unity) : src.r
|
|
return new Color32
|
|
{
|
|
r = src.b,
|
|
g = 0,
|
|
b = 0,
|
|
// Bake roughness values into a texture.
|
|
// See: https://github.com/dwango/UniVRM/issues/212.
|
|
a = (byte)(255 - Math.Min(src.g * (1.0f - _smoothness), 255)),
|
|
};
|
|
}
|
|
|
|
public Color32 Export(Color32 src)
|
|
{
|
|
// Smoothness(Unity): src.a -> Roughness(glTF): dst.g (with conversion)
|
|
// Metallic(Unity) : src.r -> Metallic(glTF) : dst.b
|
|
return new Color32
|
|
{
|
|
r = 0,
|
|
// Bake smoothness values into a texture.
|
|
// See: https://github.com/dwango/UniVRM/issues/212.
|
|
g = (byte)(255 - Math.Min(src.a * _smoothness, 255)),
|
|
b = src.r,
|
|
a = 255,
|
|
};
|
|
}
|
|
}
|
|
|
|
class NormalConverter : ITextureConverter
|
|
{
|
|
private const string m_extension = ".normal";
|
|
|
|
private Material m_decoder;
|
|
private Material GetDecoder()
|
|
{
|
|
if (m_decoder == null)
|
|
{
|
|
m_decoder = new Material(Shader.Find("UniGLTF/NormalMapDecoder"));
|
|
}
|
|
return m_decoder;
|
|
}
|
|
|
|
private Material m_encoder;
|
|
private Material GetEncoder()
|
|
{
|
|
if (m_encoder == null)
|
|
{
|
|
m_encoder = new Material(Shader.Find("UniGLTF/NormalMapEncoder"));
|
|
}
|
|
return m_encoder;
|
|
}
|
|
|
|
// GLTF data to Unity texture
|
|
// ConvertToNormalValueFromRawColorWhenCompressionIsRequired
|
|
public Texture2D GetImportTexture(Texture2D texture)
|
|
{
|
|
var mat = GetEncoder();
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat);
|
|
TextureConverter.AppendTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
|
|
// Unity texture to GLTF data
|
|
// ConvertToRawColorWhenNormalValueIsCompressed
|
|
public Texture2D GetExportTexture(Texture2D texture)
|
|
{
|
|
var mat = GetDecoder();
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat);
|
|
TextureConverter.RemoveTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
}
|
|
|
|
class OcclusionConverter : ITextureConverter
|
|
{
|
|
private const string m_extension = ".occlusion";
|
|
|
|
public Texture2D GetImportTexture(Texture2D texture)
|
|
{
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Import, null);
|
|
TextureConverter.AppendTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
|
|
public Texture2D GetExportTexture(Texture2D texture)
|
|
{
|
|
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Export, null);
|
|
TextureConverter.RemoveTextureExtension(converted, m_extension);
|
|
return converted;
|
|
}
|
|
|
|
public Color32 Import(Color32 src)
|
|
{
|
|
return new Color32
|
|
{
|
|
r = 0,
|
|
g = src.r,
|
|
b = 0,
|
|
a = 255,
|
|
};
|
|
}
|
|
|
|
public Color32 Export(Color32 src)
|
|
{
|
|
return new Color32
|
|
{
|
|
r = src.g,
|
|
g = 0,
|
|
b = 0,
|
|
a = 255,
|
|
};
|
|
}
|
|
}
|
|
}
|