Merge pull request #1338 from notargs/readonly_struct_material_descriptor

MaterialDescriptorをreadonly structに変更
This commit is contained in:
ousttrue 2021-10-26 12:44:15 +09:00 committed by GitHub
commit a5e31b76f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 402 additions and 246 deletions

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using VRMShaders;
@ -12,19 +13,22 @@ namespace UniGLTF
{
public MaterialDescriptor Get(GltfData data, int i)
{
if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param))
{
if (!GltfPbrMaterialImporter.TryCreateParam(data, i, out param))
{
// fallback
if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param;
if (GltfPbrMaterialImporter.TryCreateParam(data, i, out param)) return param;
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialDescriptor(GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
}
}
return new MaterialDescriptor(
GetMaterialName(i, null),
GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Action<Material>[]{});
return param;
}
public static string GetMaterialName(int index, glTFMaterial src)

View File

@ -1,4 +1,6 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine;
using VRMShaders;
using ColorSpace = VRMShaders.ColorSpace;
@ -38,6 +40,10 @@ namespace UniGLTF
/// </summary>
public static class GltfPbrMaterialImporter
{
private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend");
private static readonly int DstBlend = Shader.PropertyToID("_DstBlend");
private static readonly int ZWrite = Shader.PropertyToID("_ZWrite");
private static readonly int Cutoff = Shader.PropertyToID("_Cutoff");
public const string ShaderName = "Standard";
private enum BlendMode
@ -57,7 +63,12 @@ namespace UniGLTF
}
var src = data.GLTF.materials[i];
matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), ShaderName);
var textureSlots = new Dictionary<string, TextureDescriptor>();
var floatValues = new Dictionary<string, float>();
var colors = new Dictionary<string, Color>();
var vectors = new Dictionary<string, Vector4>();
var actions = new List<Action<Material>>();
var standardTexDesc = default(TextureDescriptor);
if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)
@ -68,52 +79,55 @@ namespace UniGLTF
(key, standardTexDesc) = GltfPbrTextureImporter.StandardTexture(data, src);
}
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
if (src.pbrMetallicRoughness.baseColorFactor != null &&
src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
matDesc.Colors.Add("_Color",
colors.Add("_Color",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
);
}
if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
if (src.pbrMetallicRoughness.baseColorTexture != null &&
src.pbrMetallicRoughness.baseColorTexture.index != -1)
{
var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src);
matDesc.TextureSlots.Add("_MainTex", textureParam);
textureSlots.Add("_MainTex", textureParam);
}
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null &&
src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
{
matDesc.Actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP"));
matDesc.TextureSlots.Add("_MetallicGlossMap", standardTexDesc);
actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP"));
textureSlots.Add("_MetallicGlossMap", standardTexDesc);
// Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
matDesc.FloatValues.Add("_Metallic", 1.0f);
matDesc.FloatValues.Add("_GlossMapScale", 1.0f);
floatValues.Add("_Metallic", 1.0f);
floatValues.Add("_GlossMapScale", 1.0f);
}
else
{
matDesc.FloatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
matDesc.FloatValues.Add("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
floatValues.Add("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
}
}
if (src.normalTexture != null && src.normalTexture.index != -1)
{
matDesc.Actions.Add(material => material.EnableKeyword("_NORMALMAP"));
var (key, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src);
matDesc.TextureSlots.Add("_BumpMap", textureParam);
matDesc.FloatValues.Add("_BumpScale", src.normalTexture.scale);
actions.Add(material => material.EnableKeyword("_NORMALMAP"));
var (_, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src);
textureSlots.Add("_BumpMap", textureParam);
floatValues.Add("_BumpScale", src.normalTexture.scale);
}
if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
{
matDesc.TextureSlots.Add("_OcclusionMap", standardTexDesc);
matDesc.FloatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
textureSlots.Add("_OcclusionMap", standardTexDesc);
floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
}
if (src.emissiveFactor != null
|| (src.emissiveTexture != null && src.emissiveTexture.index != -1))
{
matDesc.Actions.Add(material =>
actions.Add(material =>
{
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
@ -123,32 +137,34 @@ namespace UniGLTF
{
var emissiveFactor = src.emissiveFactor.ToColor3(ColorSpace.Linear, ColorSpace.Linear);
if (UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.GltfDeserializer.TryGet(src.extensions,
out UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.VRMC_materials_hdr_emissiveMultiplier ex))
out UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.
VRMC_materials_hdr_emissiveMultiplier ex))
{
emissiveFactor *= ex.EmissiveMultiplier.Value;
}
matDesc.Colors.Add("_EmissionColor", emissiveFactor);
colors.Add("_EmissionColor", emissiveFactor);
}
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src);
matDesc.TextureSlots.Add("_EmissionMap", textureParam);
textureSlots.Add("_EmissionMap", textureParam);
}
}
matDesc.Actions.Add(material =>
actions.Add(material =>
{
BlendMode blendMode = BlendMode.Opaque;
BlendMode blendMode;
// https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
switch (src.alphaMode)
{
case "BLEND":
blendMode = BlendMode.Fade;
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt(ZWrite, 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -158,10 +174,10 @@ namespace UniGLTF
case "MASK":
blendMode = BlendMode.Cutout;
material.SetOverrideTag("RenderType", "TransparentCutout");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.SetFloat("_Cutoff", src.alphaCutoff);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt(ZWrite, 1);
material.SetFloat(Cutoff, src.alphaCutoff);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -172,9 +188,9 @@ namespace UniGLTF
default: // OPAQUE
blendMode = BlendMode.Opaque;
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt(ZWrite, 1);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -185,7 +201,17 @@ namespace UniGLTF
material.SetFloat("_Mode", (float)blendMode);
});
matDesc = new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, src),
ShaderName,
null,
textureSlots,
floatValues,
colors,
vectors,
actions);
return true;
}
}
}
}

View File

@ -1,4 +1,7 @@
using UniGLTF.UniUnlit;
using System;
using System.Collections.Generic;
using UniGLTF.UniUnlit;
using UnityEngine;
using VRMShaders;
using ColorSpace = VRMShaders.ColorSpace;
@ -6,6 +9,8 @@ namespace UniGLTF
{
public static class GltfUnlitMaterialImporter
{
private static readonly int Cutoff = Shader.PropertyToID("_Cutoff");
public static bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc)
{
if (i < 0 || i >= data.GLTF.materials.Count)
@ -21,67 +26,83 @@ namespace UniGLTF
return false;
}
matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), UniUnlitUtil.ShaderName);
var textureSlots = new Dictionary<string, TextureDescriptor>();
var colors =
src.pbrMetallicRoughness.baseColorFactor != null &&
src.pbrMetallicRoughness.baseColorFactor.Length == 4
? new Dictionary<string, Color>
{
{
"_Color",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
}
}
: new Dictionary<string, Color>();
// texture
if (src.pbrMetallicRoughness.baseColorTexture != null)
{
var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
var (key, textureParam) = GltfTextureImporter.CreateSRGB(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
matDesc.TextureSlots.Add("_MainTex", textureParam);
var (offset, scale) =
GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture);
var (key, textureParam) = GltfTextureImporter.CreateSRGB(data,
src.pbrMetallicRoughness.baseColorTexture.index, offset, scale);
textureSlots.Add("_MainTex", textureParam);
}
// color
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
matDesc.Colors.Add("_Color",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
);
}
matDesc = new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, src),
UniUnlitUtil.ShaderName,
null,
textureSlots,
new Dictionary<string, float>(),
colors,
new Dictionary<string, Vector4>(),
new Action<Material>[]
{
//renderMode
material =>
{
switch (src.alphaMode)
{
case "OPAQUE":
UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Opaque);
break;
case "BLEND":
UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Transparent);
break;
case "MASK":
UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Cutout);
material.SetFloat(Cutoff, src.alphaCutoff);
break;
default:
// default OPAQUE
UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Opaque);
break;
}
//renderMode
matDesc.Actions.Add(material =>
{
if (src.alphaMode == "OPAQUE")
{
UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque);
}
else if (src.alphaMode == "BLEND")
{
UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent);
}
else if (src.alphaMode == "MASK")
{
UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout);
material.SetFloat("_Cutoff", src.alphaCutoff);
}
else
{
// default OPAQUE
UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque);
}
// culling
if (src.doubleSided)
{
UniUnlitUtil.SetCullMode(material, UniUnlitCullMode.Off);
}
else
{
UniUnlitUtil.SetCullMode(material, UniUnlitCullMode.Back);
}
// culling
if (src.doubleSided)
{
UniUnlitUtil.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off);
}
else
{
UniUnlitUtil.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back);
}
// VColor
var hasVertexColor = data.GLTF.MaterialHasVertexColor(i);
if (hasVertexColor)
{
UniUnlitUtil.SetVColBlendMode(material, UniUnlitVertexColorBlendOp.Multiply);
}
// VColor
var hasVertexColor = data.GLTF.MaterialHasVertexColor(i);
if (hasVertexColor)
{
UniUnlitUtil.SetVColBlendMode(material, UniUnlit.UniUnlitVertexColorBlendOp.Multiply);
UniUnlitUtil.ValidateProperties(material, true);
}
}
UniUnlitUtil.ValidateProperties(material, true);
});
);
return true;
}
}
}
}

View File

@ -1,4 +1,6 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine;
using VRMShaders;
using ColorSpace = VRMShaders.ColorSpace;
@ -11,6 +13,10 @@ namespace UniGLTF
/// </summary>
public static class GltfPbrUrpMaterialImporter
{
private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend");
private static readonly int DstBlend = Shader.PropertyToID("_DstBlend");
private static readonly int ZWrite = Shader.PropertyToID("_ZWrite");
private static readonly int Cutoff = Shader.PropertyToID("_Cutoff");
public const string ShaderName = "Universal Render Pipeline/Lit";
private enum BlendMode
@ -29,8 +35,12 @@ namespace UniGLTF
return false;
}
var textureSlots = new Dictionary<string, TextureDescriptor>();
var floatValues = new Dictionary<string, float>();
var colors = new Dictionary<string, Color>();
var vectors = new Dictionary<string, Vector4>();
var actions = new List<Action<Material>>();
var src = data.GLTF.materials[i];
matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), ShaderName);
var standardTexDesc = default(TextureDescriptor);
if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)
@ -44,7 +54,7 @@ namespace UniGLTF
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
// from _Color !
matDesc.Colors.Add("_BaseColor",
colors.Add("_BaseColor",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
);
}
@ -53,45 +63,45 @@ namespace UniGLTF
{
var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src);
// from _MainTex !
matDesc.TextureSlots.Add("_BaseMap", textureParam);
textureSlots.Add("_BaseMap", textureParam);
}
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
{
matDesc.Actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP"));
matDesc.TextureSlots.Add("_MetallicGlossMap", standardTexDesc);
actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP"));
textureSlots.Add("_MetallicGlossMap", standardTexDesc);
// Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
matDesc.FloatValues.Add("_Metallic", 1.0f);
matDesc.FloatValues.Add("_GlossMapScale", 1.0f);
floatValues.Add("_Metallic", 1.0f);
floatValues.Add("_GlossMapScale", 1.0f);
// default value is 0.5 !
matDesc.FloatValues.Add("_Smoothness", 1.0f);
floatValues.Add("_Smoothness", 1.0f);
}
else
{
matDesc.FloatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
// from _Glossiness !
matDesc.FloatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
floatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
}
}
if (src.normalTexture != null && src.normalTexture.index != -1)
{
matDesc.Actions.Add(material => material.EnableKeyword("_NORMALMAP"));
actions.Add(material => material.EnableKeyword("_NORMALMAP"));
var (key, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src);
matDesc.TextureSlots.Add("_BumpMap", textureParam);
matDesc.FloatValues.Add("_BumpScale", src.normalTexture.scale);
textureSlots.Add("_BumpMap", textureParam);
floatValues.Add("_BumpScale", src.normalTexture.scale);
}
if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
{
matDesc.TextureSlots.Add("_OcclusionMap", standardTexDesc);
matDesc.FloatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
textureSlots.Add("_OcclusionMap", standardTexDesc);
floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
}
if (src.emissiveFactor != null
|| (src.emissiveTexture != null && src.emissiveTexture.index != -1))
{
matDesc.Actions.Add(material =>
actions.Add(material =>
{
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
@ -105,17 +115,17 @@ namespace UniGLTF
{
emissiveFactor *= ex.EmissiveMultiplier.Value;
}
matDesc.Colors.Add("_EmissionColor", emissiveFactor);
colors.Add("_EmissionColor", emissiveFactor);
}
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src);
matDesc.TextureSlots.Add("_EmissionMap", textureParam);
textureSlots.Add("_EmissionMap", textureParam);
}
}
matDesc.Actions.Add(material =>
actions.Add(material =>
{
BlendMode blendMode = BlendMode.Opaque;
// https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
@ -124,9 +134,9 @@ namespace UniGLTF
case "BLEND":
blendMode = BlendMode.Fade;
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt(ZWrite, 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -136,10 +146,10 @@ namespace UniGLTF
case "MASK":
blendMode = BlendMode.Cutout;
material.SetOverrideTag("RenderType", "TransparentCutout");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.SetFloat("_Cutoff", src.alphaCutoff);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt(ZWrite, 1);
material.SetFloat(Cutoff, src.alphaCutoff);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -150,9 +160,9 @@ namespace UniGLTF
default: // OPAQUE
blendMode = BlendMode.Opaque;
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt(ZWrite, 1);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
@ -163,6 +173,15 @@ namespace UniGLTF
material.SetFloat("_Mode", (float)blendMode);
});
matDesc = new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, src),
ShaderName,
null,
textureSlots,
floatValues,
colors,
vectors,
actions);
return true;
}
}

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
using VRMShaders;
@ -12,19 +14,22 @@ namespace UniGLTF
{
public MaterialDescriptor Get(GltfData data, int i)
{
if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param))
{
if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out param))
{
// fallback
if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param;
if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out param)) return param;
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialDescriptor(GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
}
}
return new MaterialDescriptor(
GetMaterialName(i, null),
GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Collection<Action<Material>>());
return param;
}
public static string GetMaterialName(int index, glTFMaterial src)
@ -33,7 +38,8 @@ namespace UniGLTF
{
return src.name;
}
return $"material_{index:00}";
}
}
}
}

View File

@ -1,4 +1,6 @@
using UniGLTF;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -6,13 +8,15 @@ namespace VRM
{
public static class VRMMToonMaterialImporter
{
public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, out MaterialDescriptor matDesc)
public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx,
out MaterialDescriptor matDesc)
{
if (vrm?.materialProperties == null || vrm.materialProperties.Count == 0)
{
matDesc = default;
return false;
}
if (materialIdx < 0 || materialIdx >= vrm.materialProperties.Count)
{
matDesc = default;
@ -20,7 +24,7 @@ namespace VRM
}
var vrmMaterial = vrm.materialProperties[materialIdx];
if (vrmMaterial.shader == VRM.glTF_VRM_Material.VRM_USE_GLTFSHADER)
if (vrmMaterial.shader == glTF_VRM_Material.VRM_USE_GLTFSHADER)
{
// fallback to gltf
matDesc = default;
@ -32,30 +36,41 @@ namespace VRM
//
// use material.name, because material name may renamed in GltfParser.
var name = data.GLTF.materials[materialIdx].name;
matDesc = new MaterialDescriptor(name, vrmMaterial.shader);
matDesc.RenderQueue = vrmMaterial.renderQueue;
var textureSlots = new Dictionary<string, TextureDescriptor>();
var floatValues = new Dictionary<string, float>();
var colors = new Dictionary<string, Color>();
var vectors = new Dictionary<string, Vector4>();
var actions = new List<Action<Material>>();
matDesc = new MaterialDescriptor(
name,
vrmMaterial.shader,
vrmMaterial.renderQueue,
textureSlots,
floatValues,
colors,
vectors,
actions);
foreach (var kv in vrmMaterial.floatProperties)
{
matDesc.FloatValues.Add(kv.Key, kv.Value);
floatValues.Add(kv.Key, kv.Value);
}
foreach (var kv in vrmMaterial.vectorProperties)
{
// vector4 exclude TextureOffsetScale
if (!vrmMaterial.textureProperties.ContainsKey(kv.Key))
{
var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]);
matDesc.Vectors.Add(kv.Key, v);
}
if (vrmMaterial.textureProperties.ContainsKey(kv.Key)) continue;
var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]);
vectors.Add(kv.Key, v);
}
foreach (var kv in vrmMaterial.textureProperties)
{
if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, kv.Key, out var texture))
if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, kv.Key,
out var texture))
{
matDesc.TextureSlots.Add(kv.Key, texture.Item2);
textureSlots.Add(kv.Key, texture.Item2);
}
}
@ -63,28 +78,27 @@ namespace VRM
{
if (kv.Value)
{
matDesc.Actions.Add(material => material.EnableKeyword(kv.Key));
actions.Add(material => material.EnableKeyword(kv.Key));
}
else
{
matDesc.Actions.Add(material => material.DisableKeyword(kv.Key));
actions.Add(material => material.DisableKeyword(kv.Key));
}
}
foreach (var kv in vrmMaterial.tagMap)
{
matDesc.Actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value));
actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value));
}
if (vrmMaterial.shader == MToon.Utils.ShaderName)
{
// TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける
// インポート時にUniVRMに含まれるMToonのバージョンに上書きする
matDesc.FloatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber;
floatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber;
}
return true;
}
}
}
}

View File

@ -1,4 +1,6 @@
using UniGLTF;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -14,10 +16,8 @@ namespace VRM
public MaterialDescriptor Get(GltfData data, int i)
{
MaterialDescriptor matDesc;
// legacy "VRM/UnlitTransparentZWrite"
if (VRMUnlitTransparentZWriteMaterialImporter.TryCreateParam(data, m_vrm, i, out matDesc))
if (VRMUnlitTransparentZWriteMaterialImporter.TryCreateParam(data, m_vrm, i, out var matDesc))
{
return matDesc;
}
@ -42,7 +42,15 @@ namespace VRM
// fallback
Debug.LogWarning($"fallback");
return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
return new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, null),
GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Action<Material>[]{});
}
}
}

View File

@ -1,4 +1,6 @@
using UniGLTF;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -16,19 +18,22 @@ namespace VRM
{
// mtoon URP "MToon" shader is not ready. import fallback to unlit
// unlit "UniUnlit" work in URP
if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc))
{
// pbr "Standard" to "Universal Render Pipeline/Lit"
if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc))
{
// fallback
if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var matDesc)) return matDesc;
// pbr "Standard" to "Universal Render Pipeline/Lit"
if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
}
}
return matDesc;
return new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, null),
GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Action<Material>[]{});
}
}
}

View File

