mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 06:19:47 -05:00
Merge pull request #963 from Santarh/refactorTextureExporter
Even if the texture instance is the same, if the color space required by the glTF specification is different, it will be output as a different texture.
This commit is contained in:
commit
49e1ea3f02
|
|
@ -15,12 +15,12 @@ namespace UniGLTF
|
|||
|
||||
public interface IMaterialExporter
|
||||
{
|
||||
glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter);
|
||||
glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter);
|
||||
}
|
||||
|
||||
public class MaterialExporter : IMaterialExporter
|
||||
{
|
||||
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
|
||||
public virtual glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter)
|
||||
{
|
||||
var material = CreateMaterial(m);
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ namespace UniGLTF
|
|||
return material;
|
||||
}
|
||||
|
||||
static void Export_Color(Material m, TextureExporter textureManager, glTFMaterial material)
|
||||
static void Export_Color(Material m, ITextureExporter textureManager, glTFMaterial material)
|
||||
{
|
||||
if (m.HasProperty("_Color"))
|
||||
{
|
||||
|
|
@ -43,7 +43,7 @@ namespace UniGLTF
|
|||
|
||||
if (m.HasProperty("_MainTex"))
|
||||
{
|
||||
var index = textureManager.ExportSRGB(m.GetTexture("_MainTex"));
|
||||
var index = textureManager.ExportAsSRgb(m.GetTexture("_MainTex"));
|
||||
if (index != -1)
|
||||
{
|
||||
material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo()
|
||||
|
|
@ -60,9 +60,9 @@ namespace UniGLTF
|
|||
/// Occlusion, Metallic, Roughness
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="textureManager"></param>
|
||||
/// <param name="textureExporter"></param>
|
||||
/// <param name="material"></param>
|
||||
static void Export_OcclusionMetallicRoughness(Material m, TextureExporter textureManager, glTFMaterial material)
|
||||
static void Export_OcclusionMetallicRoughness(Material m, ITextureExporter textureExporter, glTFMaterial material)
|
||||
{
|
||||
Texture metallicSmoothTexture = default;
|
||||
float smoothness = 1.0f;
|
||||
|
|
@ -88,7 +88,7 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
int index = textureManager.ExportMetallicSmoothnessOcclusion(metallicSmoothTexture, smoothness, occlusionTexture);
|
||||
int index = textureExporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallicSmoothTexture, smoothness, occlusionTexture);
|
||||
|
||||
if (index != -1 && metallicSmoothTexture != null)
|
||||
{
|
||||
|
|
@ -127,11 +127,11 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
static void Export_Normal(Material m, TextureExporter textureManager, glTFMaterial material)
|
||||
static void Export_Normal(Material m, ITextureExporter textureExporter, glTFMaterial material)
|
||||
{
|
||||
if (m.HasProperty("_BumpMap"))
|
||||
{
|
||||
var index = textureManager.ExportNormal(m.GetTexture("_BumpMap"));
|
||||
var index = textureExporter.ExportAsNormal(m.GetTexture("_BumpMap"));
|
||||
if (index != -1)
|
||||
{
|
||||
material.normalTexture = new glTFMaterialNormalTextureInfo()
|
||||
|
|
@ -149,7 +149,7 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
static void Export_Emission(Material m, TextureExporter textureManager, glTFMaterial material)
|
||||
static void Export_Emission(Material m, ITextureExporter textureExporter, glTFMaterial material)
|
||||
{
|
||||
if (m.IsKeywordEnabled("_EMISSION") == false)
|
||||
return;
|
||||
|
|
@ -166,7 +166,7 @@ namespace UniGLTF
|
|||
|
||||
if (m.HasProperty("_EmissionMap"))
|
||||
{
|
||||
var index = textureManager.ExportSRGB(m.GetTexture("_EmissionMap"));
|
||||
var index = textureExporter.ExportAsSRgb(m.GetTexture("_EmissionMap"));
|
||||
if (index != -1)
|
||||
{
|
||||
material.emissiveTexture = new glTFMaterialEmissiveTextureInfo()
|
||||
|
|
|
|||
|
|
@ -43,7 +43,11 @@ namespace UniGLTF
|
|||
private set;
|
||||
}
|
||||
|
||||
public TextureExporter TextureManager;
|
||||
public TextureExporter TextureExporter
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
protected virtual IMaterialExporter CreateMaterialExporter()
|
||||
{
|
||||
|
|
@ -238,10 +242,10 @@ namespace UniGLTF
|
|||
#region Materials and Textures
|
||||
Materials = uniqueUnityMeshes.SelectMany(x => x.Renderer.sharedMaterials).Where(x => x != null).Distinct().ToList();
|
||||
|
||||
TextureManager = new TextureExporter(textureSerializer);
|
||||
TextureExporter = new TextureExporter(textureSerializer);
|
||||
|
||||
var materialExporter = CreateMaterialExporter();
|
||||
glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();
|
||||
glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter)).ToList();
|
||||
#endregion
|
||||
|
||||
#region Meshes
|
||||
|
|
@ -360,9 +364,9 @@ namespace UniGLTF
|
|||
ExportExtensions(textureSerializer);
|
||||
|
||||
// Extension で Texture が増える場合があるので最後に呼ぶ
|
||||
for (int i = 0; i < TextureManager.Exported.Count; ++i)
|
||||
for (int i = 0; i < TextureExporter.Exported.Count; ++i)
|
||||
{
|
||||
var (unityTexture, colorSpace) = TextureManager.Exported[i];
|
||||
var (unityTexture, colorSpace) = TextureExporter.Exported[i];
|
||||
glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, textureSerializer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace UniGLTF
|
|||
filterMode = FilterMode.Bilinear,
|
||||
};
|
||||
|
||||
var textureManager = new TextureExporter(new EditorTextureSerializer());
|
||||
var textureExporter = new TextureExporter(new EditorTextureSerializer());
|
||||
var srcMaterial = new Material(Shader.Find("Standard"));
|
||||
|
||||
var offset = new Vector2(0.3f, 0.2f);
|
||||
|
|
@ -29,7 +29,7 @@ namespace UniGLTF
|
|||
srcMaterial.mainTextureScale = scale;
|
||||
|
||||
var materialExporter = new MaterialExporter();
|
||||
var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureManager);
|
||||
var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureExporter);
|
||||
gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions = gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions.Deserialize();
|
||||
|
||||
Assert.IsTrue(glTF_KHR_texture_transform.TryGet(gltfMaterial.pbrMetallicRoughness.baseColorTexture, out glTF_KHR_texture_transform t));
|
||||
|
|
@ -242,8 +242,8 @@ namespace UniGLTF
|
|||
material.SetColor("_EmissionColor", new Color(0, 1, 2, 1));
|
||||
material.EnableKeyword("_EMISSION");
|
||||
var materialExporter = new MaterialExporter();
|
||||
var textureExportManager = new TextureExporter(new EditorTextureSerializer());
|
||||
var gltfMaterial = materialExporter.ExportMaterial(material, textureExportManager);
|
||||
var textureExporter = new TextureExporter(new EditorTextureSerializer());
|
||||
var gltfMaterial = materialExporter.ExportMaterial(material, textureExporter);
|
||||
|
||||
Assert.AreEqual(gltfMaterial.emissiveFactor, new float[] { 0, 0.5f, 1 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,15 +18,15 @@ namespace UniGLTF
|
|||
wrapMode = TextureWrapMode.Clamp,
|
||||
filterMode = FilterMode.Trilinear,
|
||||
};
|
||||
var textureManager = new TextureExporter(new EditorTextureSerializer());
|
||||
var textureExporter = new TextureExporter(new EditorTextureSerializer());
|
||||
|
||||
var material = new Material(Shader.Find("Standard"));
|
||||
material.mainTexture = tex0;
|
||||
|
||||
var materialExporter = new MaterialExporter();
|
||||
materialExporter.ExportMaterial(material, textureManager);
|
||||
materialExporter.ExportMaterial(material, textureExporter);
|
||||
|
||||
var (convTex0, colorSpace) = textureManager.Exported[0];
|
||||
var (convTex0, colorSpace) = textureExporter.Exported[0];
|
||||
var sampler = TextureSamplerUtil.Export(convTex0);
|
||||
|
||||
Assert.AreEqual(glWrap.CLAMP_TO_EDGE, sampler.wrapS);
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ namespace VRM.Samples
|
|||
{
|
||||
var material = Resources.Load<Material>(resourceName);
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var textureManager = new TextureExporter(new EditorTextureSerializer());
|
||||
var exported = exporter.ExportMaterial(material, textureManager);
|
||||
var textureExporter = new TextureExporter(new EditorTextureSerializer());
|
||||
var exported = exporter.ExportMaterial(material, textureExporter);
|
||||
|
||||
// parse glTFExtensionExport to glTFExtensionImport
|
||||
exported.extensions = exported.extensions.Deserialize();
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ namespace VRM
|
|||
VRM.meta.title = meta.Title;
|
||||
if (meta.Thumbnail != null)
|
||||
{
|
||||
VRM.meta.texture = TextureManager.ExportSRGB(meta.Thumbnail);
|
||||
VRM.meta.texture = TextureExporter.ExportAsSRgb(meta.Thumbnail);
|
||||
}
|
||||
|
||||
// ussage permission
|
||||
|
|
@ -199,7 +199,7 @@ namespace VRM
|
|||
// materials
|
||||
foreach (var m in Materials)
|
||||
{
|
||||
VRM.materialProperties.Add(VRMMaterialExporter.CreateFromMaterial(m, TextureManager));
|
||||
VRM.materialProperties.Add(VRMMaterialExporter.CreateFromMaterial(m, TextureExporter));
|
||||
}
|
||||
|
||||
// Serialize VRM
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ namespace VRM
|
|||
// "Queue",
|
||||
};
|
||||
|
||||
public static glTF_VRM_Material CreateFromMaterial(Material m, TextureExporter textureExporter)
|
||||
public static glTF_VRM_Material CreateFromMaterial(Material m, ITextureExporter textureExporter)
|
||||
{
|
||||
var material = new glTF_VRM_Material
|
||||
{
|
||||
|
|
@ -181,8 +181,8 @@ namespace VRM
|
|||
if (texture != null)
|
||||
{
|
||||
var value = kv.Key == "_BumpMap"
|
||||
? textureExporter.ExportNormal(texture)
|
||||
: textureExporter.ExportSRGB(texture)
|
||||
? textureExporter.ExportAsNormal(texture)
|
||||
: textureExporter.ExportAsSRgb(texture)
|
||||
;
|
||||
if (value == -1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace VRM
|
|||
filterMode = FilterMode.Bilinear,
|
||||
};
|
||||
|
||||
var textureManager = new TextureExporter(new EditorTextureSerializer());
|
||||
var textureExporter = new TextureExporter(new EditorTextureSerializer());
|
||||
var srcMaterial = new Material(Shader.Find("VRM/MToon"));
|
||||
|
||||
var offset = new Vector2(0.3f, 0.2f);
|
||||
|
|
@ -29,7 +29,7 @@ namespace VRM
|
|||
srcMaterial.mainTextureScale = scale;
|
||||
|
||||
var materialExporter = new VRMMaterialExporter();
|
||||
var vrmMaterial = VRMMaterialExporter.CreateFromMaterial(srcMaterial, textureManager);
|
||||
var vrmMaterial = VRMMaterialExporter.CreateFromMaterial(srcMaterial, textureExporter);
|
||||
Assert.AreEqual(vrmMaterial.vectorProperties["_MainTex"], new float[] { 0.3f, 0.2f, 0.5f, 0.6f });
|
||||
|
||||
var materialImporter = new VRMMaterialImporter(new glTF_VRM_extensions
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace UniVRM10
|
|||
{
|
||||
public static class Vrm10MToonMaterialExporter
|
||||
{
|
||||
public static bool TryExportMaterialAsMToon(Material src, TextureExporter textureExporter, out glTFMaterial dst)
|
||||
public static bool TryExportMaterialAsMToon(Material src, ITextureExporter textureExporter, out glTFMaterial dst)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -41,13 +41,13 @@ namespace UniVRM10
|
|||
baseColorFactor = def.Color.LitColor.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear),
|
||||
baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = textureExporter.ExportSRGB(def.Color.LitMultiplyTexture),
|
||||
index = textureExporter.ExportAsSRgb(def.Color.LitMultiplyTexture),
|
||||
},
|
||||
},
|
||||
|
||||
normalTexture = new glTFMaterialNormalTextureInfo
|
||||
{
|
||||
index = textureExporter.ExportNormal(def.Lighting.Normal.NormalTexture),
|
||||
index = textureExporter.ExportAsNormal(def.Lighting.Normal.NormalTexture),
|
||||
scale = def.Lighting.Normal.NormalScaleValue,
|
||||
},
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ namespace UniVRM10
|
|||
emissiveFactor = def.Emission.EmissionColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
|
||||
emissiveTexture = new glTFMaterialEmissiveTextureInfo
|
||||
{
|
||||
index = textureExporter.ExportSRGB(def.Emission.EmissionMultiplyTexture),
|
||||
index = textureExporter.ExportAsSRgb(def.Emission.EmissionMultiplyTexture),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ namespace UniVRM10
|
|||
ShadeColorFactor = def.Color.ShadeColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear),
|
||||
ShadeMultiplyTexture = new TextureInfo
|
||||
{
|
||||
Index = textureExporter.ExportSRGB(def.Color.ShadeMultiplyTexture),
|
||||
Index = textureExporter.ExportAsSRgb(def.Color.ShadeMultiplyTexture),
|
||||
},
|
||||
ShadingToonyFactor = def.Lighting.LitAndShadeMixing.ShadingToonyValue,
|
||||
ShadingShiftFactor = def.Lighting.LitAndShadeMixing.ShadingShiftValue,
|
||||
|
|
@ -87,14 +87,14 @@ namespace UniVRM10
|
|||
// Rim Lighting
|
||||
MatcapTexture = new TextureInfo
|
||||
{
|
||||
Index = textureExporter.ExportSRGB(def.MatCap.AdditiveTexture),
|
||||
Index = textureExporter.ExportAsSRgb(def.MatCap.AdditiveTexture),
|
||||
},
|
||||
ParametricRimColorFactor = def.Rim.RimColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
|
||||
ParametricRimFresnelPowerFactor = def.Rim.RimFresnelPowerValue,
|
||||
ParametricRimLiftFactor = def.Rim.RimLiftValue,
|
||||
RimMultiplyTexture = new TextureInfo
|
||||
{
|
||||
Index = textureExporter.ExportSRGB(def.Rim.RimMultiplyTexture),
|
||||
Index = textureExporter.ExportAsSRgb(def.Rim.RimMultiplyTexture),
|
||||
},
|
||||
RimLightingMixFactor = def.Rim.RimLightingMixValue,
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ namespace UniVRM10
|
|||
OutlineWidthFactor = def.Outline.OutlineWidthValue * centimeterToMeter,
|
||||
OutlineWidthMultiplyTexture = new TextureInfo
|
||||
{
|
||||
Index = textureExporter.ExportLinear(def.Outline.OutlineWidthMultiplyTexture),
|
||||
Index = textureExporter.ExportAsLinear(def.Outline.OutlineWidthMultiplyTexture),
|
||||
},
|
||||
OutlineColorFactor = def.Outline.OutlineColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear),
|
||||
OutlineLightingMixFactor = ExportOutlineLightingMixFactor(def.Outline.OutlineColorMode, def.Outline.OutlineLightingMixValue),
|
||||
|
|
@ -111,7 +111,7 @@ namespace UniVRM10
|
|||
// UV Anim
|
||||
UvAnimationMaskTexture = new TextureInfo
|
||||
{
|
||||
Index = textureExporter.ExportLinear(def.TextureOption.UvAnimationMaskTexture),
|
||||
Index = textureExporter.ExportAsLinear(def.TextureOption.UvAnimationMaskTexture),
|
||||
},
|
||||
UvAnimationScrollXSpeedFactor = def.TextureOption.UvAnimationScrollXSpeedValue,
|
||||
UvAnimationScrollYSpeedFactor = def.TextureOption.UvAnimationScrollYSpeedValue * invertY,
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ namespace UniVRM10
|
|||
int? thumbnailTextureIndex = default;
|
||||
if (meta.Thumbnail != null)
|
||||
{
|
||||
thumbnailTextureIndex = m_textureExporter.ExportSRGB(meta.Thumbnail);
|
||||
thumbnailTextureIndex = m_textureExporter.ExportAsSRgb(meta.Thumbnail);
|
||||
}
|
||||
return thumbnailTextureIndex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace UniVRM10
|
|||
{
|
||||
public class Vrm10MaterialExporter : MaterialExporter
|
||||
{
|
||||
public override glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
|
||||
public override glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter)
|
||||
{
|
||||
if (Vrm10MToonMaterialExporter.TryExportMaterialAsMToon(m, textureExporter, out var dst))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace VRMShaders
|
|||
|
||||
public (byte[] bytes, string mime) ExportBytesWithMime(Texture2D texture, ColorSpace textureColorSpace)
|
||||
{
|
||||
if (TryGetBytesWithMime(texture, out byte[] bytes, out string mime))
|
||||
if (CanExportAsEditorAssetFile(texture) && TryGetBytesWithMime(texture, out byte[] bytes, out string mime))
|
||||
{
|
||||
return (bytes, mime);
|
||||
}
|
||||
|
|
|
|||
38
Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs
Normal file
38
Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Texture を用途別に変換の要不要を判断して gltf.textures の index に対応させる機能。
|
||||
///
|
||||
/// glTF 拡張で Texture の用途を増やす必要がある場合は、この interface を継承して実装すればよい。
|
||||
/// </summary>
|
||||
public interface ITextureExporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Export する Texture2D のリスト。これが gltf.textures になる
|
||||
/// </summary>
|
||||
IReadOnlyList<(Texture2D, UniGLTF.ColorSpace)> Exported { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 指定の Texture を、 sRGB 色空間の値を持つ Texture に出力するように指示する。
|
||||
/// </summary>
|
||||
int ExportAsSRgb(Texture src);
|
||||
|
||||
/// <summary>
|
||||
/// 指定の Texture を、 Linear の値を持つ Texture に出力するように指示する。
|
||||
/// </summary>
|
||||
int ExportAsLinear(Texture src);
|
||||
|
||||
/// <summary>
|
||||
/// 指定の Metallic, Roughness, Occlusion 情報を、 glTF 仕様に準拠した 1 枚の合成テクスチャとして出力するように指示する。
|
||||
/// </summary>
|
||||
int ExportAsGltfMetallicSmoothnessOcclusionCombined(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture);
|
||||
|
||||
/// <summary>
|
||||
/// 指定の Texture を、glTF 仕様に準拠した Normal Texture に出力するように指示する。
|
||||
/// </summary>
|
||||
int ExportAsNormal(Texture src);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4e22c9906e3e42038724e1bcf46450bf
|
||||
timeCreated: 1621507967
|
||||
|
|
@ -2,17 +2,20 @@
|
|||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Texture2D を入力として byte[] を得る機能
|
||||
/// </summary>
|
||||
public interface ITextureSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Texture をファイルのバイト列そのまま出力してよいかどうか判断するデリゲート。
|
||||
/// Texture をファイルのバイト列そのまま出力してよいかどうか判断する。
|
||||
///
|
||||
/// Runtime 出力では常に false が望ましい。
|
||||
/// </summary>
|
||||
bool CanExportAsEditorAssetFile(Texture texture);
|
||||
|
||||
/// <summary>
|
||||
/// Texture2D から実際のバイト列を取得するデリゲート。
|
||||
/// Texture2D から実際のバイト列を取得する。
|
||||
///
|
||||
/// textureColorSpace はその Texture2D がアサインされる glTF プロパティの仕様が定める色空間を指定する。
|
||||
/// 具体的には Texture2D をコピーする際に、コピー先の Texture2D の色空間を決定するために使用する。
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
|
||||
namespace VRMShaders
|
||||
|
|
@ -35,14 +36,14 @@ namespace VRMShaders
|
|||
// ConvertToNormalValueFromRawColorWhenCompressionIsRequired
|
||||
public static Texture2D Import(Texture2D texture)
|
||||
{
|
||||
return TextureConverter.Convert(texture, TextureImportTypes.NormalMap, null, Encoder);
|
||||
return TextureConverter.Convert(texture, ColorSpace.Linear, null, Encoder);
|
||||
}
|
||||
|
||||
// Unity texture to GLTF data
|
||||
// ConvertToRawColorWhenNormalValueIsCompressed
|
||||
public static Texture2D Export(Texture texture)
|
||||
{
|
||||
return TextureConverter.Convert(texture, TextureImportTypes.NormalMap, null, Decoder);
|
||||
return TextureConverter.Convert(texture, ColorSpace.Linear, null, Decoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,25 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using ColorSpace = UniGLTF.ColorSpace;
|
||||
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// * https://github.com/vrm-c/UniVRM/issues/781
|
||||
///
|
||||
///
|
||||
/// * https://github.com/vrm-c/UniVRM/issues/781
|
||||
///
|
||||
/// Unity = glTF
|
||||
/// Occlusion: unity.g = glTF.r
|
||||
/// Roughness: unity.a = 1 - glTF.g * roughnessFactor
|
||||
/// Metallic : unity.r = glTF.b * metallicFactor
|
||||
///
|
||||
///
|
||||
/// glTF = Unity
|
||||
/// Occlusion: glTF.r = unity.g
|
||||
/// Roughness: glTF.g = 1 - unity.a * smoothness
|
||||
/// Metallic : glTF.b = unity.r
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public static class OcclusionMetallicRoughnessConverter
|
||||
{
|
||||
|
|
@ -29,7 +30,7 @@ namespace VRMShaders
|
|||
{
|
||||
if (metallicRoughnessTexture == occlusionTexture)
|
||||
{
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
|
||||
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
|
||||
for (int i = 0; i < metallicRoughnessPixels.Length; ++i)
|
||||
{
|
||||
|
|
@ -42,9 +43,9 @@ namespace VRMShaders
|
|||
}
|
||||
else
|
||||
{
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
|
||||
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
|
||||
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
|
||||
var occlusionPixels = copyOcclusion.GetPixels32();
|
||||
if (metallicRoughnessPixels.Length != occlusionPixels.Length)
|
||||
{
|
||||
|
|
@ -62,7 +63,7 @@ namespace VRMShaders
|
|||
}
|
||||
else if (metallicRoughnessTexture != null)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null);
|
||||
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(x, metallicFactor, roughnessFactor, default)).ToArray());
|
||||
copyTexture.Apply();
|
||||
copyTexture.name = metallicRoughnessTexture.name;
|
||||
|
|
@ -70,7 +71,7 @@ namespace VRMShaders
|
|||
}
|
||||
else if (occlusionTexture != null)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
|
||||
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(default, metallicFactor, roughnessFactor, x)).ToArray());
|
||||
copyTexture.Apply();
|
||||
copyTexture.name = occlusionTexture.name;
|
||||
|
|
@ -88,7 +89,7 @@ namespace VRMShaders
|
|||
{
|
||||
r = (byte)(metallicRoughness.b * metallicFactor), // Metallic
|
||||
g = occlusion.r, // Occlusion
|
||||
b = 0, // not used
|
||||
b = 0, // not used
|
||||
a = (byte)(255 - metallicRoughness.g * roughnessFactor), // Roughness to Smoothness
|
||||
};
|
||||
|
||||
|
|
@ -101,7 +102,7 @@ namespace VRMShaders
|
|||
{
|
||||
if (metallicSmoothTexture == occlusionTexture)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null);
|
||||
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;
|
||||
|
|
@ -109,9 +110,9 @@ namespace VRMShaders
|
|||
}
|
||||
else
|
||||
{
|
||||
var copyMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null);
|
||||
var metallicSmoothPixels = copyMetallicSmooth.GetPixels32();
|
||||
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null);
|
||||
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null);
|
||||
var occlusionPixels = copyOcclusion.GetPixels32();
|
||||
if (metallicSmoothPixels.Length != occlusionPixels.Length)
|
||||
{
|
||||
|
|
@ -129,7 +130,7 @@ namespace VRMShaders
|
|||
}
|
||||
else if (metallicSmoothTexture)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null);
|
||||
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;
|
||||
|
|
@ -137,7 +138,7 @@ namespace VRMShaders
|
|||
}
|
||||
else if (occlusionTexture)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null);
|
||||
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;
|
||||
|
|
@ -153,7 +154,7 @@ namespace VRMShaders
|
|||
{
|
||||
var dst = new Color32
|
||||
{
|
||||
r = occlusion.g, // Occlusion
|
||||
r = occlusion.g, // Occlusion
|
||||
g = (byte)(255 - metallicSmooth.a * smoothness), // Roughness from Smoothness
|
||||
b = metallicSmooth.r, // Metallic
|
||||
a = 255, // not used
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ namespace VRMShaders
|
|||
{
|
||||
public delegate Color32 ColorConversion(Color32 color);
|
||||
|
||||
public static Texture2D Convert(Texture texture, TextureImportTypes textureType, ColorConversion colorConversion, Material convertMaterial)
|
||||
public static Texture2D Convert(Texture texture, ColorSpace dstColorSpace, ColorConversion colorConversion, Material convertMaterial)
|
||||
{
|
||||
var copyTexture = CopyTexture(texture, textureType, convertMaterial);
|
||||
var copyTexture = CopyTexture(texture, dstColorSpace, convertMaterial);
|
||||
if (colorConversion != null)
|
||||
{
|
||||
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
|
||||
|
|
@ -22,16 +22,11 @@ namespace VRMShaders
|
|||
return copyTexture;
|
||||
}
|
||||
|
||||
public static Texture2D CopyTexture(Texture src, TextureImportTypes textureType, Material material)
|
||||
{
|
||||
return CopyTexture(src, textureType.GetColorSpace(), material);
|
||||
}
|
||||
|
||||
public static Texture2D CopyTexture(Texture src, ColorSpace colorSpace, Material material)
|
||||
public static Texture2D CopyTexture(Texture src, ColorSpace dstColorSpace, Material material)
|
||||
{
|
||||
Texture2D dst = null;
|
||||
RenderTextureReadWrite readWrite;
|
||||
switch (colorSpace)
|
||||
switch (dstColorSpace)
|
||||
{
|
||||
case ColorSpace.sRGB:
|
||||
readWrite = RenderTextureReadWrite.sRGB;
|
||||
|
|
@ -40,7 +35,7 @@ namespace VRMShaders
|
|||
readWrite = RenderTextureReadWrite.Linear;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null);
|
||||
throw new ArgumentOutOfRangeException(nameof(dstColorSpace), dstColorSpace, null);
|
||||
}
|
||||
|
||||
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, readWrite);
|
||||
|
|
@ -78,4 +73,4 @@ namespace VRMShaders
|
|||
return dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,13 @@ namespace VRMShaders
|
|||
/// glTF にエクスポートする Texture2D を蓄えて index を確定させる。
|
||||
/// Exporter の最後でまとめて Texture2D から bytes 列を得て出力する。
|
||||
/// </summary>
|
||||
public class TextureExporter : IDisposable
|
||||
public sealed class TextureExporter : IDisposable, ITextureExporter
|
||||
{
|
||||
private ITextureSerializer m_textureSerializer;
|
||||
private readonly ITextureSerializer m_textureSerializer;
|
||||
private readonly Dictionary<ExportKey, int> m_exportMap = new Dictionary<ExportKey, int>();
|
||||
private readonly List<(Texture2D, ColorSpace)> m_exported = new List<(Texture2D, ColorSpace)>();
|
||||
|
||||
public IReadOnlyList<(Texture2D, ColorSpace)> Exported => m_exported;
|
||||
|
||||
public TextureExporter(ITextureSerializer textureSerializer)
|
||||
{
|
||||
|
|
@ -25,22 +29,24 @@ namespace VRMShaders
|
|||
// TODO: export 用にコピー・変換したテクスチャーをここで解放したい
|
||||
}
|
||||
|
||||
public enum ConvertTypes
|
||||
enum ExportTypes
|
||||
{
|
||||
// 無変換
|
||||
None,
|
||||
// sRGB テクスチャとして出力
|
||||
Srgb,
|
||||
// Linear テクスチャとして出力
|
||||
Linear,
|
||||
// Unity Standard様式 から glTF PBR様式への変換
|
||||
OcclusionMetallicRoughness,
|
||||
// Assetを使うときはそのバイト列を無変換で、それ以外は DXT5nm 形式からのデコードを行う
|
||||
Normal,
|
||||
}
|
||||
|
||||
struct ExportKey
|
||||
readonly struct ExportKey
|
||||
{
|
||||
public readonly Texture Src;
|
||||
public readonly ConvertTypes TextureType;
|
||||
public readonly ExportTypes TextureType;
|
||||
|
||||
public ExportKey(Texture src, ConvertTypes type)
|
||||
public ExportKey(Texture src, ExportTypes type)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
|
|
@ -50,36 +56,13 @@ namespace VRMShaders
|
|||
TextureType = type;
|
||||
}
|
||||
}
|
||||
Dictionary<ExportKey, int> m_exportMap = new Dictionary<ExportKey, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Export する Texture2D のリスト。これが gltf.textures になる
|
||||
/// </summary>
|
||||
/// <typeparam name="Texture2D"></typeparam>
|
||||
/// <returns></returns>
|
||||
public readonly List<(Texture2D, ColorSpace)> Exported = new List<(Texture2D, ColorSpace)>();
|
||||
|
||||
/// <summary>
|
||||
/// Texture の export index を得る
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="textureType"></param>
|
||||
/// <returns></returns>
|
||||
public int GetTextureIndex(Texture src, ConvertTypes textureType)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return m_exportMap[new ExportKey(src, textureType)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sRGBなテクスチャーを処理し、index を確定させる
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <returns></returns>
|
||||
public int ExportSRGB(Texture src)
|
||||
public int ExportAsSRgb(Texture src)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
|
|
@ -87,13 +70,13 @@ namespace VRMShaders
|
|||
}
|
||||
|
||||
// cache
|
||||
if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.None), out var index))
|
||||
if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Srgb), out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
// get Texture2D
|
||||
index = Exported.Count;
|
||||
index = m_exported.Count;
|
||||
var texture2D = src as Texture2D;
|
||||
if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D))
|
||||
{
|
||||
|
|
@ -101,10 +84,10 @@ namespace VRMShaders
|
|||
}
|
||||
else
|
||||
{
|
||||
texture2D = TextureConverter.CopyTexture(src, TextureImportTypes.sRGB, null);
|
||||
texture2D = TextureConverter.CopyTexture(src, ColorSpace.sRGB, null);
|
||||
}
|
||||
Exported.Add((texture2D, ColorSpace.sRGB));
|
||||
m_exportMap.Add(new ExportKey(src, ConvertTypes.None), index);
|
||||
m_exported.Add((texture2D, ColorSpace.sRGB));
|
||||
m_exportMap.Add(new ExportKey(src, ExportTypes.Srgb), index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
|
@ -114,14 +97,14 @@ namespace VRMShaders
|
|||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <returns></returns>
|
||||
public int ExportLinear(Texture src)
|
||||
public int ExportAsLinear(Texture src)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var exportKey = new ExportKey(src, ConvertTypes.None);
|
||||
var exportKey = new ExportKey(src, ExportTypes.Linear);
|
||||
|
||||
// search cache
|
||||
if (m_exportMap.TryGetValue(exportKey, out var index))
|
||||
|
|
@ -129,7 +112,7 @@ namespace VRMShaders
|
|||
return index;
|
||||
}
|
||||
|
||||
index = Exported.Count;
|
||||
index = m_exported.Count;
|
||||
var texture2d = src as Texture2D;
|
||||
if (m_textureSerializer.CanExportAsEditorAssetFile(texture2d))
|
||||
{
|
||||
|
|
@ -137,9 +120,9 @@ namespace VRMShaders
|
|||
}
|
||||
else
|
||||
{
|
||||
texture2d = TextureConverter.CopyTexture(src, TextureImportTypes.Linear, null);
|
||||
texture2d = TextureConverter.CopyTexture(src, ColorSpace.Linear, null);
|
||||
}
|
||||
Exported.Add((texture2d, ColorSpace.Linear));
|
||||
m_exported.Add((texture2d, ColorSpace.Linear));
|
||||
m_exportMap.Add(exportKey, index);
|
||||
|
||||
return index;
|
||||
|
|
@ -152,7 +135,7 @@ namespace VRMShaders
|
|||
/// <param name="smoothness"></param>
|
||||
/// <param name="occlusionTexture"></param>
|
||||
/// <returns></returns>
|
||||
public int ExportMetallicSmoothnessOcclusion(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture)
|
||||
public int ExportAsGltfMetallicSmoothnessOcclusionCombined(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture)
|
||||
{
|
||||
if (metallicSmoothTexture == null && occlusionTexture == null)
|
||||
{
|
||||
|
|
@ -160,11 +143,12 @@ namespace VRMShaders
|
|||
}
|
||||
|
||||
// cache
|
||||
if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), out var index))
|
||||
// TODO 厳密なチェックをしていない
|
||||
if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, ExportTypes.OcclusionMetallicRoughness), out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, ConvertTypes.OcclusionMetallicRoughness), out index))
|
||||
if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), out index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
|
@ -172,17 +156,17 @@ namespace VRMShaders
|
|||
//
|
||||
// Unity と glTF で互換性が無いので必ず変換が必用
|
||||
//
|
||||
index = Exported.Count;
|
||||
index = m_exported.Count;
|
||||
var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture);
|
||||
|
||||
Exported.Add((texture2D, ColorSpace.Linear));
|
||||
m_exported.Add((texture2D, ColorSpace.Linear));
|
||||
if (metallicSmoothTexture != null)
|
||||
{
|
||||
m_exportMap.Add(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), index);
|
||||
m_exportMap.Add(new ExportKey(metallicSmoothTexture, ExportTypes.OcclusionMetallicRoughness), index);
|
||||
}
|
||||
if (occlusionTexture != null && occlusionTexture != metallicSmoothTexture)
|
||||
{
|
||||
m_exportMap.Add(new ExportKey(occlusionTexture, ConvertTypes.OcclusionMetallicRoughness), index);
|
||||
m_exportMap.Add(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), index);
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
@ -193,7 +177,7 @@ namespace VRMShaders
|
|||
/// </summary>
|
||||
/// <param name="normalTexture"></param>
|
||||
/// <returns></returns>
|
||||
public int ExportNormal(Texture src)
|
||||
public int ExportAsNormal(Texture src)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
|
|
@ -201,13 +185,13 @@ namespace VRMShaders
|
|||
}
|
||||
|
||||
// cache
|
||||
if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.Normal), out var index))
|
||||
if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Normal), out var index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
// get Texture2D
|
||||
index = Exported.Count;
|
||||
index = m_exported.Count;
|
||||
var texture2D = src as Texture2D;
|
||||
if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D))
|
||||
{
|
||||
|
|
@ -219,8 +203,8 @@ namespace VRMShaders
|
|||
texture2D = NormalConverter.Export(src);
|
||||
}
|
||||
|
||||
Exported.Add((texture2D, ColorSpace.Linear));
|
||||
m_exportMap.Add(new ExportKey(src, ConvertTypes.Normal), index);
|
||||
m_exported.Add((texture2D, ColorSpace.Linear));
|
||||
m_exportMap.Add(new ExportKey(src, ExportTypes.Normal), index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,22 +29,4 @@ namespace VRMShaders
|
|||
// TextureImporter.sRGBTexture = false;
|
||||
Linear,
|
||||
}
|
||||
|
||||
public static class TextureImportTypesExtensions
|
||||
{
|
||||
public static ColorSpace GetColorSpace(this TextureImportTypes textureType)
|
||||
{
|
||||
switch (textureType)
|
||||
{
|
||||
case TextureImportTypes.sRGB:
|
||||
return ColorSpace.sRGB;
|
||||
case TextureImportTypes.Linear:
|
||||
case TextureImportTypes.StandardMap:
|
||||
case TextureImportTypes.NormalMap:
|
||||
return ColorSpace.Linear;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,18 +99,18 @@ namespace VRMShaders
|
|||
|
||||
{
|
||||
var exporter = new TextureExporter(new EditorTextureSerializer());
|
||||
Assert.AreEqual(-1, exporter.ExportMetallicSmoothnessOcclusion(null, 0, null));
|
||||
Assert.AreEqual(-1, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, null));
|
||||
}
|
||||
{
|
||||
var exporter = new TextureExporter(new EditorTextureSerializer());
|
||||
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion));
|
||||
Assert.AreEqual(1, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null));
|
||||
Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, occlusion));
|
||||
Assert.AreEqual(1, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, null));
|
||||
}
|
||||
{
|
||||
var exporter = new TextureExporter(new EditorTextureSerializer());
|
||||
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, occlusion));
|
||||
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion));
|
||||
Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null));
|
||||
Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, occlusion));
|
||||
Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, occlusion));
|
||||
Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user