diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs
index f14ff3e0b..bb996f84e 100644
--- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs
+++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs
@@ -12,7 +12,7 @@ namespace UniGLTF
{
public override void OnImportAsset(AssetImportContext ctx)
{
- Import(this, ctx, m_reverseAxis.ToAxes());
+ Import(this, ctx, m_reverseAxis.ToAxes(), m_useURPMaterial);
}
}
}
diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs
index 2ab443cd6..1a6df70c2 100644
--- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs
+++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs
@@ -12,7 +12,7 @@ namespace UniGLTF
{
public override void OnImportAsset(AssetImportContext ctx)
{
- Import(this, ctx, m_reverseAxis.ToAxes());
+ Import(this, ctx, m_reverseAxis.ToAxes(), m_useURPMaterial);
}
}
}
diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterBase.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterBase.cs
index cbb75086e..9ce13fe48 100644
--- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterBase.cs
+++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterBase.cs
@@ -2,6 +2,7 @@ using UnityEngine;
using UnityEditor;
using System.Linq;
using VRMShaders;
+using UnityEngine.Rendering;
#if UNITY_2020_2_OR_NEWER
using UnityEditor.AssetImporters;
#else
@@ -19,13 +20,28 @@ namespace UniGLTF
[SerializeField]
public ScriptedImporterAxes m_reverseAxis = default;
+ [SerializeField]
+ public bool m_useURPMaterial;
+
+ static IMaterialDescriptorGenerator GetMaterialGenerator(bool useURPMaterial)
+ {
+ if (useURPMaterial)
+ {
+ return new GltfURPMaterialDescriptorGenerator();
+ }
+ else
+ {
+ return new GltfMaterialDescriptorGenerator();
+ }
+ }
+
///
/// glb をパースして、UnityObject化、さらにAsset化する
///
///
///
///
- protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis)
+ protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis, bool useURPMaterial)
{
#if VRM_DEVELOP
Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
@@ -46,7 +62,9 @@ namespace UniGLTF
.Where(x => x.Value != null)
.ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);
- using (var loader = new ImporterContext(data, extractedObjects))
+ IMaterialDescriptorGenerator materialGenerator = GetMaterialGenerator(useURPMaterial);
+
+ using (var loader = new ImporterContext(data, extractedObjects, materialGenerator: materialGenerator))
{
// Configure TextureImporter to Extracted Textures.
foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable())
diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ZipArchivedGltfScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ZipArchivedGltfScriptedImporter.cs
index 668cbe3a2..719b1995a 100644
--- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ZipArchivedGltfScriptedImporter.cs
+++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ZipArchivedGltfScriptedImporter.cs
@@ -14,7 +14,7 @@ namespace UniGLTF
{
public override void OnImportAsset(AssetImportContext ctx)
{
- Import(this, ctx, m_reverseAxis.ToAxes());
+ Import(this, ctx, m_reverseAxis.ToAxes(), m_useURPMaterial);
}
}
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs
index 814eac7b2..d9ed0dba9 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs
@@ -22,11 +22,12 @@ namespace UniGLTF
public ImporterContext(
GltfData data,
IReadOnlyDictionary externalObjectMap = null,
- ITextureDeserializer textureDeserializer = null)
+ ITextureDeserializer textureDeserializer = null,
+ IMaterialDescriptorGenerator materialGenerator = null)
{
Data = data;
TextureDescriptorGenerator = new GltfTextureDescriptorGenerator(Data);
- MaterialDescriptorGenerator = new GltfMaterialDescriptorGenerator();
+ MaterialDescriptorGenerator = materialGenerator ?? new GltfMaterialDescriptorGenerator();
ExternalObjectMap = externalObjectMap ?? new Dictionary();
textureDeserializer = textureDeserializer ?? new UnityTextureDeserializer();
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP.meta
new file mode 100644
index 000000000..a716bc76f
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e25906189630c09469e8bdfcab01b754
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs
new file mode 100644
index 000000000..7276126c7
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs
@@ -0,0 +1,169 @@
+using UnityEngine;
+using VRMShaders;
+using ColorSpace = VRMShaders.ColorSpace;
+
+namespace UniGLTF
+{
+ ///
+ /// glTF PBR to URP Lit.
+ ///
+ /// see: https://github.com/Unity-Technologies/Graphics/blob/v7.5.3/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineMaterialUpgrader.cs#L354-L379
+ ///
+ public static class GltfPbrURPMaterialImporter
+ {
+ public const string ShaderName = "Universal Render Pipeline/Lit";
+
+ private enum BlendMode
+ {
+ Opaque,
+ Cutout,
+ Fade,
+ Transparent
+ }
+
+ public static bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc)
+ {
+ if (i < 0 || i >= data.GLTF.materials.Count)
+ {
+ matDesc = default;
+ return false;
+ }
+
+ 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)
+ {
+ if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null)
+ {
+ SubAssetKey key;
+ (key, standardTexDesc) = GltfPbrTextureImporter.StandardTexture(data, src);
+ }
+
+ if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
+ {
+ // from _Color !
+ matDesc.Colors.Add("_BaseColor",
+ src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
+ );
+ }
+
+ if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
+ {
+ var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src);
+ // from _MainTex !
+ matDesc.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);
+ // 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);
+ // default value is 0.5 !
+ matDesc.FloatValues.Add("_Smoothness", 1.0f);
+ }
+ else
+ {
+ matDesc.FloatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
+ // from _Glossiness !
+ matDesc.FloatValues.Add("_Smoothness", 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);
+ }
+
+ if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
+ {
+ matDesc.TextureSlots.Add("_OcclusionMap", standardTexDesc);
+ matDesc.FloatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
+ }
+
+ if (src.emissiveFactor != null
+ || (src.emissiveTexture != null && src.emissiveTexture.index != -1))
+ {
+ matDesc.Actions.Add(material =>
+ {
+ material.EnableKeyword("_EMISSION");
+ material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
+ });
+
+ if (src.emissiveFactor != null && src.emissiveFactor.Length == 3)
+ {
+ 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))
+ {
+ emissiveFactor *= ex.EmissiveMultiplier.Value;
+ }
+ matDesc.Colors.Add("_EmissionColor", emissiveFactor);
+ }
+
+ if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
+ {
+ var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src);
+ matDesc.TextureSlots.Add("_EmissionMap", textureParam);
+ }
+ }
+
+ matDesc.Actions.Add(material =>
+ {
+ BlendMode blendMode = BlendMode.Opaque;
+ // 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.DisableKeyword("_ALPHATEST_ON");
+ material.EnableKeyword("_ALPHABLEND_ON");
+ material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
+ material.renderQueue = 3000;
+ break;
+
+ 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.EnableKeyword("_ALPHATEST_ON");
+ material.DisableKeyword("_ALPHABLEND_ON");
+ material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
+ material.renderQueue = 2450;
+
+ break;
+
+ 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.DisableKeyword("_ALPHATEST_ON");
+ material.DisableKeyword("_ALPHABLEND_ON");
+ material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
+ material.renderQueue = -1;
+ break;
+ }
+
+ material.SetFloat("_Mode", (float)blendMode);
+ });
+
+ return true;
+ }
+ }
+}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs.meta
new file mode 100644
index 000000000..3a87eaf63
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 08a0ae763ee70ed45809fad80ffe8e78
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs
new file mode 100644
index 000000000..479ad31cb
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using UnityEngine;
+using VRMShaders;
+
+
+namespace UniGLTF
+{
+ ///
+ /// GLTF の MaterialImporter
+ ///
+ public sealed class GltfURPMaterialDescriptorGenerator : IMaterialDescriptorGenerator
+ {
+ public MaterialDescriptor Get(GltfData data, int i)
+ {
+ if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param))
+ {
+ if (!GltfPbrURPMaterialImporter.TryCreateParam(data, i, out param))
+ {
+ // fallback
+#if VRM_DEVELOP
+ Debug.LogWarning($"material: {i} out of range. fallback");
+#endif
+ return new MaterialDescriptor(GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName);
+ }
+ }
+
+ return param;
+ }
+
+ public static string GetMaterialName(int index, glTFMaterial src)
+ {
+ if (src != null && !string.IsNullOrEmpty(src.name))
+ {
+ return src.name;
+ }
+ return $"material_{index:00}";
+ }
+ }
+}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs.meta
new file mode 100644
index 000000000..ba39444e7
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4ae66bf5ee5e1cb44b7dc416727d3bc1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: