mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-27 21:34:38 -05:00
add GltfURPMaterialDescriptorGenerator
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// glb をパースして、UnityObject化、さらにAsset化する
|
||||
/// </summary>
|
||||
/// <param name="scriptedImporter"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="reverseAxis"></param>
|
||||
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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,12 @@ namespace UniGLTF
|
||||
public ImporterContext(
|
||||
GltfData data,
|
||||
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> 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<SubAssetKey, UnityEngine.Object>();
|
||||
textureDeserializer = textureDeserializer ?? new UnityTextureDeserializer();
|
||||
|
||||
8
Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP.meta
Normal file
8
Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e25906189630c09469e8bdfcab01b754
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,169 @@
|
||||
using UnityEngine;
|
||||
using VRMShaders;
|
||||
using ColorSpace = VRMShaders.ColorSpace;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08a0ae763ee70ed45809fad80ffe8e78
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using VRMShaders;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// GLTF の MaterialImporter
|
||||
/// </summary>
|
||||
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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ae66bf5ee5e1cb44b7dc416727d3bc1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user