Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VRM1.0 MToon の Texture をすべて Import できる #934

Merged
merged 9 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 1 addition & 27 deletions Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,8 @@

namespace UniGLTF
{
public enum glTFTextureTypes
{
OcclusionMetallicRoughness,
Normal,
SRGB,
Linear,
}

public interface IglTFTextureinfo
{
glTFTextureTypes TextureType { get; }
}

[Serializable]
public abstract class glTFTextureInfo : IglTFTextureinfo
public abstract class glTFTextureInfo
{
[JsonSchema(Required = true, Minimum = 0)]
public int index = -1;
Expand All @@ -28,47 +15,34 @@ public abstract class glTFTextureInfo : IglTFTextureinfo
// empty schemas
public glTFExtension extensions;
public glTFExtension extras;

public abstract glTFTextureTypes TextureType { get; }
}


[Serializable]
public class glTFMaterialBaseColorTextureInfo : glTFTextureInfo
{
public override glTFTextureTypes TextureType => glTFTextureTypes.SRGB;
}

[Serializable]
public class glTFMaterialMetallicRoughnessTextureInfo : glTFTextureInfo
{
public override glTFTextureTypes TextureType => glTFTextureTypes.OcclusionMetallicRoughness;
}

[Serializable]
public class glTFMaterialNormalTextureInfo : glTFTextureInfo
{
public float scale = 1.0f;

public override glTFTextureTypes TextureType
{
get { return glTFTextureTypes.Normal; }
}
}

[Serializable]
public class glTFMaterialOcclusionTextureInfo : glTFTextureInfo
{
[JsonSchema(Minimum = 0.0, Maximum = 1.0)]
public float strength = 1.0f;

public override glTFTextureTypes TextureType => glTFTextureTypes.OcclusionMetallicRoughness;
}

[Serializable]
public class glTFMaterialEmissiveTextureInfo : glTFTextureInfo
{
public override glTFTextureTypes TextureType => glTFTextureTypes.SRGB;
}

[Serializable]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,35 @@ public MaterialImportParam GetMaterialParam(GltfParser parser, int i)

public static (Vector2, Vector2) GetTextureOffsetAndScale(glTFTextureInfo textureInfo)
{
Vector2 offset = new Vector2(0, 0);
Vector2 scale = new Vector2(1, 1);
if (glTF_KHR_texture_transform.TryGet(textureInfo, out glTF_KHR_texture_transform textureTransform))
if (glTF_KHR_texture_transform.TryGet(textureInfo, out var textureTransform))
{
return GetTextureOffsetAndScale(textureTransform);
}
return (new Vector2(0, 0), new Vector2(1, 1));
}

public static (Vector2, Vector2) GetTextureOffsetAndScale(glTF_KHR_texture_transform textureTransform)
{
var offset = new Vector2(0, 0);
var scale = new Vector2(1, 1);

if (textureTransform != null)
{
if (textureTransform.offset != null && textureTransform.offset.Length == 2)
{
offset = new Vector2(textureTransform.offset[0], textureTransform.offset[1]);
}

if (textureTransform.scale != null && textureTransform.scale.Length == 2)
{
scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]);
}

offset.y = (offset.y + scale.y - 1.0f) * -1.0f;

// Coordinate Conversion: GL (top-left origin) to DX (bottom-left origin)
// Formula: https://github.com/vrm-c/UniVRM/issues/930
offset.y = 1.0f - offset.y - scale.y;
}