@ -1,3 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MToon;
using UniGLTF;
using UnityEngine;
@ -11,13 +14,15 @@ namespace VRM
public const string UnlitTransparentZWriteShaderName = "VRM/UnlitTransparentZWrite";
public const string UnlitTransparentZWriteMainTexturePropName = "_MainTex";
public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, out MaterialDescriptor matDesc)
public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx,
out MaterialDescriptor matDesc)
{
if (vrm?.materialProperties == null || vrm.materialProperties.Count == 0)
{
matDesc = default;
return false;
}
if (materialIdx < 0 || materialIdx >= vrm.materialProperties.Count)
{
matDesc = default;
@ -34,19 +39,24 @@ namespace VRM
// use material.name, because material name may renamed in GltfParser.
var name = data.GLTF.materials[materialIdx].name;
matDesc = new MaterialDescriptor(name, MToon.Utils.ShaderName);
var textureSlots = new Dictionary<string, TextureDescriptor>();
var floatValues = new Dictionary<string, float>();
var colors = new Dictionary<string, Color>();
var vectors = new Dictionary<string, Vector4>();
var actions = new Collection<Action<Material>>();
if (vrmMaterial.textureProperties.ContainsKey(UnlitTransparentZWriteMainTexturePropName))
{
if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, UnlitTransparentZWriteMainTexturePropName, out var texture))
if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial,
UnlitTransparentZWriteMainTexturePropName, out var texture))
{
matDesc.TextureSlots.Add(MToon.Utils.PropMainTex, texture.Item2);
textureSlots.Add(MToon.Utils.PropMainTex, texture.Item2);
}
}
matDesc.Actions.Add(unityMaterial =>
actions.Add(unityMaterial =>
{
var mainTexture = (Texture2D) unityMaterial.GetTexture(MToon.Utils.PropMainTex);
var mainTexture = (Texture2D)unityMaterial.GetTexture(MToon.Utils.PropMainTex);
// NOTE: Unlit のフォールバックなので
// Lit/Shade 色は黒として、Alpha のために Lit にテクスチャを設定する.
@ -148,8 +158,15 @@ namespace VRM
unityMaterial.renderQueue = vrmMaterial.renderQueue;
});
matDesc = new MaterialDescriptor(name, Utils.ShaderName, null,
textureSlots,
floatValues,
colors,
vectors,
actions);
Debug.LogWarning($"fallback: {UnlitTransparentZWriteShaderName} => {MToon.Utils.ShaderName}");
return true;
}
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UniGLTF.Extensions.VRMC_materials_mtoon;
using UnityEngine;
@ -30,33 +31,22 @@ namespace UniVRM10
}
// use material.name, because material name may renamed in GltfParser.
matDesc = new MaterialDescriptor(m.name, MToon10Meta.UnityShaderName);
foreach (var (key, (subAssetKey, value)) in Vrm10MToonTextureImporter.EnumerateAllTextures(data, m, mtoon))
{
matDesc.TextureSlots.Add(key, value);
}
foreach (var (key, value) in TryGetAllColors(m, mtoon))
{
matDesc.Colors.Add(key, value);
}
foreach (var (key, value) in TryGetAllFloats(m, mtoon))
{
matDesc.FloatValues.Add(key, value);
}
foreach (var (key, value) in TryGetAllFloatArrays(m, mtoon))
{
matDesc.Vectors.Add(key, value);
}
matDesc.Actions.Add(material =>
{
// Set hidden properties, keywords from float properties.
new MToonValidator(material).Validate();
});
matDesc = new MaterialDescriptor(
m.name,
MToon10Meta.UnityShaderName,
null,
Vrm10MToonTextureImporter.EnumerateAllTextures(data, m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.Item2.Item2),
TryGetAllFloats(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value),
TryGetAllColors(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value),
TryGetAllFloatArrays(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value),
new Action<Material>[]
{
material =>
{
// Set hidden properties, keywords from float properties.
new MToonValidator(material).Validate();
}
});
return true;
}

View File

@ -1,4 +1,6 @@
using UniGLTF;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -9,23 +11,23 @@ namespace UniVRM10
public MaterialDescriptor Get(GltfData data, int i)
{
// mtoon
if (!Vrm10MToonMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc))
{
// unlit
if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out matDesc))
{
// pbr
if (!GltfPbrMaterialImporter.TryCreateParam(data, i, out matDesc))
{
// fallback
if (Vrm10MToonMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) return matDesc;
// unlit
if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
// pbr
if (GltfPbrMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
}
}
}
return matDesc;
return new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Action<Material>[]{});
}
}

View File

@ -1,4 +1,6 @@
using UniGLTF;
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
@ -9,17 +11,20 @@ namespace UniVRM10
public MaterialDescriptor Get(GltfData data, int i)
{
// unlit
if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc))
{
// pbr
if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc))
{
// fallback
Debug.LogWarning($"material: {i} out of range. fallback");
return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
}
}
return matDesc;
if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) return matDesc;
// pbr
if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
// fallback
Debug.LogWarning($"material: {i} out of range. fallback");
return new MaterialDescriptor(
GltfMaterialDescriptorGenerator.GetMaterialName(i, null),
GltfPbrMaterialImporter.ShaderName,
null,
new Dictionary<string, TextureDescriptor>(),
new Dictionary<string, float>(),
new Dictionary<string, Color>(),
new Dictionary<string, Vector4>(),
new Action<Material>[]{});
}
}

View File

@ -2,26 +2,65 @@
using System.Collections.Generic;
using UnityEngine;
namespace VRMShaders
{
public class MaterialDescriptor
public readonly struct MaterialDescriptor : IEquatable<MaterialDescriptor>
{
public readonly string Name;
public readonly string ShaderName;
public readonly Dictionary<string, TextureDescriptor> TextureSlots = new Dictionary<string, TextureDescriptor>();
public readonly Dictionary<string, float> FloatValues = new Dictionary<string, float>();
public readonly Dictionary<string, Color> Colors = new Dictionary<string, Color>();
public readonly Dictionary<string, Vector4> Vectors = new Dictionary<string, Vector4>();
public int? RenderQueue;
public readonly List<Action<Material>> Actions = new List<Action<Material>>();
public readonly int? RenderQueue;
public readonly IReadOnlyDictionary<string, TextureDescriptor> TextureSlots;
public readonly IReadOnlyDictionary<string, float> FloatValues;
public readonly IReadOnlyDictionary<string, Color> Colors;
public readonly IReadOnlyDictionary<string, Vector4> Vectors;
public readonly IReadOnlyList<Action<Material>> Actions;
public SubAssetKey SubAssetKey => new SubAssetKey(SubAssetKey.MaterialType, Name);
public MaterialDescriptor(string name, string shaderName)
public MaterialDescriptor(
string name,
string shaderName,
int? renderQueue,
IReadOnlyDictionary<string, TextureDescriptor> textureSlots,
IReadOnlyDictionary<string, float> floatValues,
IReadOnlyDictionary<string, Color> colors,
IReadOnlyDictionary<string, Vector4> vectors,
IReadOnlyList<Action<Material>> actions)
{
Name = name;
ShaderName = shaderName;
RenderQueue = renderQueue;
TextureSlots = textureSlots;
FloatValues = floatValues;
Colors = colors;
Vectors = vectors;
Actions = actions;
}
public bool Equals(MaterialDescriptor other)
{
return Name == other.Name && ShaderName == other.ShaderName && RenderQueue == other.RenderQueue && Equals(TextureSlots, other.TextureSlots) && Equals(FloatValues, other.FloatValues) && Equals(Colors, other.Colors) && Equals(Vectors, other.Vectors) && Equals(Actions, other.Actions);
}
public override bool Equals(object obj)
{
return obj is MaterialDescriptor other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = (Name != null ? Name.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (ShaderName != null ? ShaderName.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ RenderQueue.GetHashCode();
hashCode = (hashCode * 397) ^ (TextureSlots != null ? TextureSlots.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (FloatValues != null ? FloatValues.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (Colors != null ? Colors.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (Vectors != null ? Vectors.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (Actions != null ? Actions.GetHashCode() : 0);
return hashCode;
}
}
}
}
}