return (offset, scale);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace UniGLTF
/// </summary>
public static class GltfTextureEnumerator
{
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesForMaterial(GltfParser parser, int i)
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterials(GltfParser parser, int i)
{
var m = parser.GLTF.materials[i];

Expand Down Expand Up @@ -82,17 +82,12 @@ public static class GltfTextureEnumerator
/// <returns></returns>
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
var used = new HashSet<SubAssetKey>();
Func<(SubAssetKey, TextureImportParam), bool> add = (kv) =>
{
var (key, textureInfo) = kv;
return used.Add(key);
};
var usedTextures = new HashSet<SubAssetKey>();
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
foreach (var kv in EnumerateTexturesForMaterial(parser, i))
foreach ((SubAssetKey key, TextureImportParam) kv in EnumerateTexturesReferencedByMaterials(parser, i))
{
if (add(kv))
if (usedTextures.Add(kv.key))
{
yield return kv;
}
Expand Down
12 changes: 12 additions & 0 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ public static (SubAssetKey, TextureImportParam Param) CreateSRGB(GltfParser pars
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default);
return (key, param);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glTF の Linear は、metallic_roughness_occlusion もしくは normal として扱うので無かった。

public static (SubAssetKey, TextureImportParam Param) CreateLinear(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
{
var gltfTexture = parser.GLTF.textures[textureIndex];
var gltfImage = parser.GLTF.images[gltfTexture.source];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.Linear, gltfTexture.name, gltfImage.uri);
var sampler = CreateSampler(parser.GLTF, textureIndex);
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(parser.GLTF.GetImageBytesFromTextureIndex(parser.Storage, textureIndex)));
var key = new SubAssetKey(typeof(Texture2D), name);
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.Linear, default, default, getTextureBytesAsync, default, default, default, default, default);
return (key, param);
}

public static (SubAssetKey, TextureImportParam Param) CreateNormal(GltfParser parser, int textureIndex, Vector2 offset, Vector2 scale)
{
Expand Down
2 changes: 1 addition & 1 deletion Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void TextureExtractTest()

// extractor
var extractor = new TextureExtractor(parser, UnityPath.FromUnityPath(""), loader.TextureFactory.Textures.Select(x => (new SubAssetKey(typeof(Texture2D), x.Texture.name), x.Texture)).ToArray());
var m = GltfTextureEnumerator.EnumerateTexturesForMaterial(parser, 0).FirstOrDefault(x => x.Item1.Name == "texture_1.standard");
var m = GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, 0).FirstOrDefault(x => x.Item1.Name == "texture_1.standard");

Assert.Catch<NotImplementedException>(() => extractor.Extract(m.Item1, m.Item2));
}
Expand Down
2 changes: 1 addition & 1 deletion Assets/VRM/Runtime/IO/VRMMaterialImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public MaterialImportParam GetMaterialParam(GltfParser parser, int i)
else
{
// PBR or Unlit
foreach (var (key, value) in GltfTextureEnumerator.EnumerateTexturesForMaterial(parser, i))
foreach (var (key, value) in GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, i))
{
if (used.Add(key))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public override void OnInspectorGUI()
case Tabs.Materials:
if (m_parser != null)
{
EditorMaterial.OnGUI(m_importer, m_parser, Vrm10MaterialImporter.EnumerateAllTexturesDistinct);
EditorMaterial.OnGUI(m_importer, m_parser, Vrm10TextureEnumerator.EnumerateAllTexturesDistinct);
}
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static void Import(ScriptedImporter scriptedImporter, AssetImportContext
using (var loader = new Vrm10Importer(parser, externalObjectMap))
{
// settings TextureImporters
foreach (var (key, textureInfo) in Vrm10MaterialImporter.EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in Vrm10TextureEnumerator.EnumerateAllTexturesDistinct(parser))
{
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
}
Expand Down
8 changes: 8 additions & 0 deletions Assets/VRM10/Runtime/IO/Material.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

153 changes: 153 additions & 0 deletions Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using System;
using UniGLTF;
using UniGLTF.Extensions.VRMC_materials_mtoon;
using UnityEngine;
using VRMShaders;

namespace UniVRM10
{
public static class Vrm10MToonMaterialImporter
{
public static bool TryGetBaseColorTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
{
try
{
pair = GltfPBRMaterial.BaseColorTexture(parser, src);
return true;
}
catch (NullReferenceException)
{
pair = default;
return false;
}
catch (ArgumentOutOfRangeException)
{
pair = default;
return false;
}
}

public static bool TryGetNormalTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
{
try
{
pair = GltfPBRMaterial.NormalTexture(parser, src);
return true;
}
catch (NullReferenceException)
{
pair = default;
return false;
}
catch (ArgumentOutOfRangeException)
{
pair = default;
return false;
}
}

public static bool TryGetShadeMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.ShadeMultiplyTexture), out pair);
}

public static bool TryGetShadingShiftTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.ShadingShiftTexture), out pair);
}

public static bool TryGetMatcapTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.ShadingShiftTexture), out pair);
}

public static bool TryGetRimMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.RimMultiplyTexture), out pair);
}

public static bool TryGetOutlineWidthMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.OutlineWidthMultiplyTexture), out pair);
}

public static bool TryGetUvAnimationMaskTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.UvAnimationMaskTexture), out pair);
}

private static bool TryGetSRGBTexture(GltfParser parser, Vrm10TextureInfo info, out (SubAssetKey, TextureImportParam) pair)
{
try
{
var (offset, scale) = GetTextureOffsetAndScale(info);
pair = GltfTextureImporter.CreateSRGB(parser, info.index, offset, scale);
return true;
}
catch (NullReferenceException)
{
pair = default;
return false;
}
catch (ArgumentOutOfRangeException)
{
pair = default;
return false;
}
}
private static bool TryGetLinearTexture(GltfParser parser, Vrm10TextureInfo info, out (SubAssetKey, TextureImportParam) pair)
{
try
{
var (offset, scale) = GetTextureOffsetAndScale(info);
pair = GltfTextureImporter.CreateLinear(parser, info.index, offset, scale);
return true;
}
catch (NullReferenceException)
{
pair = default;
return false;
}
catch (ArgumentOutOfRangeException)
{
pair = default;
return false;
}
}

private static (Vector2, Vector2) GetTextureOffsetAndScale(Vrm10TextureInfo textureInfo)
{
if (glTF_KHR_texture_transform.TryGet(textureInfo, out var textureTransform))
{
return GltfMaterialImporter.GetTextureOffsetAndScale(textureTransform);
}
return (new Vector2(0, 0), new Vector2(1, 1));
}

/// <summary>
/// MToon 定義内の TextureInfo を glTFTextureInfo として扱う入れ物
/// </summary>
private sealed class Vrm10TextureInfo : glTFTextureInfo
{
public Vrm10TextureInfo(TextureInfo info)
{
if (info == null) return;

index = info.Index ?? -1;
texCoord = info.TexCoord ?? -1;
extensions = info.Extensions as glTFExtension;
extras = info.Extras as glTFExtension;
}

public Vrm10TextureInfo(ShadingShiftTextureInfo info)
{
if (info == null) return;

index = info.Index ?? -1;
texCoord = info.TexCoord ?? -1;
extensions = info.Extensions as glTFExtension;
extras = info.Extras as glTFExtension;
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Assets/VRM10/Runtime/IO/Texture.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading