Merge branch 'master' into fix/samples_urp_scene
|
|
@ -19,35 +19,7 @@ namespace UniGLTF
|
|||
public ScriptedImporterAxes m_reverseAxis = default;
|
||||
|
||||
[SerializeField]
|
||||
[Header("Experimental")]
|
||||
public RenderPipelineTypes m_renderPipeline;
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
if (m_renderPipeline == UniGLTF.RenderPipelineTypes.UniversalRenderPipeline)
|
||||
{
|
||||
if (Shader.Find(UniGLTF.UrpGltfPbrMaterialImporter.ShaderName) == null)
|
||||
{
|
||||
Debug.LogWarning("URP is not installed. Force to BuiltinRenderPipeline");
|
||||
m_renderPipeline = UniGLTF.RenderPipelineTypes.BuiltinRenderPipeline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IMaterialDescriptorGenerator GetMaterialGenerator(RenderPipelineTypes renderPipeline)
|
||||
{
|
||||
switch (renderPipeline)
|
||||
{
|
||||
case RenderPipelineTypes.BuiltinRenderPipeline:
|
||||
return new BuiltInGltfMaterialDescriptorGenerator();
|
||||
|
||||
case RenderPipelineTypes.UniversalRenderPipeline:
|
||||
return new UrpGltfMaterialDescriptorGenerator();
|
||||
|
||||
default:
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
public ImporterRenderPipelineTypes m_renderPipeline;
|
||||
|
||||
/// <summary>
|
||||
/// glb をパースして、UnityObject化、さらにAsset化する
|
||||
|
|
@ -55,7 +27,8 @@ namespace UniGLTF
|
|||
/// <param name="scriptedImporter"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="reverseAxis"></param>
|
||||
protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis, RenderPipelineTypes renderPipeline)
|
||||
/// <param name="renderPipeline"></param>
|
||||
protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis, ImporterRenderPipelineTypes renderPipeline)
|
||||
{
|
||||
UniGLTFLogger.Log("OnImportAsset to " + scriptedImporter.assetPath);
|
||||
|
||||
|
|
@ -68,10 +41,11 @@ namespace UniGLTF
|
|||
.Where(x => x.Value != null)
|
||||
.ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);
|
||||
|
||||
IMaterialDescriptorGenerator materialGenerator = GetMaterialGenerator(renderPipeline);
|
||||
var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline);
|
||||
var importerContextSettings = new ImporterContextSettings(loadAnimation: true, invertAxis: reverseAxis);
|
||||
|
||||
using (var data = new AutoGltfFileParser(scriptedImporter.assetPath).Parse())
|
||||
using (var loader = new ImporterContext(data, extractedObjects, materialGenerator: materialGenerator))
|
||||
using (var loader = new ImporterContext(data, extractedObjects, materialGenerator: materialGenerator, settings: importerContextSettings))
|
||||
{
|
||||
// Configure TextureImporter to Extracted Textures.
|
||||
foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable())
|
||||
|
|
@ -79,7 +53,6 @@ namespace UniGLTF
|
|||
TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures);
|
||||
}
|
||||
|
||||
loader.InvertAxis = reverseAxis;
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
|
|
@ -94,5 +67,16 @@ namespace UniGLTF
|
|||
context.SetMainObject(root);
|
||||
}
|
||||
}
|
||||
|
||||
private static IMaterialDescriptorGenerator GetMaterialDescriptorGenerator(ImporterRenderPipelineTypes renderPipeline)
|
||||
{
|
||||
return renderPipeline switch
|
||||
{
|
||||
ImporterRenderPipelineTypes.Auto => MaterialDescriptorGeneratorUtility .GetValidGltfMaterialDescriptorGenerator(),
|
||||
ImporterRenderPipelineTypes.BuiltinRenderPipeline => MaterialDescriptorGeneratorUtility .GetGltfMaterialDescriptorGenerator(RenderPipelineTypes.BuiltinRenderPipeline),
|
||||
ImporterRenderPipelineTypes.UniversalRenderPipeline => MaterialDescriptorGeneratorUtility .GetGltfMaterialDescriptorGenerator(RenderPipelineTypes.UniversalRenderPipeline),
|
||||
_ => MaterialDescriptorGeneratorUtility.GetValidGltfMaterialDescriptorGenerator(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public enum ImporterRenderPipelineTypes
|
||||
{
|
||||
Auto = 0,
|
||||
BuiltinRenderPipeline = 1,
|
||||
UniversalRenderPipeline = 2,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d4f38213d6e442ef986fd3e633991ba7
|
||||
timeCreated: 1722347490
|
||||
|
|
@ -145,6 +145,7 @@ namespace UniGLTF
|
|||
public int AppendToBuffer(NativeArray<byte> segment)
|
||||
{
|
||||
var gltfBufferView = _buffer.Extend(segment);
|
||||
Gltf.buffers[0].byteLength = _buffer.Bytes.Count;
|
||||
var viewIndex = Gltf.bufferViews.Count;
|
||||
Gltf.bufferViews.Add(gltfBufferView);
|
||||
return viewIndex;
|
||||
|
|
|
|||
|
|
@ -12,12 +12,14 @@ namespace UniGLTF
|
|||
/// </summary>
|
||||
public class ImporterContext : IResponsibilityForDestroyObjects
|
||||
{
|
||||
private readonly ImporterContextSettings _settings;
|
||||
|
||||
public ITextureDescriptorGenerator TextureDescriptorGenerator { get; protected set; }
|
||||
public IMaterialDescriptorGenerator MaterialDescriptorGenerator { get; protected set; }
|
||||
public TextureFactory TextureFactory { get; }
|
||||
public MaterialFactory MaterialFactory { get; }
|
||||
public AnimationClipFactory AnimationClipFactory { get; }
|
||||
public bool LoadAnimation { get; set; } = true;
|
||||
private bool LoadAnimation => _settings.LoadAnimation;
|
||||
|
||||
public IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> ExternalObjectMap;
|
||||
|
||||
|
|
@ -29,12 +31,15 @@ namespace UniGLTF
|
|||
/// <param name="externalObjectMap">外部オブジェクトのリスト(主にScriptedImporterのRemapで使う)</param>
|
||||
/// <param name="textureDeserializer">Textureロードをカスタマイズする</param>
|
||||
/// <param name="materialGenerator">Materialロードをカスタマイズする(URP向け)</param>
|
||||
/// <param name="settings">ImporterContextの設定</param>
|
||||
public ImporterContext(
|
||||
GltfData data,
|
||||
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> externalObjectMap = null,
|
||||
ITextureDeserializer textureDeserializer = null,
|
||||
IMaterialDescriptorGenerator materialGenerator = null)
|
||||
IMaterialDescriptorGenerator materialGenerator = null,
|
||||
ImporterContextSettings settings = null)
|
||||
{
|
||||
_settings = settings ?? new ImporterContextSettings();
|
||||
Data = data;
|
||||
TextureDescriptorGenerator = new GltfTextureDescriptorGenerator(Data);
|
||||
MaterialDescriptorGenerator = materialGenerator ?? MaterialDescriptorGeneratorUtility.GetValidGltfMaterialDescriptorGenerator();
|
||||
|
|
@ -66,7 +71,7 @@ namespace UniGLTF
|
|||
/// <summary>
|
||||
/// GLTF から Unity に変換するときに反転させる軸
|
||||
/// </summary>
|
||||
public Axes InvertAxis = Axes.Z;
|
||||
private Axes InvertAxis => _settings.InvertAxis;
|
||||
|
||||
public static List<string> UnsupportedExtensions = new List<string>
|
||||
{
|
||||
|
|
|
|||
19
Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextSettings.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public class ImporterContextSettings
|
||||
{
|
||||
public bool LoadAnimation { get; }
|
||||
public Axes InvertAxis { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ImporterContextの設定を指定する。
|
||||
/// </summary>
|
||||
/// <param name="loadAnimation">アニメーションをインポートする場合はtrueを指定(初期値はtrue)</param>
|
||||
/// <param name="invertAxis">GLTF から Unity に変換するときに反転させる軸を指定(初期値はAxes.Z)</param>
|
||||
public ImporterContextSettings(bool loadAnimation = true, Axes invertAxis = Axes.Z)
|
||||
{
|
||||
LoadAnimation = loadAnimation;
|
||||
InvertAxis = invertAxis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 091d1bfaecd542b6a039fb7a3e3676f8
|
||||
timeCreated: 1723863327
|
||||
|
|
@ -13,26 +13,15 @@ namespace UniGLTF
|
|||
{
|
||||
if (BuiltInGltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param;
|
||||
if (BuiltInGltfPbrMaterialImporter.TryCreateParam(data, i, out param)) return param;
|
||||
|
||||
// fallback
|
||||
if (Symbols.VRM_DEVELOP)
|
||||
{
|
||||
Debug.LogWarning($"material: {i} out of range. fallback");
|
||||
}
|
||||
|
||||
return new MaterialDescriptor(
|
||||
GltfMaterialImportUtils.ImportMaterialName(i, null),
|
||||
BuiltInGltfPbrMaterialImporter.Shader,
|
||||
null,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new Action<Material>[]{});
|
||||
return GetGltfDefault(GltfMaterialImportUtils.ImportMaterialName(i, null));
|
||||
}
|
||||
|
||||
public MaterialDescriptor GetGltfDefault()
|
||||
{
|
||||
return BuiltInGltfDefaultMaterialImporter.CreateParam();
|
||||
}
|
||||
public MaterialDescriptor GetGltfDefault(string materialName = null) => BuiltInGltfDefaultMaterialImporter.CreateParam(materialName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ namespace UniGLTF
|
|||
/// </summary>
|
||||
public static class BuiltInGltfDefaultMaterialImporter
|
||||
{
|
||||
public static MaterialDescriptor CreateParam()
|
||||
public static MaterialDescriptor CreateParam(string materialName = null)
|
||||
{
|
||||
// FIXME
|
||||
return new MaterialDescriptor(
|
||||
"__default__",
|
||||
string.IsNullOrEmpty(materialName) ? "__default__" : materialName,
|
||||
BuiltInGltfPbrMaterialImporter.Shader,
|
||||
default,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
|
|
|
|||
|
|
@ -7,10 +7,19 @@ namespace UniGLTF
|
|||
{
|
||||
public static void ExportTextureTransform(Material src, glTFTextureInfo dstTextureInfo, string targetTextureName)
|
||||
{
|
||||
if (dstTextureInfo != null && src.HasProperty(targetTextureName))
|
||||
if (src.HasProperty(targetTextureName))
|
||||
{
|
||||
var offset = src.GetTextureOffset(targetTextureName);
|
||||
var scale = src.GetTextureScale(targetTextureName);
|
||||
|
||||
ExportTextureTransform(offset, scale, dstTextureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportTextureTransform(Vector2 offset, Vector2 scale, glTFTextureInfo dstTextureInfo)
|
||||
{
|
||||
if (dstTextureInfo != null)
|
||||
{
|
||||
(scale, offset) = TextureTransform.VerticalFlipScaleOffset(scale, offset);
|
||||
|
||||
glTF_KHR_texture_transform.Serialize(dstTextureInfo, (offset.x, offset.y), (scale.x, scale.y));
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
{
|
||||
return RenderPipelineUtility.GetRenderPipelineType() switch
|
||||
{
|
||||
RenderPipelineTypes.UniversalRenderPipeline => throw new System.NotImplementedException(),
|
||||
RenderPipelineTypes.UniversalRenderPipeline => new UrpGltfMaterialExporter(),
|
||||
RenderPipelineTypes.BuiltinRenderPipeline => new BuiltInGltfMaterialExporter(),
|
||||
_ => new BuiltInGltfMaterialExporter(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@
|
|||
/// <summary>
|
||||
/// Generate the MaterialDescriptor for the non-specified glTF material.
|
||||
/// </summary>
|
||||
MaterialDescriptor GetGltfDefault();
|
||||
MaterialDescriptor GetGltfDefault(string materialName = null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public sealed class MaterialDescriptor
|
||||
{
|
||||
public delegate Task MaterialGenerateAsyncFunc(Material m, GetTextureAsyncFunc getTexture, IAwaitCaller awaitCaller);
|
||||
|
||||
public readonly string Name;
|
||||
public readonly Shader Shader;
|
||||
public readonly int? RenderQueue;
|
||||
|
|
@ -14,6 +17,7 @@ namespace UniGLTF
|
|||
public readonly IReadOnlyDictionary<string, Color> Colors;
|
||||
public readonly IReadOnlyDictionary<string, Vector4> Vectors;
|
||||
public readonly IReadOnlyList<Action<Material>> Actions;
|
||||
public readonly IReadOnlyList<MaterialGenerateAsyncFunc> AsyncActions;
|
||||
|
||||
public SubAssetKey SubAssetKey => new SubAssetKey(SubAssetKey.MaterialType, Name);
|
||||
|
||||
|
|
@ -25,7 +29,8 @@ namespace UniGLTF
|
|||
IReadOnlyDictionary<string, float> floatValues,
|
||||
IReadOnlyDictionary<string, Color> colors,
|
||||
IReadOnlyDictionary<string, Vector4> vectors,
|
||||
IReadOnlyList<Action<Material>> actions)
|
||||
IReadOnlyList<Action<Material>> actions,
|
||||
IReadOnlyList<MaterialGenerateAsyncFunc> asyncActions = null)
|
||||
{
|
||||
Name = name;
|
||||
Shader = shader;
|
||||
|
|
@ -35,6 +40,7 @@ namespace UniGLTF
|
|||
Colors = colors;
|
||||
Vectors = vectors;
|
||||
Actions = actions;
|
||||
AsyncActions = asyncActions ?? new List<MaterialGenerateAsyncFunc>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,12 @@ namespace UniGLTF
|
|||
{
|
||||
public static IMaterialDescriptorGenerator GetValidGltfMaterialDescriptorGenerator()
|
||||
{
|
||||
return RenderPipelineUtility.GetRenderPipelineType() switch
|
||||
return GetGltfMaterialDescriptorGenerator(RenderPipelineUtility.GetRenderPipelineType());
|
||||
}
|
||||
|
||||
public static IMaterialDescriptorGenerator GetGltfMaterialDescriptorGenerator(RenderPipelineTypes renderPipelineType)
|
||||
{
|
||||
return renderPipelineType switch
|
||||
{
|
||||
RenderPipelineTypes.UniversalRenderPipeline => new UrpGltfMaterialDescriptorGenerator(),
|
||||
RenderPipelineTypes.BuiltinRenderPipeline => new BuiltInGltfMaterialDescriptorGenerator(),
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@ namespace UniGLTF
|
|||
public class MaterialFactory : IResponsibilityForDestroyObjects
|
||||
{
|
||||
private readonly IReadOnlyDictionary<SubAssetKey, Material> m_externalMap;
|
||||
|
||||
/// <summary>
|
||||
/// デフォルトマテリアルの MaterialDescriptor は IMaterialDescriptorGenerator の実装によって異なるので外から渡す
|
||||
/// </summary>
|
||||
private readonly SubAssetKey m_defaultMaterialKey = new SubAssetKey(typeof(Material), "__UNIGLTF__DEFAULT__MATERIAL__");
|
||||
private readonly MaterialDescriptor m_defaultMaterialParams;
|
||||
private readonly List<MaterialLoadInfo> m_materials = new List<MaterialLoadInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// gltfPritmitive.material が無い場合のデフォルトマテリアル
|
||||
|
|
@ -23,6 +21,9 @@ namespace UniGLTF
|
|||
/// </summary>
|
||||
private Material m_defaultMaterial;
|
||||
|
||||
public IReadOnlyList<MaterialLoadInfo> Materials => m_materials;
|
||||
|
||||
|
||||
public MaterialFactory(IReadOnlyDictionary<SubAssetKey, Material> externalMaterialMap, MaterialDescriptor defaultMaterialParams)
|
||||
{
|
||||
m_externalMap = externalMaterialMap;
|
||||
|
|
@ -45,18 +46,6 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
List<MaterialLoadInfo> m_materials = new List<MaterialLoadInfo>();
|
||||
public IReadOnlyList<MaterialLoadInfo> Materials => m_materials;
|
||||
void Remove(Material material)
|
||||
{
|
||||
var index = m_materials.FindIndex(x => x.Asset == material);
|
||||
if (index >= 0)
|
||||
{
|
||||
m_materials.RemoveAt(index);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var x in m_materials)
|
||||
|
|
@ -67,6 +56,11 @@ namespace UniGLTF
|
|||
UnityObjectDestroyer.DestroyRuntimeOrEditor(x.Asset);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_defaultMaterial != null)
|
||||
{
|
||||
UnityObjectDestroyer.DestroyRuntimeOrEditor(m_defaultMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -90,6 +84,12 @@ namespace UniGLTF
|
|||
m_materials.Remove(x);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_defaultMaterial != null)
|
||||
{
|
||||
take(m_defaultMaterialKey, m_defaultMaterial);
|
||||
m_defaultMaterial = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Material GetMaterial(int index)
|
||||
|
|
@ -101,6 +101,12 @@ namespace UniGLTF
|
|||
|
||||
public async Task<Material> GetDefaultMaterialAsync(IAwaitCaller awaitCaller)
|
||||
{
|
||||
if (m_externalMap.ContainsKey(m_defaultMaterialKey))
|
||||
{
|
||||
m_defaultMaterial = m_externalMap[m_defaultMaterialKey];
|
||||
return m_externalMap[m_defaultMaterialKey];
|
||||
}
|
||||
|
||||
if (m_defaultMaterial == null)
|
||||
{
|
||||
m_defaultMaterial = await LoadAsync(m_defaultMaterialParams, (_, _) => null, awaitCaller);
|
||||
|
|
@ -136,7 +142,8 @@ namespace UniGLTF
|
|||
if (texture != null)
|
||||
{
|
||||
material.SetTexture(kv.Key, texture);
|
||||
SetTextureOffsetAndScale(material, kv.Key, kv.Value.Offset, kv.Value.Scale);
|
||||
material.SetTextureOffset(kv.Key, kv.Value.Offset);
|
||||
material.SetTextureScale(kv.Key, kv.Value.Scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,15 +172,14 @@ namespace UniGLTF
|
|||
action(material);
|
||||
}
|
||||
|
||||
foreach (var asyncAction in matDesc.AsyncActions)
|
||||
{
|
||||
await asyncAction(material, getTexture, awaitCaller);
|
||||
}
|
||||
|
||||
m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, false));
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
public static void SetTextureOffsetAndScale(Material material, string propertyName, Vector2 offset, Vector2 scale)
|
||||
{
|
||||
material.SetTextureOffset(propertyName, offset);
|
||||
material.SetTextureScale(propertyName, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4c2edd284a744a13bf888a4b29fac93a
|
||||
timeCreated: 1722269836
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70546771aa234567b5d7c4430548ac0f
|
||||
timeCreated: 1722269920
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// フォールバック目的で最低限なにかをエクスポートする。
|
||||
///
|
||||
/// メインカラーとメインテクスチャをエクスポートする。
|
||||
/// </summary>
|
||||
public class UrpFallbackMaterialExporter
|
||||
{
|
||||
public glTFMaterial ExportMaterial(Material src, ITextureExporter textureExporter)
|
||||
{
|
||||
var dst = new glTFMaterial
|
||||
{
|
||||
name = src.name,
|
||||
pbrMetallicRoughness = new glTFPbrMetallicRoughness(),
|
||||
};
|
||||
|
||||
dst.pbrMetallicRoughness.baseColorFactor = src.color.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
|
||||
var index = textureExporter.RegisterExportingAsSRgb(src.mainTexture, false);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
};
|
||||
GltfMaterialExportUtils.ExportTextureTransform(src.mainTextureOffset, src.mainTextureScale, dst.pbrMetallicRoughness.baseColorTexture);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c0269be076674f5988895ecd61b8d316
|
||||
timeCreated: 1722612454
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class UrpLitMaterialExporter
|
||||
{
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "Universal Render Pipeline/Lit" シェーダのマテリアルをエクスポートする。
|
||||
///
|
||||
/// プロパティに互換性がある他のシェーダを指定することもできる。
|
||||
/// </summary>
|
||||
public UrpLitMaterialExporter(Shader shader = null)
|
||||
{
|
||||
Shader = shader != null ? shader : Shader.Find("Universal Render Pipeline/Lit");
|
||||
}
|
||||
|
||||
public bool TryExportMaterial(Material src, ITextureExporter textureExporter, out glTFMaterial dst)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (src == null) throw new ArgumentNullException(nameof(src));
|
||||
if (textureExporter == null) throw new ArgumentNullException(nameof(textureExporter));
|
||||
if (src.shader != Shader || Shader == null) throw new UniGLTFShaderNotMatchedInternalException(src.shader);
|
||||
|
||||
dst = new glTFMaterial
|
||||
{
|
||||
name = src.name,
|
||||
pbrMetallicRoughness = new glTFPbrMetallicRoughness(),
|
||||
};
|
||||
|
||||
var context = new UrpLitContext(src);
|
||||
foreach (var validation in EnumerateValidation(context))
|
||||
{
|
||||
if (!validation.CanExport)
|
||||
{
|
||||
Debug.LogError(validation.Message, src);
|
||||
throw new UniGLTFNotSupportedException(validation.Message);
|
||||
}
|
||||
}
|
||||
|
||||
ExportSurfaceSettings(context, dst, textureExporter);
|
||||
ExportBaseColor(context, dst, textureExporter);
|
||||
ExportMetallicSmoothness(context, dst, textureExporter);
|
||||
ExportOcclusion(context, dst, textureExporter);
|
||||
ExportNormal(context, dst, textureExporter);
|
||||
ExportEmission(context, dst, textureExporter);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (UniGLTFShaderNotMatchedInternalException)
|
||||
{
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportSurfaceSettings(UrpBaseShaderContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
dst.alphaMode = (context.SurfaceType, context.IsAlphaClipEnabled) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, false) => glTFBlendMode.OPAQUE.ToString(),
|
||||
(UrpLitSurfaceType.Opaque, true) => glTFBlendMode.MASK.ToString(),
|
||||
(UrpLitSurfaceType.Transparent, false) => glTFBlendMode.BLEND.ToString(),
|
||||
(UrpLitSurfaceType.Transparent, true) => glTFBlendMode.BLEND.ToString(), // NOTE: not supported in glTF
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
dst.alphaCutoff = context.Cutoff;
|
||||
dst.doubleSided = context.CullMode != CullMode.Back; // NOTE: cull front not supported in glTF
|
||||
}
|
||||
|
||||
public static void ExportBaseColor(UrpBaseShaderContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
dst.pbrMetallicRoughness.baseColorFactor = context.BaseColorSrgb.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
|
||||
if (context.BaseTexture != null)
|
||||
{
|
||||
var needsAlpha = context.SurfaceType != UrpLitSurfaceType.Opaque;
|
||||
var index = textureExporter.RegisterExportingAsSRgb(context.BaseTexture, needsAlpha);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
};
|
||||
ExportBaseTexTransform(context, dst.pbrMetallicRoughness.baseColorTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportMetallicSmoothness(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
// NOTE: maybe KHR_materials_specular
|
||||
if (context.WorkflowType != UrpLitWorkflowType.Metallic) return;
|
||||
|
||||
// Metallic-Roughness
|
||||
dst.pbrMetallicRoughness.metallicRoughnessTexture = null;
|
||||
dst.pbrMetallicRoughness.metallicFactor = context.Metallic;
|
||||
dst.pbrMetallicRoughness.roughnessFactor = 1.0f - context.Smoothness;
|
||||
if (context.MetallicGlossMap != null)
|
||||
{
|
||||
var index = textureExporter.RegisterExportingAsCombinedGltfPbrParameterTextureFromUnityStandardTextures(
|
||||
context.MetallicGlossMap,
|
||||
context.Smoothness,
|
||||
context.OcclusionTexture
|
||||
);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.pbrMetallicRoughness.metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
};
|
||||
ExportBaseTexTransform(context, dst.pbrMetallicRoughness.metallicRoughnessTexture);
|
||||
dst.pbrMetallicRoughness.metallicFactor = 1.0f;
|
||||
dst.pbrMetallicRoughness.roughnessFactor = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ExportOcclusion(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
if (context.WorkflowType != UrpLitWorkflowType.Metallic) return;
|
||||
|
||||
// Occlusion
|
||||
if (context.OcclusionTexture != null)
|
||||
{
|
||||
var index = textureExporter.RegisterExportingAsCombinedGltfPbrParameterTextureFromUnityStandardTextures(
|
||||
context.MetallicGlossMap,
|
||||
context.Smoothness,
|
||||
context.OcclusionTexture
|
||||
);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.occlusionTexture = new glTFMaterialOcclusionTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
strength = context.OcclusionStrength,
|
||||
};
|
||||
ExportBaseTexTransform(context, dst.occlusionTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ExportNormal(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
if (context.BumpMap == null) return;
|
||||
|
||||
var index = textureExporter.RegisterExportingAsNormal(context.BumpMap);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.normalTexture = new glTFMaterialNormalTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
scale = context.BumpScale,
|
||||
};
|
||||
ExportBaseTexTransform(context, dst.normalTexture);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExportEmission(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
if (!context.IsEmissionEnabled) return;
|
||||
|
||||
dst.emissiveFactor = context.EmissionColorLinear.ToFloat3(ColorSpace.Linear, ColorSpace.Linear);
|
||||
if (context.EmissionTexture != null)
|
||||
{
|
||||
var index = textureExporter.RegisterExportingAsSRgb(context.EmissionTexture, true);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.emissiveTexture = new glTFMaterialEmissiveTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
};
|
||||
ExportBaseTexTransform(context, dst.emissiveTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExportBaseTexTransform(UrpBaseShaderContext context, glTFTextureInfo dst)
|
||||
{
|
||||
GltfMaterialExportUtils.ExportTextureTransform(
|
||||
context.BaseTextureOffset,
|
||||
context.BaseTextureScale,
|
||||
dst
|
||||
);
|
||||
}
|
||||
|
||||
public static IEnumerable<Validation> EnumerateValidation(UrpLitContext context)
|
||||
{
|
||||
var validationContext = ValidationContext.Create(context.Material);
|
||||
|
||||
// Surface Settings
|
||||
if (context.WorkflowType != UrpLitWorkflowType.Metallic) yield return Error(ValidationMessage.WorkflowTypeNotSupported);
|
||||
if (context.SurfaceType == UrpLitSurfaceType.Transparent && context.IsAlphaClipEnabled) yield return Warning(ValidationMessage.TransparentAlphaClipNotSupported);
|
||||
if (context.CullMode == CullMode.Front) yield return Error(ValidationMessage.BackFaceRenderingNotSupported);
|
||||
if (context.BlendMode == UrpLitBlendMode.Additive) yield return Error(ValidationMessage.AdditiveBlendModeNotSupported);
|
||||
if (context.BlendMode == UrpLitBlendMode.Multiply) yield return Error(ValidationMessage.MultiplyBlendModeNotSupported);
|
||||
|
||||
// Etc Textures
|
||||
if (context.ParallaxTexture != null) yield return Warning(ValidationMessage.ParallaxTextureNotSupported);
|
||||
|
||||
yield break;
|
||||
|
||||
Validation Error(ValidationMessage message)
|
||||
{
|
||||
return Validation.Error(message.ToString(), validationContext);
|
||||
}
|
||||
|
||||
Validation Warning(ValidationMessage message)
|
||||
{
|
||||
return Validation.Warning(message.ToString(), validationContext);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ValidationMessage
|
||||
{
|
||||
WorkflowTypeNotSupported,
|
||||
TransparentAlphaClipNotSupported,
|
||||
BackFaceRenderingNotSupported,
|
||||
ParallaxTextureNotSupported,
|
||||
AdditiveBlendModeNotSupported,
|
||||
MultiplyBlendModeNotSupported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8832f807c30a420d95aeaee15a1fbff7
|
||||
timeCreated: 1722269933
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using UniGLTF.UniUnlit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class UrpUniUnlitMaterialExporter
|
||||
{
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "UniGLTF/UniUnlit" シェーダのマテリアルをエクスポートする。
|
||||
///
|
||||
/// プロパティに互換性がある他のシェーダを指定することもできる。
|
||||
/// </summary>
|
||||
public UrpUniUnlitMaterialExporter(Shader shader = null)
|
||||
{
|
||||
Shader = shader != null ? shader : Shader.Find("UniGLTF/UniUnlit");
|
||||
}
|
||||
|
||||
public bool TryExportMaterial(Material src, ITextureExporter textureExporter, out glTFMaterial dst)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (src == null) throw new ArgumentNullException(nameof(src));
|
||||
if (textureExporter == null) throw new ArgumentNullException(nameof(textureExporter));
|
||||
if (src.shader != Shader || Shader == null) throw new UniGLTFShaderNotMatchedInternalException(src.shader);
|
||||
|
||||
dst = glTF_KHR_materials_unlit.CreateDefault();
|
||||
dst.name = src.name;
|
||||
|
||||
var context = new UniUnlitContext(src);
|
||||
|
||||
dst.alphaMode = context.RenderMode switch
|
||||
{
|
||||
UniUnlitRenderMode.Opaque => glTFBlendMode.OPAQUE.ToString(),
|
||||
UniUnlitRenderMode.Cutout => glTFBlendMode.MASK.ToString(),
|
||||
UniUnlitRenderMode.Transparent => glTFBlendMode.BLEND.ToString(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
dst.alphaCutoff = context.Cutoff;
|
||||
dst.doubleSided = context.CullMode != UniUnlitCullMode.Back;
|
||||
|
||||
dst.pbrMetallicRoughness.baseColorFactor = context.MainColorSrgb
|
||||
.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
|
||||
if (context.MainTexture != null)
|
||||
{
|
||||
var needsAlpha = context.RenderMode != UniUnlitRenderMode.Opaque;
|
||||
var index = textureExporter.RegisterExportingAsSRgb(context.MainTexture, needsAlpha);
|
||||
if (index >= 0)
|
||||
{
|
||||
dst.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = index,
|
||||
texCoord = 0,
|
||||
};
|
||||
GltfMaterialExportUtils.ExportTextureTransform(
|
||||
context.MainTextureOffset,
|
||||
context.MainTextureScale,
|
||||
dst.pbrMetallicRoughness.baseColorTexture);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (UniGLTFShaderNotMatchedInternalException)
|
||||
{
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5b17f3928c684fc1a9beda10797b0e76
|
||||
timeCreated: 1722613258
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class UrpUnlitMaterialExporter
|
||||
{
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "Universal Render Pipeline/Unlit" シェーダのマテリアルをエクスポートする。
|
||||
///
|
||||
/// プロパティに互換性がある他のシェーダを指定することもできる。
|
||||
/// </summary>
|
||||
public UrpUnlitMaterialExporter(Shader shader = null)
|
||||
{
|
||||
Shader = shader != null ? shader : Shader.Find("Universal Render Pipeline/Unlit");
|
||||
}
|
||||
|
||||
public bool TryExportMaterial(Material src, ITextureExporter textureExporter, out glTFMaterial dst)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (src == null) throw new ArgumentNullException(nameof(src));
|
||||
if (textureExporter == null) throw new ArgumentNullException(nameof(textureExporter));
|
||||
if (src.shader != Shader || Shader == null) throw new UniGLTFShaderNotMatchedInternalException(src.shader);
|
||||
|
||||
dst = glTF_KHR_materials_unlit.CreateDefault();
|
||||
dst.name = src.name;
|
||||
|
||||
var context = new UrpUnlitContext(src);
|
||||
UrpLitMaterialExporter.ExportSurfaceSettings(context, dst, textureExporter);
|
||||
UrpLitMaterialExporter.ExportBaseColor(context, dst, textureExporter);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (UniGLTFShaderNotMatchedInternalException)
|
||||
{
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a90bb1e911744bbab916950324c70e52
|
||||
timeCreated: 1722614768
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class UrpGltfMaterialExporter : IMaterialExporter
|
||||
{
|
||||
public UrpLitMaterialExporter UrpLitExporter { get; set; } = new();
|
||||
public UrpUnlitMaterialExporter UrpUnlitExporter { get; set; } = new();
|
||||
public UrpUniUnlitMaterialExporter UrpUniUnlitExporter { get; set; } = new();
|
||||
public UrpFallbackMaterialExporter FallbackExporter { get; set; } = new();
|
||||
|
||||
public glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter, GltfExportSettings settings)
|
||||
{
|
||||
if (UrpLitExporter.TryExportMaterial(m, textureExporter, out var dst)) return dst;
|
||||
if (UrpUnlitExporter.TryExportMaterial(m, textureExporter, out dst)) return dst;
|
||||
if (UrpUniUnlitExporter.TryExportMaterial(m, textureExporter, out dst)) return dst;
|
||||
|
||||
Debug.Log($"Material `{m.name}` fallbacks.");
|
||||
return FallbackExporter.ExportMaterial(m, textureExporter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 943c27f3f6054f25b4c0bf7e4cd50eff
|
||||
timeCreated: 1722269861
|
||||
|
|
@ -1,27 +1,65 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate the descriptor of the glTF default material.
|
||||
///
|
||||
/// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#default-material
|
||||
/// </summary>
|
||||
public static class UrpGltfDefaultMaterialImporter
|
||||
public class UrpGltfDefaultMaterialImporter
|
||||
{
|
||||
public static MaterialDescriptor CreateParam()
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
public UrpGltfDefaultMaterialImporter(Shader shader = null)
|
||||
{
|
||||
Shader = shader != null ? shader : Shader.Find("Universal Render Pipeline/Lit");
|
||||
}
|
||||
|
||||
public MaterialDescriptor CreateParam(string materialName)
|
||||
{
|
||||
// FIXME
|
||||
return new MaterialDescriptor(
|
||||
"__default__",
|
||||
UrpGltfPbrMaterialImporter.Shader,
|
||||
default,
|
||||
string.IsNullOrEmpty(materialName) ? "__default__" : materialName,
|
||||
Shader,
|
||||
null,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new List<Action<Material>>()
|
||||
new List<Action<Material>> { GenerateDefaultMaterial }
|
||||
);
|
||||
}
|
||||
|
||||
public static void GenerateDefaultMaterial(Material dst)
|
||||
{
|
||||
var context = new UrpLitContext(dst);
|
||||
context.UnsafeEditMode = true;
|
||||
|
||||
context.SurfaceType = UrpLitSurfaceType.Opaque;
|
||||
context.IsAlphaClipEnabled = false;
|
||||
context.CullMode = CullMode.Back;
|
||||
|
||||
context.BaseColorSrgb = new Color(1, 1, 1, 1);
|
||||
context.BaseTexture = null;
|
||||
|
||||
context.WorkflowType = UrpLitWorkflowType.Metallic;
|
||||
context.SmoothnessTextureChannel = UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
|
||||
context.Metallic = 1f;
|
||||
context.Smoothness = 0f;
|
||||
context.MetallicGlossMap = null;
|
||||
|
||||
context.OcclusionTexture = null;
|
||||
|
||||
context.BumpMap = null;
|
||||
|
||||
context.IsEmissionEnabled = false;
|
||||
context.EmissionColorLinear = new Color(0, 0, 0, 0);
|
||||
context.EmissionTexture = null;
|
||||
|
||||
context.Validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
|
|
@ -9,26 +11,19 @@ namespace UniGLTF
|
|||
///
|
||||
/// 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 UrpGltfPbrMaterialImporter
|
||||
public class UrpGltfPbrMaterialImporter
|
||||
{
|
||||
public const string ShaderName = "Universal Render Pipeline/Lit";
|
||||
/// <summary>
|
||||
/// Universal Render Pipeline/Lit とプロパティやキーワードに互換があるカスタムシェーダに置換可能。
|
||||
/// </summary>
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
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 static Shader Shader => Shader.Find(ShaderName);
|
||||
|
||||
private enum BlendMode
|
||||
public UrpGltfPbrMaterialImporter(Shader shader = null)
|
||||
{
|
||||
Opaque,
|
||||
Cutout,
|
||||
Fade,
|
||||
Transparent
|
||||
Shader = shader != null ? shader : Shader.Find("Universal Render Pipeline/Lit");
|
||||
}
|
||||
|
||||
public static bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc)
|
||||
public bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc)
|
||||
{
|
||||
if (i < 0 || i >= data.GLTF.materials.Count)
|
||||
{
|
||||
|
|
@ -36,161 +31,142 @@ 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];
|
||||
|
||||
TextureDescriptor? standardTexDesc = default;
|
||||
if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)
|
||||
{
|
||||
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null)
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryStandardTexture(data, src, out var key, out var desc))
|
||||
{
|
||||
if (string.IsNullOrEmpty(desc.UnityObjectName))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
standardTexDesc = desc;
|
||||
}
|
||||
}
|
||||
|
||||
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
|
||||
{
|
||||
// from _Color !
|
||||
colors.Add("_BaseColor",
|
||||
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
|
||||
);
|
||||
}
|
||||
|
||||
if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryBaseColorTexture(data, src, out var key, out var desc))
|
||||
{
|
||||
// from _MainTex !
|
||||
textureSlots.Add("_BaseMap", desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1 && standardTexDesc.HasValue)
|
||||
{
|
||||
actions.Add(material => material.EnableKeyword("_METALLICSPECGLOSSMAP"));
|
||||
textureSlots.Add("_MetallicGlossMap", standardTexDesc.Value);
|
||||
// Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
|
||||
floatValues.Add("_Metallic", 1.0f);
|
||||
floatValues.Add("_GlossMapScale", 1.0f);
|
||||
// default value is 0.5 !
|
||||
floatValues.Add("_Smoothness", 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor);
|
||||
// from _Glossiness !
|
||||
floatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
|
||||
}
|
||||
}
|
||||
|
||||
if (src.normalTexture != null && src.normalTexture.index != -1)
|
||||
{
|
||||
actions.Add(material => material.EnableKeyword("_NORMALMAP"));
|
||||
if (GltfPbrTextureImporter.TryNormalTexture(data, src, out var key, out var desc))
|
||||
{
|
||||
textureSlots.Add("_BumpMap", desc);
|
||||
floatValues.Add("_BumpScale", src.normalTexture.scale);
|
||||
}
|
||||
}
|
||||
|
||||
if (src.occlusionTexture != null && src.occlusionTexture.index != -1 && standardTexDesc.HasValue)
|
||||
{
|
||||
textureSlots.Add("_OcclusionMap", standardTexDesc.Value);
|
||||
floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength);
|
||||
}
|
||||
|
||||
if (src.emissiveFactor != null
|
||||
|| (src.emissiveTexture != null && src.emissiveTexture.index != -1))
|
||||
{
|
||||
actions.Add(material =>
|
||||
{
|
||||
material.EnableKeyword("_EMISSION");
|
||||
material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
});
|
||||
|
||||
var emissiveFactor = GltfMaterialImportUtils.ImportLinearEmissiveFactor(data, src);
|
||||
if (emissiveFactor.HasValue)
|
||||
{
|
||||
colors.Add("_EmissionColor", emissiveFactor.Value);
|
||||
}
|
||||
|
||||
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryEmissiveTexture(data, src, out var key, out var desc))
|
||||
{
|
||||
textureSlots.Add("_EmissionMap", desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
matDesc = new MaterialDescriptor(
|
||||
GltfMaterialImportUtils.ImportMaterialName(i, src),
|
||||
Shader,
|
||||
null,
|
||||
textureSlots,
|
||||
floatValues,
|
||||
colors,
|
||||
vectors,
|
||||
actions);
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new List<Action<Material>>(),
|
||||
new [] { (MaterialDescriptor.MaterialGenerateAsyncFunc)AsyncAction }
|
||||
);
|
||||
return true;
|
||||
|
||||
Task AsyncAction(Material x, GetTextureAsyncFunc y, IAwaitCaller z) => GenerateMaterialAsync(data, src, x, y, z);
|
||||
}
|
||||
|
||||
public static async Task GenerateMaterialAsync(GltfData data, glTFMaterial src, Material dst, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
var context = new UrpLitContext(dst);
|
||||
context.UnsafeEditMode = true;
|
||||
|
||||
ImportSurfaceSettings(src, context);
|
||||
await ImportBaseColorAsync(data, src, context, getTextureAsync, awaitCaller);
|
||||
await ImportMetallicSmoothnessAsync(data, src, context, getTextureAsync, awaitCaller);
|
||||
await ImportOcclusionAsync(data, src, context, getTextureAsync, awaitCaller);
|
||||
await ImportNormalAsync(data, src, context, getTextureAsync, awaitCaller);
|
||||
await ImportEmissionAsync(data, src, context, getTextureAsync, awaitCaller);
|
||||
|
||||
context.Validate();
|
||||
}
|
||||
|
||||
public static void ImportSurfaceSettings(glTFMaterial src, UrpLitContext context)
|
||||
{
|
||||
context.SurfaceType = src.alphaMode switch
|
||||
{
|
||||
"OPAQUE" => UrpLitSurfaceType.Opaque,
|
||||
"MASK" => UrpLitSurfaceType.Transparent,
|
||||
"BLEND" => UrpLitSurfaceType.Transparent,
|
||||
_ => UrpLitSurfaceType.Opaque,
|
||||
};
|
||||
context.BlendMode = context.SurfaceType switch
|
||||
{
|
||||
UrpLitSurfaceType.Transparent => UrpLitBlendMode.Alpha,
|
||||
_ => UrpLitBlendMode.Alpha,
|
||||
};
|
||||
context.IsAlphaClipEnabled = src.alphaMode switch
|
||||
{
|
||||
"MASK" => true,
|
||||
_ => false,
|
||||
};
|
||||
context.Cutoff = src.alphaCutoff;
|
||||
context.CullMode = src.doubleSided ? CullMode.Off : CullMode.Back;
|
||||
}
|
||||
|
||||
public static async Task ImportBaseColorAsync(GltfData data, glTFMaterial src, UrpLitContext context, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
var baseColorFactor = GltfMaterialImportUtils.ImportLinearBaseColorFactor(data, src);
|
||||
if (baseColorFactor.HasValue)
|
||||
{
|
||||
context.BaseColorSrgb = baseColorFactor.Value.gamma;
|
||||
}
|
||||
|
||||
if (src is { pbrMetallicRoughness: { baseColorTexture: { index: >= 0 } } })
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryBaseColorTexture(data, src, out _, out var desc))
|
||||
{
|
||||
context.BaseTexture = await getTextureAsync(desc, awaitCaller);
|
||||
context.BaseTextureOffset = desc.Offset;
|
||||
context.BaseTextureScale = desc.Scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task ImportMetallicSmoothnessAsync(GltfData data, glTFMaterial src, UrpLitContext context, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
context.WorkflowType = UrpLitWorkflowType.Metallic;
|
||||
context.SmoothnessTextureChannel = UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
|
||||
context.Metallic = src.pbrMetallicRoughness.metallicFactor;
|
||||
context.Smoothness = 1.0f - src.pbrMetallicRoughness.roughnessFactor;
|
||||
|
||||
if (src is { pbrMetallicRoughness: { metallicRoughnessTexture: { index: >= 0 } } })
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryStandardTexture(data, src, out _, out var desc))
|
||||
{
|
||||
context.MetallicGlossMap = await getTextureAsync(desc, awaitCaller);
|
||||
context.Metallic = 1;
|
||||
context.Smoothness = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task ImportOcclusionAsync(GltfData data, glTFMaterial src, UrpLitContext context, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
if (src is { occlusionTexture: { index: >= 0 } })
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryStandardTexture(data, src, out _, out var desc))
|
||||
{
|
||||
context.OcclusionTexture = await getTextureAsync(desc, awaitCaller);
|
||||
context.OcclusionStrength = src.occlusionTexture.strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ImportNormalAsync(GltfData data, glTFMaterial src, UrpLitContext context, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
if (src.normalTexture is { index: >= 0 })
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryNormalTexture(data, src, out _, out var desc))
|
||||
{
|
||||
context.BumpMap = await getTextureAsync(desc, awaitCaller);
|
||||
context.BumpScale = src.normalTexture.scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ImportEmissionAsync(GltfData data, glTFMaterial src, UrpLitContext context, GetTextureAsyncFunc getTextureAsync, IAwaitCaller awaitCaller)
|
||||
{
|
||||
var emissiveFactor = GltfMaterialImportUtils.ImportLinearEmissiveFactor(data, src);
|
||||
if (emissiveFactor.HasValue)
|
||||
{
|
||||
context.EmissionColorLinear = emissiveFactor.Value;
|
||||
}
|
||||
|
||||
if (src is { emissiveTexture: { index: >= 0 } })
|
||||
{
|
||||
if (GltfPbrTextureImporter.TryEmissiveTexture(data, src, out _, out var desc))
|
||||
{
|
||||
context.EmissionTexture = await getTextureAsync(desc, awaitCaller);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.EmissionColorLinear is {maxColorComponent: > 0} || context.EmissionTexture != null)
|
||||
{
|
||||
context.IsEmissionEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -10,30 +7,22 @@ namespace UniGLTF
|
|||
/// </summary>
|
||||
public sealed class UrpGltfMaterialDescriptorGenerator : IMaterialDescriptorGenerator
|
||||
{
|
||||
public UrpGltfPbrMaterialImporter PbrMaterialImporter { get; } = new();
|
||||
public UrpGltfDefaultMaterialImporter DefaultMaterialImporter { get; } = new();
|
||||
|
||||
public MaterialDescriptor Get(GltfData data, int i)
|
||||
{
|
||||
if (BuiltInGltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param;
|
||||
if (UrpGltfPbrMaterialImporter.TryCreateParam(data, i, out param)) return param;
|
||||
// fallback
|
||||
if (PbrMaterialImporter.TryCreateParam(data, i, out param)) return param;
|
||||
|
||||
// NOTE: Fallback to default material
|
||||
if (Symbols.VRM_DEVELOP)
|
||||
{
|
||||
Debug.LogWarning($"material: {i} out of range. fallback");
|
||||
}
|
||||
|
||||
return new MaterialDescriptor(
|
||||
GltfMaterialImportUtils.ImportMaterialName(i, null),
|
||||
UrpGltfPbrMaterialImporter.Shader,
|
||||
null,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new Collection<Action<Material>>());
|
||||
return GetGltfDefault(GltfMaterialImportUtils.ImportMaterialName(i, null));
|
||||
}
|
||||
|
||||
public MaterialDescriptor GetGltfDefault()
|
||||
{
|
||||
return UrpGltfDefaultMaterialImporter.CreateParam();
|
||||
}
|
||||
public MaterialDescriptor GetGltfDefault(string materialName = null) => DefaultMaterialImporter.CreateParam(materialName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4a35a0639a7f4eb4b2c5fb8225803ce3
|
||||
timeCreated: 1722270899
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2100c40775e3446bb05f63f32820930a
|
||||
timeCreated: 1722270911
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public abstract class UrpBaseShaderContext
|
||||
{
|
||||
private static readonly int Surface = Shader.PropertyToID("_Surface");
|
||||
private static readonly int AlphaClip = Shader.PropertyToID("_AlphaClip");
|
||||
private static readonly int Blend = Shader.PropertyToID("_Blend");
|
||||
private static readonly int Cull = Shader.PropertyToID("_Cull");
|
||||
private static readonly int BaseColorProp = Shader.PropertyToID("_BaseColor");
|
||||
private static readonly int BaseMap = Shader.PropertyToID("_BaseMap");
|
||||
private static readonly int CutoffProp = Shader.PropertyToID("_Cutoff");
|
||||
private static readonly int ZWrite = Shader.PropertyToID("_ZWrite");
|
||||
private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend");
|
||||
private static readonly int DstBlend = Shader.PropertyToID("_DstBlend");
|
||||
private static readonly string SurfaceTypeTransparentKeyword = "_SURFACE_TYPE_TRANSPARENT";
|
||||
private static readonly string AlphaTestOnKeyword = "_ALPHATEST_ON";
|
||||
private static readonly string AlphaPremultiplyOnKeyword = "_ALPHAPREMULTIPLY_ON";
|
||||
private static readonly string AlphaModulateOnKeyword = "_ALPHAMODULATE_ON";
|
||||
|
||||
protected UrpBaseShaderContext(Material material)
|
||||
{
|
||||
Material = material;
|
||||
}
|
||||
|
||||
public Material Material { get; }
|
||||
|
||||
/// <summary>
|
||||
/// これが有効な場合、Validate() 関数が呼ばれるべき場合でも自動的に呼ばれなくなります。
|
||||
///
|
||||
/// 処理最適化目的で使用できます。
|
||||
/// </summary>
|
||||
public bool UnsafeEditMode { get; set; } = false;
|
||||
|
||||
public UrpLitSurfaceType SurfaceType
|
||||
{
|
||||
get => (UrpLitSurfaceType)Material.GetFloat(Surface);
|
||||
set
|
||||
{
|
||||
Material.SetFloat(Surface, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public UrpLitBlendMode BlendMode
|
||||
{
|
||||
get => (UrpLitBlendMode)Material.GetFloat(Blend);
|
||||
set
|
||||
{
|
||||
Material.SetFloat(Blend, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAlphaClipEnabled
|
||||
{
|
||||
get => Material.GetFloat(AlphaClip) >= 0.5f;
|
||||
set
|
||||
{
|
||||
Material.SetFloat(AlphaClip, value ? 1.0f : 0.0f);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public CullMode CullMode
|
||||
{
|
||||
get => (CullMode)Material.GetFloat(Cull);
|
||||
set
|
||||
{
|
||||
Material.SetFloat(Cull, (float)value);
|
||||
Material.doubleSidedGI = value != CullMode.Back;
|
||||
}
|
||||
}
|
||||
|
||||
public Color BaseColorSrgb
|
||||
{
|
||||
get => Material.GetColor(BaseColorProp);
|
||||
set => Material.SetColor(BaseColorProp, value);
|
||||
}
|
||||
|
||||
public Texture BaseTexture
|
||||
{
|
||||
get => Material.GetTexture(BaseMap);
|
||||
set => Material.SetTexture(BaseMap, value);
|
||||
}
|
||||
|
||||
public Vector2 BaseTextureOffset
|
||||
{
|
||||
get => Material.GetTextureOffset(BaseMap);
|
||||
set => Material.SetTextureOffset(BaseMap, value);
|
||||
}
|
||||
|
||||
public Vector2 BaseTextureScale
|
||||
{
|
||||
get => Material.GetTextureScale(BaseMap);
|
||||
set => Material.SetTextureScale(BaseMap, value);
|
||||
}
|
||||
|
||||
public float Cutoff
|
||||
{
|
||||
get => Material.GetFloat(CutoffProp);
|
||||
set => Material.SetFloat(CutoffProp, value);
|
||||
}
|
||||
|
||||
|
||||
public virtual void Validate()
|
||||
{
|
||||
// Surface Type
|
||||
var surfaceType = (UrpLitSurfaceType)Material.GetFloat(Surface);
|
||||
Material.SetKeyword(SurfaceTypeTransparentKeyword, surfaceType != UrpLitSurfaceType.Opaque);
|
||||
|
||||
// Alpha Clip
|
||||
var alphaClip = Material.GetFloat(AlphaClip) >= 0.5f;
|
||||
Material.SetKeyword(AlphaTestOnKeyword, alphaClip);
|
||||
|
||||
// Blend Mode
|
||||
var blendMode = (UrpLitBlendMode)Material.GetFloat(Blend);
|
||||
Material.SetKeyword(AlphaPremultiplyOnKeyword, blendMode == UrpLitBlendMode.Premultiply);
|
||||
Material.SetKeyword(AlphaModulateOnKeyword, blendMode == UrpLitBlendMode.Additive);
|
||||
|
||||
// ZWrite
|
||||
var zWrite = surfaceType == UrpLitSurfaceType.Opaque;
|
||||
Material.SetFloat(ZWrite, zWrite ? 1.0f : 0.0f);
|
||||
Material.SetShaderPassEnabled("DepthOnly", zWrite);
|
||||
|
||||
// Render Settings
|
||||
Material.SetFloat(SrcBlend, (surfaceType, blendMode) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, _) => (float)UnityEngine.Rendering.BlendMode.One,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Alpha) => (float)UnityEngine.Rendering.BlendMode.SrcAlpha,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Premultiply) => (float)UnityEngine.Rendering.BlendMode.One,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Additive) => (float)UnityEngine.Rendering.BlendMode.One,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Multiply) => (float)UnityEngine.Rendering.BlendMode.DstColor,
|
||||
_ => (float)UnityEngine.Rendering.BlendMode.One,
|
||||
});
|
||||
Material.SetFloat(DstBlend, (surfaceType, blendMode) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, _) => (float)UnityEngine.Rendering.BlendMode.Zero,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Alpha) => (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Premultiply) => (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Additive) => (float)UnityEngine.Rendering.BlendMode.One,
|
||||
(UrpLitSurfaceType.Transparent, UrpLitBlendMode.Multiply) => (float)UnityEngine.Rendering.BlendMode.Zero,
|
||||
_ => (float) UnityEngine.Rendering.BlendMode.Zero,
|
||||
});
|
||||
Material.SetOverrideTag("RenderType", (surfaceType, alphaClip) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, false) => "Opaque",
|
||||
(UrpLitSurfaceType.Opaque, true) => "TransparentCutout",
|
||||
(UrpLitSurfaceType.Transparent, _) => "Transparent",
|
||||
_ => "Opaque",
|
||||
});
|
||||
Material.renderQueue = (surfaceType, alphaClip) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, false) => (int)RenderQueue.Geometry,
|
||||
(UrpLitSurfaceType.Opaque, true) => (int)RenderQueue.AlphaTest,
|
||||
(UrpLitSurfaceType.Transparent, _) => (int)RenderQueue.Transparent,
|
||||
_ => Material.shader.renderQueue,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0a218f533e64925a87626ce8129f264
|
||||
timeCreated: 1722615731
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public enum UrpLitBlendMode
|
||||
{
|
||||
Alpha = 0,
|
||||
Premultiply = 1,
|
||||
Additive = 2,
|
||||
Multiply = 3,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 307c409e09f74fed8caaaedfdf794ef9
|
||||
timeCreated: 1722351228
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// "Universal Render Pipeline/Lit" シェーダーのプロパティを操作するためのクラス
|
||||
///
|
||||
/// glTF との読み書きに必要な機能だけ実装する
|
||||
///
|
||||
/// 非対応項目
|
||||
/// - Detail Texture
|
||||
/// - Specular Highlights Toggle
|
||||
/// - Environment Reflections Toggle
|
||||
/// - Sorting Priority
|
||||
/// </summary>
|
||||
public class UrpLitContext : UrpBaseShaderContext
|
||||
{
|
||||
private static readonly int WorkflowMode = Shader.PropertyToID("_WorkflowMode");
|
||||
private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor");
|
||||
private static readonly int EmissionMap = Shader.PropertyToID("_EmissionMap");
|
||||
private static readonly int OcclusionMap = Shader.PropertyToID("_OcclusionMap");
|
||||
private static readonly int ParallaxMap = Shader.PropertyToID("_ParallaxMap");
|
||||
private static readonly int SmoothnessProp = Shader.PropertyToID("_Smoothness");
|
||||
private static readonly int SmoothnessTextureChannelProp = Shader.PropertyToID("_SmoothnessTextureChannel");
|
||||
private static readonly int MetallicProp = Shader.PropertyToID("_Metallic");
|
||||
private static readonly int MetallicGlossMapProp = Shader.PropertyToID("_MetallicGlossMap");
|
||||
private static readonly int SpecColorProp = Shader.PropertyToID("_SpecColor");
|
||||
private static readonly int SpecGlossMapProp = Shader.PropertyToID("_SpecGlossMap");
|
||||
private static readonly int BumpScaleProp = Shader.PropertyToID("_BumpScale");
|
||||
private static readonly int BumpMapProp = Shader.PropertyToID("_BumpMap");
|
||||
|
||||
private static readonly string SpecularSetupKeyword = "_SPECULAR_SETUP";
|
||||
private static readonly string MetallicSpecGlossMapKeyword = "_METALLICSPECGLOSSMAP";
|
||||
private static readonly string SmoothnessTextureAlbedoChannelAKeyword = "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A";
|
||||
private static readonly string NormalMapKeyword = "_NORMALMAP";
|
||||
private static readonly string EmissionKeyword = "_EMISSION";
|
||||
private static readonly string OcclusionMapKeyword = "_OCCLUSIONMAP";
|
||||
private static readonly string ParallaxMapKeyword = "_PARALLAXMAP";
|
||||
private static readonly int OcclusionStrengthProp = Shader.PropertyToID("_OcclusionStrength");
|
||||
private static readonly int ParallaxProp = Shader.PropertyToID("_Parallax");
|
||||
|
||||
public UrpLitContext(Material material) : base(material)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UrpLitWorkflowType WorkflowType
|
||||
{
|
||||
get => (UrpLitWorkflowType)Material.GetFloat(WorkflowMode);
|
||||
set
|
||||
{
|
||||
Material.SetFloat(WorkflowMode, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public float Smoothness
|
||||
{
|
||||
get => Material.GetFloat(SmoothnessProp);
|
||||
set => Material.SetFloat(SmoothnessProp, value);
|
||||
}
|
||||
|
||||
public UrpLitSmoothnessMapChannel SmoothnessTextureChannel
|
||||
{
|
||||
// NOTE: Float Prop 以外に条件があるので、Keyword から読み取った方が確実
|
||||
get => Material.IsKeywordEnabled(SmoothnessTextureAlbedoChannelAKeyword) ? UrpLitSmoothnessMapChannel.AlbedoAlpha : UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
|
||||
set
|
||||
{
|
||||
Material.SetFloat(SmoothnessTextureChannelProp, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public float Metallic
|
||||
{
|
||||
// NOTE: Metallic ワークフロー専用
|
||||
get => Material.GetFloat(MetallicProp);
|
||||
set => Material.SetFloat(MetallicProp, value);
|
||||
}
|
||||
|
||||
public Texture MetallicGlossMap
|
||||
{
|
||||
// NOTE: Metallic ワークフロー専用
|
||||
get => Material.GetTexture(MetallicGlossMapProp);
|
||||
set => Material.SetTexture(MetallicGlossMapProp, value);
|
||||
}
|
||||
|
||||
public Color SpecColorSrgb
|
||||
{
|
||||
// NOTE: Specular ワークフロー専用
|
||||
get => Material.GetColor(SpecColorProp);
|
||||
set => Material.SetColor(SpecColorProp, value);
|
||||
}
|
||||
|
||||
public Texture SpecGlossMap
|
||||
{
|
||||
// NOTE: Specular ワークフロー専用
|
||||
get => Material.GetTexture(SpecGlossMapProp);
|
||||
set => Material.SetTexture(SpecGlossMapProp, value);
|
||||
}
|
||||
|
||||
public float BumpScale
|
||||
{
|
||||
get => Material.GetFloat(BumpScaleProp);
|
||||
set => Material.SetFloat(BumpScaleProp, value);
|
||||
}
|
||||
|
||||
public Texture BumpMap
|
||||
{
|
||||
get => Material.GetTexture(BumpMapProp);
|
||||
set
|
||||
{
|
||||
Material.SetTexture(BumpMapProp, value);
|
||||
Material.SetKeyword(NormalMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmissionEnabled
|
||||
{
|
||||
get => Material.IsKeywordEnabled(EmissionKeyword);
|
||||
set
|
||||
{
|
||||
Material.SetKeyword(EmissionKeyword, value);
|
||||
if (value)
|
||||
{
|
||||
Material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
}
|
||||
else
|
||||
{
|
||||
Material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Color EmissionColorLinear
|
||||
{
|
||||
get => Material.GetColor(EmissionColor);
|
||||
set => Material.SetColor(EmissionColor, value);
|
||||
}
|
||||
|
||||
public Texture EmissionTexture
|
||||
{
|
||||
get => Material.GetTexture(EmissionMap);
|
||||
set => Material.SetTexture(EmissionMap, value);
|
||||
}
|
||||
|
||||
public float OcclusionStrength
|
||||
{
|
||||
get => Material.GetFloat(OcclusionStrengthProp);
|
||||
set => Material.SetFloat(OcclusionStrengthProp, value);
|
||||
}
|
||||
|
||||
public Texture OcclusionTexture
|
||||
{
|
||||
get => Material.GetTexture(OcclusionMap);
|
||||
set
|
||||
{
|
||||
Material.SetTexture(OcclusionMap, value);
|
||||
Material.SetKeyword(OcclusionMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
public float Parallax
|
||||
{
|
||||
get => Material.GetFloat(ParallaxProp);
|
||||
set => Material.SetFloat(ParallaxProp, value);
|
||||
}
|
||||
|
||||
public Texture ParallaxTexture
|
||||
{
|
||||
get => Material.GetTexture(ParallaxMap);
|
||||
set
|
||||
{
|
||||
Material.SetTexture(ParallaxMap, value);
|
||||
Material.SetKeyword(ParallaxMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 複数のプロパティに関連して設定されるキーワードやプロパティなどを更新する
|
||||
/// </summary>
|
||||
public override void Validate()
|
||||
{
|
||||
base.Validate();
|
||||
|
||||
// Workflow
|
||||
var workflowType = (UrpLitWorkflowType)Material.GetFloat(WorkflowMode);
|
||||
var isSpecularSetup = workflowType == UrpLitWorkflowType.Specular;
|
||||
Material.SetKeyword(SpecularSetupKeyword, isSpecularSetup);
|
||||
|
||||
// GlossMap
|
||||
var glossMapName = isSpecularSetup ? SpecGlossMapProp : MetallicGlossMapProp;
|
||||
var hasGlossMap = Material.GetTexture(glossMapName) != null;
|
||||
Material.SetKeyword(MetallicSpecGlossMapKeyword, hasGlossMap);
|
||||
|
||||
// SmoothnessTextureChannel
|
||||
var isOpaque = SurfaceType == UrpLitSurfaceType.Opaque;
|
||||
var smoothnessMapChannel = (UrpLitSmoothnessMapChannel)Material.GetFloat(SmoothnessTextureChannelProp);
|
||||
Material.SetKeyword(SmoothnessTextureAlbedoChannelAKeyword, isOpaque && smoothnessMapChannel == UrpLitSmoothnessMapChannel.AlbedoAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c15ac3fb36ff4e7d8ec271e2cf1fb263
|
||||
timeCreated: 1722270619
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public enum UrpLitSmoothnessMapChannel
|
||||
{
|
||||
SpecularMetallicAlpha = 0,
|
||||
AlbedoAlpha = 1,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5669057b7c2d45de9167a335f222c61d
|
||||
timeCreated: 1722344104
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public enum UrpLitSurfaceType
|
||||
{
|
||||
Opaque = 0,
|
||||
Transparent = 1,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 404bf44062364d41a91735181e6ead33
|
||||
timeCreated: 1722270974
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public enum UrpLitWorkflowType
|
||||
{
|
||||
Specular = 0,
|
||||
Metallic = 1,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a76aba2bef494654948abea5eef21fac
|
||||
timeCreated: 1722271263
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class UrpUnlitContext : UrpBaseShaderContext
|
||||
{
|
||||
public UrpUnlitContext(Material material) : base(material)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3fe15309261045ba937d6a8dafb6a93d
|
||||
timeCreated: 1722616677
|
||||
3
Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/Utils.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f0ed4e9ca99a4447896accb69a065c2e
|
||||
timeCreated: 1722343812
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
internal static class InternalMaterialUtils
|
||||
{
|
||||
public static void SetKeyword(this Material material, string keyword, bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
material.EnableKeyword(keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
material.DisableKeyword(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc1b44f784074898b268882d75b86e23
|
||||
timeCreated: 1722343798
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
internal class UniGLTFShaderNotMatchedInternalException : UniGLTFException
|
||||
{
|
||||
public UniGLTFShaderNotMatchedInternalException(Shader shader) : base(shader != null ? shader.name : "") { }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7857ff1b8d15440f9886f293a747ebb1
|
||||
timeCreated: 1722617046
|
||||
|
|
@ -4,8 +4,8 @@ namespace UniGLTF
|
|||
public static partial class PackageVersion
|
||||
{
|
||||
public const int MAJOR = 0;
|
||||
public const int MINOR = 124;
|
||||
public const int PATCH = 2;
|
||||
public const string VERSION = "0.124.2";
|
||||
public const int MINOR = 125;
|
||||
public const int PATCH = 0;
|
||||
public const string VERSION = "0.125.0";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ namespace UniGLTF
|
|||
public static partial class UniGLTFVersion
|
||||
{
|
||||
public const int MAJOR = 2;
|
||||
public const int MINOR = 60;
|
||||
public const int PATCH = 2;
|
||||
public const string VERSION = "2.60.2";
|
||||
public const int MINOR = 61;
|
||||
public const int PATCH = 0;
|
||||
public const string VERSION = "2.61.0";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ namespace UniGLTF
|
|||
}
|
||||
|
||||
[System.Diagnostics.Conditional("VRM_DEVELOP")]
|
||||
#if UNITY_2022_OR_NEWER
|
||||
[HideInCallstack]
|
||||
#endif
|
||||
public static void Log(string msg, UnityEngine.Object context = null) => s_logger.LogFormat(LogType.Log, context, msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ namespace UniGLTF.GltfViewer
|
|||
LoadPathAsync(path);
|
||||
}
|
||||
|
||||
async void LoadPathAsync(VRMShaders.PathObject path)
|
||||
async void LoadPathAsync(PathObject path)
|
||||
{
|
||||
if (_instance)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ namespace UniGLTF.GltfViewer
|
|||
{
|
||||
public static class OpenFileDialog
|
||||
{
|
||||
public static VRMShaders.PathObject Show(string title, params string[] extensions)
|
||||
public static PathObject Show(string title, params string[] extensions)
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
return VRMShaders.PathObject.FromFullPath(FileDialogForWindows.FileDialog(title, extensions));
|
||||
return PathObject.FromFullPath(FileDialogForWindows.FileDialog(title, extensions));
|
||||
#else
|
||||
UnityEngine.Debug.LogWarning("Non-Windows runtime file dialogs are not yet implemented.");
|
||||
return default;
|
||||
|
|
|
|||
|
|
@ -119,7 +119,11 @@ namespace UniHumanoid
|
|||
builder.AddLeg(0.1f, 0.3f, 0.4f, 0.1f, 0.1f);
|
||||
|
||||
var description = AvatarDescription.Create(builder.Skeleton);
|
||||
var animator = GetComponentOrThrow<Animator>();
|
||||
var animator = GetComponent<Animator>();
|
||||
if (animator == null)
|
||||
{
|
||||
throw new System.ArgumentException("no animator");
|
||||
}
|
||||
animator.avatar = description.CreateAvatar(root);
|
||||
|
||||
// create SkinnedMesh for bone visualize
|
||||
|
|
@ -132,7 +136,8 @@ namespace UniHumanoid
|
|||
renderer.sharedMaterial = m_material;
|
||||
//root.gameObject.AddComponent<BoneMapping>();
|
||||
|
||||
if (TryGetComponent<HumanPoseTransfer>(out var transfer))
|
||||
var transfer = GetComponent<HumanPoseTransfer>();
|
||||
if (transfer != null)
|
||||
{
|
||||
transfer.Avatar = animator.avatar;
|
||||
transfer.Setup();
|
||||
|
|
|
|||
8
Assets/UniGLTF/Tests/Objects.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 257f9efac603801459934018928760de
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 79 B After Width: | Height: | Size: 79 B |
|
|
@ -3,7 +3,7 @@ guid: fc1ba24d4a4141d4d9e9ae0a0d3ecd0a
|
|||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
|
@ -24,6 +24,7 @@ TextureImporter:
|
|||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
|
@ -62,6 +63,7 @@ TextureImporter:
|
|||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
|
|
@ -99,6 +101,18 @@ TextureImporter:
|
|||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
|
|
@ -112,6 +126,7 @@ TextureImporter:
|
|||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
|
Before Width: | Height: | Size: 79 B After Width: | Height: | Size: 79 B |
|
|
@ -3,7 +3,7 @@ guid: b5d17df8d14f2324692a7c69f24cf658
|
|||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
|
|
@ -24,6 +24,7 @@ TextureImporter:
|
|||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
|
@ -62,6 +63,7 @@ TextureImporter:
|
|||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
|
|
@ -99,6 +101,18 @@ TextureImporter:
|
|||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
|
|
@ -112,6 +126,7 @@ TextureImporter:
|
|||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
|
Before Width: | Height: | Size: 79 B After Width: | Height: | Size: 79 B |
|
|
@ -3,7 +3,7 @@ guid: 0f7acf68f1798ae48a5505519abac457
|
|||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
|
@ -24,6 +24,7 @@ TextureImporter:
|
|||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
|
@ -62,6 +63,7 @@ TextureImporter:
|
|||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
|
|
@ -99,6 +101,18 @@ TextureImporter:
|
|||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
|
|
@ -112,6 +126,7 @@ TextureImporter:
|
|||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
|
Before Width: | Height: | Size: 560 B After Width: | Height: | Size: 560 B |
|
|
@ -33,6 +33,8 @@ namespace UniGLTF
|
|||
|
||||
var tmp = AssetDatabase.LoadAssetAtPath<Mesh>(assetPath);
|
||||
Assert.Null(tmp);
|
||||
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public sealed class CopyTextureTests
|
||||
{
|
||||
private static string AssetPath = "Assets/VRMShaders/GLTF/IO/Tests";
|
||||
|
||||
private static readonly Color32 Black = new Color32(0, 0, 0, 255);
|
||||
private static readonly Color32 Gray = new Color32(127, 127, 127, 255);
|
||||
private static readonly Color32 White = new Color32(255, 255, 255, 255);
|
||||
|
|
@ -32,7 +29,7 @@ namespace UniGLTF
|
|||
[Test]
|
||||
public void CopyFromNonReadableSRgbPng()
|
||||
{
|
||||
var nonReadableTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable.png");
|
||||
var nonReadableTex = TestAssets.LoadAsset<Texture2D>("4x4_non_readable.png");
|
||||
Assert.False(nonReadableTex.isReadable);
|
||||
var copiedTex = TextureConverter.CopyTexture(nonReadableTex, ColorSpace.sRGB, true, null);
|
||||
var pixels = copiedTex.GetPixels32(miplevel: 0);
|
||||
|
|
@ -46,7 +43,7 @@ namespace UniGLTF
|
|||
[Test]
|
||||
public void CopyFromNonReadableSRgbDds()
|
||||
{
|
||||
var compressedTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable_compressed.dds");
|
||||
var compressedTex = TestAssets.LoadAsset<Texture2D>("4x4_non_readable_compressed.dds");
|
||||
Assert.False(compressedTex.isReadable);
|
||||
var copiedTex = TextureConverter.CopyTexture(compressedTex, ColorSpace.sRGB, true, null);
|
||||
var pixels = copiedTex.GetPixels32(miplevel: 0);
|
||||
|
|
@ -60,7 +57,7 @@ namespace UniGLTF
|
|||
[Test]
|
||||
public void CopyAttributes()
|
||||
{
|
||||
var src = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable.png");
|
||||
var src = TestAssets.LoadAsset<Texture2D>("4x4_non_readable.png");
|
||||
var dst = TextureConverter.CopyTexture(src, ColorSpace.sRGB, false, null);
|
||||
Assert.AreEqual(src.name, dst.name);
|
||||
Assert.AreEqual(src.anisoLevel, dst.anisoLevel);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public sealed class EditorTextureSerializerTests
|
||||
{
|
||||
private static readonly string AssetPath = "Assets/UniGLTF/Tests/UniGLTF";
|
||||
private static readonly string SrgbGrayImageName = "4x4_gray_import_as_srgb";
|
||||
private static readonly string LinearGrayImageName = "4x4_gray_import_as_linear";
|
||||
private static readonly string NormalMapGrayImageName = "4x4_gray_import_as_normal_map";
|
||||
private static readonly Texture2D SrgbGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{SrgbGrayImageName}.png");
|
||||
private static readonly Texture2D LinearGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{LinearGrayImageName}.png");
|
||||
private static readonly Texture2D NormalMapGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{NormalMapGrayImageName}.png");
|
||||
private static readonly Texture2D SrgbGrayTex = TestAssets.LoadAsset<Texture2D>($"{SrgbGrayImageName}.png");
|
||||
private static readonly Texture2D LinearGrayTex = TestAssets.LoadAsset<Texture2D>($"{LinearGrayImageName}.png");
|
||||
private static readonly Texture2D NormalMapGrayTex = TestAssets.LoadAsset<Texture2D>($"{NormalMapGrayImageName}.png");
|
||||
private static readonly Color32 JustGray = new Color32(127, 127, 127, 255);
|
||||
private static readonly Color32 SrgbGrayInSrgb = JustGray;
|
||||
private static readonly Color32 SrgbGrayInLinear = ((Color)SrgbGrayInSrgb).linear;
|
||||
|
|
@ -113,23 +111,28 @@ namespace UniGLTF
|
|||
{
|
||||
// Prepare
|
||||
var root = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var mat = new Material(Shader.Find("Standard"));
|
||||
var mat = new Material(Shader.Find(BuiltInStandardMaterialExporter.TargetShaderName));
|
||||
mat.SetTexture(propertyName, srcTex);
|
||||
root.GetComponentOrThrow<MeshRenderer>().sharedMaterial = mat;
|
||||
|
||||
// Export glTF
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings
|
||||
{
|
||||
InverseAxis = Axes.X,
|
||||
ExportOnlyBlendShapePosition = false,
|
||||
UseSparseAccessorForMorphTarget = false,
|
||||
DivideVertexBuffer = false,
|
||||
}, textureSerializer: new EditorTextureSerializer()))
|
||||
{
|
||||
exporter.Prepare(root);
|
||||
exporter.Export();
|
||||
}
|
||||
using var exporter = new gltfExporter(
|
||||
data,
|
||||
new GltfExportSettings
|
||||
{
|
||||
InverseAxis = Axes.X,
|
||||
ExportOnlyBlendShapePosition = false,
|
||||
UseSparseAccessorForMorphTarget = false,
|
||||
DivideVertexBuffer = false,
|
||||
},
|
||||
materialExporter: new BuiltInGltfMaterialExporter(),
|
||||
textureSerializer: new EditorTextureSerializer()
|
||||
);
|
||||
|
||||
exporter.Prepare(root);
|
||||
exporter.Export();
|
||||
|
||||
var gltf = data.Gltf;
|
||||
Assert.AreEqual(1, gltf.images.Count);
|
||||
var exportedImage = gltf.images[0];
|
||||
|
|
|
|||
12
Assets/UniGLTF/Tests/UniGLTF/TestAssets.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
public static class TestAssets
|
||||
{
|
||||
public static readonly string AssetPath = "Assets/UniGLTF/Tests/Objects";
|
||||
|
||||
public static T LoadAsset<T>(string filename) where T : UnityEngine.Object
|
||||
{
|
||||
return UnityEditor.AssetDatabase.LoadAssetAtPath<T>($"{AssetPath}/{filename}");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/UniGLTF/Tests/UniGLTF/TestAssets.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8519ebb2f0f84833a752bb564b59c47c
|
||||
timeCreated: 1722263712
|
||||
52
Assets/UniGLTF/Tests/UniGLTF/TestGltf.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public static class TestGltf
|
||||
{
|
||||
public static RuntimeGltfInstance LoadBytesAsBuiltInRP(byte[] bytes)
|
||||
{
|
||||
return GltfUtility.LoadBytesAsync(
|
||||
"",
|
||||
bytes,
|
||||
awaitCaller: new ImmediateCaller(),
|
||||
materialGenerator: new BuiltInGltfMaterialDescriptorGenerator()
|
||||
).Result;
|
||||
}
|
||||
|
||||
public static RuntimeGltfInstance LoadPathAsBuiltInRP(string path)
|
||||
{
|
||||
return GltfUtility.LoadAsync(
|
||||
path,
|
||||
awaitCaller: new ImmediateCaller(),
|
||||
materialGenerator: new BuiltInGltfMaterialDescriptorGenerator()
|
||||
).Result;
|
||||
}
|
||||
|
||||
public static ExportingGltfData ExportAsBuiltInRP(GameObject gameObject, GltfExportSettings exportSettings = null)
|
||||
{
|
||||
var data = new ExportingGltfData();
|
||||
using var exporter = new gltfExporter(
|
||||
data,
|
||||
exportSettings ?? new GltfExportSettings(),
|
||||
progress: new EditorProgress(),
|
||||
animationExporter: new EditorAnimationExporter(),
|
||||
materialExporter: new BuiltInGltfMaterialExporter(),
|
||||
textureSerializer: new EditorTextureSerializer()
|
||||
);
|
||||
exporter.Prepare(gameObject);
|
||||
exporter.Export();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static GameObject CreatePrimitiveAsBuiltInRP(PrimitiveType primitiveType)
|
||||
{
|
||||
var go = GameObject.CreatePrimitive(primitiveType);
|
||||
var shader = Shader.Find("Standard");
|
||||
var material = new Material(shader);
|
||||
go.GetComponent<Renderer>().sharedMaterial = material;
|
||||
return go;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/UniGLTF/Tests/UniGLTF/TestGltf.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 11719ab072944cc2b7c0eaafa0cdff2e
|
||||
timeCreated: 1722267047
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class TextureBytesTests
|
||||
{
|
||||
static string AssetPath = "Assets/VRMShaders/GLTF/IO/Tests";
|
||||
|
||||
[Test]
|
||||
public void NonReadablePng()
|
||||
{
|
||||
var nonReadableTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable.png");
|
||||
var nonReadableTex = TestAssets.LoadAsset<Texture2D>("4x4_non_readable.png");
|
||||
Assert.False(nonReadableTex.isReadable);
|
||||
var (bytes, mime) = new EditorTextureSerializer().ExportBytesWithMime(nonReadableTex, ColorSpace.sRGB);
|
||||
Assert.NotNull(bytes);
|
||||
|
|
@ -20,7 +17,7 @@ namespace UniGLTF
|
|||
[Test]
|
||||
public void NonReadableDds()
|
||||
{
|
||||
var readonlyTexture = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4_non_readable_compressed.dds");
|
||||
var readonlyTexture = TestAssets.LoadAsset<Texture2D>("4x4_non_readable_compressed.dds");
|
||||
Assert.False(readonlyTexture.isReadable);
|
||||
var (bytes, mime) = new EditorTextureSerializer().ExportBytesWithMime(readonlyTexture, ColorSpace.sRGB);
|
||||
Assert.NotNull(bytes);
|
||||
|
|
|
|||
|
|
@ -100,18 +100,17 @@ namespace UniGLTF
|
|||
|
||||
// export
|
||||
var data = new ExportingGltfData();
|
||||
using var exporter = new gltfExporter(
|
||||
data,
|
||||
new GltfExportSettings(),
|
||||
materialExporter: new BuiltInGltfMaterialExporter());
|
||||
exporter.Prepare(go);
|
||||
exporter.Export();
|
||||
|
||||
string json = null;
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export();
|
||||
// remove empty buffer
|
||||
data.Gltf.buffers.Clear();
|
||||
|
||||
// remove empty buffer
|
||||
data.Gltf.buffers.Clear();
|
||||
|
||||
json = data.Gltf.ToJson();
|
||||
}
|
||||
var json = data.Gltf.ToJson();
|
||||
|
||||
// parse
|
||||
using (var parsed = GltfData.CreateFromExportForTest(data))
|
||||
|
|
@ -353,12 +352,7 @@ namespace UniGLTF
|
|||
[Test]
|
||||
public void GlTFToJsonTest()
|
||||
{
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(CreateSimpleScene());
|
||||
exporter.Export();
|
||||
}
|
||||
var data = TestGltf.ExportAsBuiltInRP(CreateSimpleScene());
|
||||
|
||||
var expected = data.Gltf.ToJson().ParseAsJson();
|
||||
expected.AddKey(Utf8String.From("meshes"));
|
||||
|
|
@ -565,7 +559,7 @@ namespace UniGLTF
|
|||
{
|
||||
var shader = Shader.Find("Unlit/Color");
|
||||
|
||||
var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var cubeA = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube);
|
||||
{
|
||||
cubeA.transform.SetParent(go.transform);
|
||||
var material = new Material(shader);
|
||||
|
|
@ -586,16 +580,8 @@ namespace UniGLTF
|
|||
}
|
||||
|
||||
// export
|
||||
var data = new ExportingGltfData();
|
||||
var data = TestGltf.ExportAsBuiltInRP(go);
|
||||
var gltf = data.Gltf;
|
||||
var json = default(string);
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export();
|
||||
|
||||
json = gltf.ToJson();
|
||||
}
|
||||
|
||||
Assert.AreEqual(2, gltf.meshes.Count);
|
||||
|
||||
|
|
@ -658,22 +644,14 @@ namespace UniGLTF
|
|||
try
|
||||
{
|
||||
{
|
||||
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var cube = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube);
|
||||
cube.transform.SetParent(go.transform);
|
||||
UnityEngine.Object.DestroyImmediate(cube.GetComponent<MeshRenderer>());
|
||||
}
|
||||
|
||||
// export
|
||||
var data = new ExportingGltfData();
|
||||
var data = TestGltf.ExportAsBuiltInRP(go);
|
||||
var gltf = data.Gltf;
|
||||
string json;
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export();
|
||||
|
||||
json = gltf.ToJson();
|
||||
}
|
||||
|
||||
Assert.AreEqual(0, gltf.meshes.Count);
|
||||
Assert.AreEqual(1, gltf.nodes.Count);
|
||||
|
|
@ -682,7 +660,7 @@ namespace UniGLTF
|
|||
// import
|
||||
using (var parsed = GltfData.CreateFromExportForTest(data))
|
||||
{
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var context = new ImporterContext(parsed, materialGenerator: new BuiltInGltfMaterialDescriptorGenerator()))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
Assert.AreEqual(1, loaded.transform.GetChildren().Count());
|
||||
|
|
@ -708,14 +686,14 @@ namespace UniGLTF
|
|||
try
|
||||
{
|
||||
{
|
||||
var child = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var child = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube);
|
||||
child.transform.SetParent(root.transform);
|
||||
// remove MeshFilter
|
||||
Component.DestroyImmediate(child.GetComponent<MeshFilter>());
|
||||
}
|
||||
|
||||
{
|
||||
var child = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var child = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube);
|
||||
child.transform.SetParent(root.transform);
|
||||
// set null
|
||||
child.GetComponent<MeshFilter>().sharedMesh = null;
|
||||
|
|
@ -727,16 +705,9 @@ namespace UniGLTF
|
|||
Assert.True(vs.All(x => x.CanExport));
|
||||
|
||||
// export
|
||||
var data = new ExportingGltfData();
|
||||
var data = TestGltf.ExportAsBuiltInRP(root);
|
||||
var gltf = data.Gltf;
|
||||
string json;
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(root);
|
||||
exporter.Export();
|
||||
|
||||
json = gltf.ToJson();
|
||||
}
|
||||
var json = gltf.ToJson();
|
||||
|
||||
Assert.AreEqual(0, gltf.meshes.Count);
|
||||
Assert.AreEqual(2, gltf.nodes.Count);
|
||||
|
|
@ -770,6 +741,42 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// https://github.com/vrm-c/UniVRM/pull/2413
|
||||
//
|
||||
[Test]
|
||||
public void ExportingMeshByteLengthTest()
|
||||
{
|
||||
var validator = ScriptableObject.CreateInstance<MeshExportValidator>();
|
||||
var root = new GameObject("root");
|
||||
try
|
||||
{
|
||||
{
|
||||
var child = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube);
|
||||
child.transform.SetParent(root.transform);
|
||||
}
|
||||
// export
|
||||
var data = TestGltf.ExportAsBuiltInRP(root);
|
||||
var gltf = data.Gltf;
|
||||
// cube
|
||||
var expected =
|
||||
// pos
|
||||
(4*3)*24
|
||||
// normal
|
||||
+(4*3)*24
|
||||
// uv
|
||||
+(4*2)*24
|
||||
// indices
|
||||
+ 4 * 36;
|
||||
Assert.AreEqual(expected, gltf.buffers[0].byteLength);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GameObject.DestroyImmediate(root);
|
||||
ScriptableObject.DestroyImmediate(validator);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class CantConstruct
|
||||
{
|
||||
|
|
|
|||
80
Assets/UniGLTF/UniUnlit/Runtime/UniUnlitContext.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF.UniUnlit
|
||||
{
|
||||
public class UniUnlitContext
|
||||
{
|
||||
public Material Material { get; }
|
||||
public bool UnsafeEditMode { get; set; } = false;
|
||||
|
||||
public UniUnlitContext(Material material)
|
||||
{
|
||||
Material = material;
|
||||
}
|
||||
|
||||
public UniUnlitRenderMode RenderMode
|
||||
{
|
||||
get => UniUnlitUtil.GetRenderMode(Material);
|
||||
set
|
||||
{
|
||||
UniUnlitUtil.SetRenderMode(Material, value);
|
||||
if (!UnsafeEditMode) UniUnlitUtil.ValidateProperties(Material, isRenderModeChangedByUser: true);
|
||||
}
|
||||
}
|
||||
|
||||
public UniUnlitCullMode CullMode
|
||||
{
|
||||
get => UniUnlitUtil.GetCullMode(Material);
|
||||
set
|
||||
{
|
||||
UniUnlitUtil.SetCullMode(Material, value);
|
||||
if (!UnsafeEditMode) UniUnlitUtil.ValidateProperties(Material);
|
||||
}
|
||||
}
|
||||
|
||||
public UniUnlitVertexColorBlendOp VColBlendMode
|
||||
{
|
||||
get => UniUnlitUtil.GetVColBlendMode(Material);
|
||||
set
|
||||
{
|
||||
UniUnlitUtil.SetVColBlendMode(Material, value);
|
||||
if (!UnsafeEditMode) UniUnlitUtil.ValidateProperties(Material);
|
||||
}
|
||||
}
|
||||
|
||||
public Color MainColorSrgb
|
||||
{
|
||||
get => Material.GetColor(UniUnlitUtil.PropNameColor);
|
||||
set => Material.SetColor(UniUnlitUtil.PropNameColor, value);
|
||||
}
|
||||
|
||||
public Texture MainTexture
|
||||
{
|
||||
get => Material.GetTexture(UniUnlitUtil.PropNameMainTex);
|
||||
set => Material.SetTexture(UniUnlitUtil.PropNameMainTex, value);
|
||||
}
|
||||
|
||||
public Vector2 MainTextureOffset
|
||||
{
|
||||
get => Material.GetTextureOffset(UniUnlitUtil.PropNameMainTex);
|
||||
set => Material.SetTextureOffset(UniUnlitUtil.PropNameMainTex, value);
|
||||
}
|
||||
|
||||
public Vector2 MainTextureScale
|
||||
{
|
||||
get => Material.GetTextureScale(UniUnlitUtil.PropNameMainTex);
|
||||
set => Material.SetTextureScale(UniUnlitUtil.PropNameMainTex, value);
|
||||
}
|
||||
|
||||
public float Cutoff
|
||||
{
|
||||
get => Material.GetFloat(UniUnlitUtil.PropNameCutoff);
|
||||
set => Material.SetFloat(UniUnlitUtil.PropNameCutoff, value);
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
UniUnlitUtil.ValidateProperties(Material, isRenderModeChangedByUser: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/UniGLTF/UniUnlit/Runtime/UniUnlitContext.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 57963fbf465047bf83ed829f8a0022d3
|
||||
timeCreated: 1722613449
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "com.vrmc.gltf",
|
||||
"version": "0.124.2",
|
||||
"version": "0.125.0",
|
||||
"displayName": "UniGLTF",
|
||||
"description": "GLTF importer and exporter",
|
||||
"unity": "2021.3",
|
||||
|
|
|
|||
|
|
@ -16,12 +16,17 @@ namespace VRM
|
|||
/// </summary>
|
||||
/// <param name="path">出力先</param>
|
||||
/// <param name="settings">エクスポート設定</param>
|
||||
public static byte[] Export(GameObject exportRoot, VRMMetaObject meta, VRMExportSettings settings)
|
||||
public static byte[] Export(
|
||||
GameObject exportRoot,
|
||||
VRMMetaObject meta,
|
||||
VRMExportSettings settings,
|
||||
IMaterialExporter materialExporter = null
|
||||
)
|
||||
{
|
||||
List<GameObject> destroy = new List<GameObject>();
|
||||
try
|
||||
{
|
||||
return Export(exportRoot, meta, settings, destroy);
|
||||
return Export(exportRoot, meta, settings, materialExporter, destroy);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -143,9 +148,12 @@ namespace VRM
|
|||
/// <param name="path"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="destroy">作業が終わったらDestoryするべき一時オブジェクト</param>
|
||||
static byte[] Export(GameObject exportRoot, VRMMetaObject meta,
|
||||
VRMExportSettings settings,
|
||||
List<GameObject> destroy)
|
||||
private static byte[] Export(
|
||||
GameObject exportRoot,
|
||||
VRMMetaObject meta,
|
||||
VRMExportSettings settings,
|
||||
IMaterialExporter materialExporter,
|
||||
List<GameObject> destroy)
|
||||
{
|
||||
var target = exportRoot;
|
||||
|
||||
|
|
@ -227,6 +235,7 @@ namespace VRM
|
|||
var gltfExportSettings = settings.GltfExportSettings;
|
||||
using (var exporter = new VRMExporter(data, gltfExportSettings,
|
||||
animationExporter: settings.KeepAnimation ? new EditorAnimationExporter() : null,
|
||||
materialExporter: materialExporter,
|
||||
textureSerializer: new EditorTextureSerializer()))
|
||||
{
|
||||
exporter.Prepare(target);
|
||||
|
|
|
|||
|
|
@ -76,10 +76,11 @@ namespace VRM
|
|||
var map = texturePaths
|
||||
.Select(x => x.LoadAsset<Texture>())
|
||||
.ToDictionary(x => new SubAssetKey(x), x => x as UnityEngine.Object);
|
||||
var settings = new ImporterContextSettings();
|
||||
|
||||
// 確実に Dispose するために敢えて再パースしている
|
||||
using (var data = new GlbFileParser(vrmPath).Parse())
|
||||
using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map, loadAnimation: true))
|
||||
using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map, settings: settings))
|
||||
{
|
||||
var editor = new VRMEditorImporterContext(context, prefabPath);
|
||||
foreach (var textureInfo in context.TextureDescriptorGenerator.Get().GetEnumerable())
|
||||
|
|
|
|||
|
|
@ -41,21 +41,13 @@ namespace VRM
|
|||
}
|
||||
|
||||
// fallback
|
||||
Debug.LogWarning($"fallback");
|
||||
return new MaterialDescriptor(
|
||||
GltfMaterialImportUtils.ImportMaterialName(i, null),
|
||||
BuiltInGltfPbrMaterialImporter.Shader,
|
||||
null,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new Action<Material>[]{});
|
||||
if (Symbols.VRM_DEVELOP)
|
||||
{
|
||||
Debug.LogWarning($"material: {i} out of range. fallback");
|
||||
}
|
||||
return GetGltfDefault(GltfMaterialImportUtils.ImportMaterialName(i, null));
|
||||
}
|
||||
|
||||
public MaterialDescriptor GetGltfDefault()
|
||||
{
|
||||
return BuiltInGltfDefaultMaterialImporter.CreateParam();
|
||||
}
|
||||
public MaterialDescriptor GetGltfDefault(string materialName = null) => BuiltInGltfDefaultMaterialImporter.CreateParam(materialName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ namespace VRM
|
|||
{
|
||||
private readonly glTF_VRM_extensions _vrm;
|
||||
|
||||
public UrpGltfPbrMaterialImporter PbrMaterialImporter { get; } = new();
|
||||
public UrpGltfDefaultMaterialImporter DefaultMaterialImporter { get; } = new();
|
||||
|
||||
public UrpVrmMaterialDescriptorGenerator(glTF_VRM_extensions vrm)
|
||||
{
|
||||
_vrm = vrm;
|
||||
|
|
@ -20,26 +23,16 @@ namespace VRM
|
|||
// unlit "UniUnlit" work in URP
|
||||
if (BuiltInGltfUnlitMaterialImporter.TryCreateParam(data, i, out var matDesc)) return matDesc;
|
||||
// pbr "Standard" to "Universal Render Pipeline/Lit"
|
||||
if (UrpGltfPbrMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
|
||||
// fallback
|
||||
if (PbrMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc;
|
||||
|
||||
// NOTE: Fallback to default material
|
||||
if (Symbols.VRM_DEVELOP)
|
||||
{
|
||||
Debug.LogWarning($"material: {i} out of range. fallback");
|
||||
}
|
||||
return new MaterialDescriptor(
|
||||
GltfMaterialImportUtils.ImportMaterialName(i, null),
|
||||
UrpGltfPbrMaterialImporter.Shader,
|
||||
null,
|
||||
new Dictionary<string, TextureDescriptor>(),
|
||||
new Dictionary<string, float>(),
|
||||
new Dictionary<string, Color>(),
|
||||
new Dictionary<string, Vector4>(),
|
||||
new Action<Material>[]{});
|
||||
return GetGltfDefault(GltfMaterialImportUtils.ImportMaterialName(i, null));
|
||||
}
|
||||
|
||||
public MaterialDescriptor GetGltfDefault()
|
||||
{
|
||||
return UrpGltfDefaultMaterialImporter.CreateParam();
|
||||
}
|
||||
public MaterialDescriptor GetGltfDefault(string materialName = null) => DefaultMaterialImporter.CreateParam(materialName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@ namespace VRM
|
|||
{
|
||||
public static IMaterialDescriptorGenerator GetValidVrmMaterialDescriptorGenerator(glTF_VRM_extensions vrm)
|
||||
{
|
||||
return RenderPipelineUtility.GetRenderPipelineType() switch
|
||||
return GetVrmMaterialDescriptorGenerator(vrm, RenderPipelineUtility.GetRenderPipelineType());
|
||||
}
|
||||
|
||||
public static IMaterialDescriptorGenerator GetVrmMaterialDescriptorGenerator(glTF_VRM_extensions vrm, RenderPipelineTypes renderPipelineType)
|
||||
{
|
||||
return renderPipelineType switch
|
||||
{
|
||||
RenderPipelineTypes.UniversalRenderPipeline => new UrpVrmMaterialDescriptorGenerator(vrm),
|
||||
RenderPipelineTypes.BuiltinRenderPipeline => new BuiltInVrmMaterialDescriptorGenerator(vrm),
|
||||
|
|
|
|||
|
|
@ -25,12 +25,11 @@ namespace VRM
|
|||
IReadOnlyDictionary<SubAssetKey, Object> externalObjectMap = null,
|
||||
ITextureDeserializer textureDeserializer = null,
|
||||
IMaterialDescriptorGenerator materialGenerator = null,
|
||||
bool loadAnimation = false)
|
||||
: base(data.Data, externalObjectMap, textureDeserializer, materialGenerator ?? VrmMaterialDescriptorGeneratorUtility.GetValidVrmMaterialDescriptorGenerator(data.VrmExtension))
|
||||
ImporterContextSettings settings = null)
|
||||
: base(data.Data, externalObjectMap, textureDeserializer, materialGenerator ?? VrmMaterialDescriptorGeneratorUtility.GetValidVrmMaterialDescriptorGenerator(data.VrmExtension), settings ?? new ImporterContextSettings(false))
|
||||
{
|
||||
_data = data;
|
||||
TextureDescriptorGenerator = new VrmTextureDescriptorGenerator(Data, VRM);
|
||||
LoadAnimation = loadAnimation;
|
||||
}
|
||||
|
||||
#region OnLoad
|
||||
|
|
|
|||
|
|
@ -39,11 +39,12 @@ namespace VRM
|
|||
{
|
||||
materialGen = materialGeneratorCallback(vrm.VrmExtension);
|
||||
}
|
||||
var importerContextSettings = new ImporterContextSettings(loadAnimation);
|
||||
using (var loader = new VRMImporterContext(
|
||||
vrm,
|
||||
textureDeserializer: textureDeserializer,
|
||||
materialGenerator: materialGen,
|
||||
loadAnimation: loadAnimation))
|
||||
settings: importerContextSettings))
|
||||
{
|
||||
if (metaCallback != null)
|
||||
{
|
||||
|
|
@ -96,11 +97,12 @@ namespace VRM
|
|||
{
|
||||
materialGen = materialGeneratorCallback(vrm.VrmExtension);
|
||||
}
|
||||
var importerContextSettings = new ImporterContextSettings(loadAnimation: loadAnimation);
|
||||
using (var loader = new VRMImporterContext(
|
||||
vrm,
|
||||
textureDeserializer: textureDeserializer,
|
||||
materialGenerator: materialGen,
|
||||
loadAnimation: loadAnimation))
|
||||
settings: importerContextSettings))
|
||||
{
|
||||
if (metaCallback != null)
|
||||
{
|
||||
|
|
|
|||
8
Assets/VRM/Runtime/SpringBone/Logic.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1b3d9c467d3da3e4aa800f2a9229768c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
12
Assets/VRM/Runtime/SpringBone/Logic/SceneInfo.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRM.SpringBone
|
||||
{
|
||||
struct SceneInfo
|
||||
{
|
||||
public IReadOnlyList<Transform> RootBones;
|
||||
public Transform Center;
|
||||
public VRMSpringBoneColliderGroup[] ColliderGroups;
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Runtime/SpringBone/Logic/SceneInfo.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1f9f3d46865885b4a8d559a5d962db5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/VRM/Runtime/SpringBone/Logic/SphereCollider.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace VRM.SpringBone
|
||||
{
|
||||
struct SphereCollider
|
||||
{
|
||||
public readonly Vector3 Position;
|
||||
public readonly float Radius;
|
||||
|
||||
public SphereCollider(Transform transform, VRMSpringBoneColliderGroup.SphereCollider collider)
|
||||
{
|
||||
Position = transform.TransformPoint(collider.Offset);
|
||||
var ls = transform.lossyScale;
|
||||
var scale = Mathf.Max(Mathf.Max(ls.x, ls.y), ls.z);
|
||||
Radius = scale * collider.Radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Runtime/SpringBone/Logic/SphereCollider.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 102ef8d07b335ee42b6a198b5657ef80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
129
Assets/VRM/Runtime/SpringBone/Logic/SpringBoneJoint.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRM.SpringBone
|
||||
{
|
||||
/// <summary>
|
||||
/// original from
|
||||
/// http://rocketjump.skr.jp/unity3d/109/
|
||||
/// </summary>
|
||||
class SpringBoneJoint
|
||||
{
|
||||
Transform m_transform;
|
||||
public Transform Head => m_transform;
|
||||
|
||||
private Vector3 m_boneAxis;
|
||||
private Vector3 m_currentTail;
|
||||
|
||||
private readonly float m_length;
|
||||
private Vector3 m_localDir;
|
||||
private Vector3 m_prevTail;
|
||||
|
||||
public SpringBoneJoint(Transform center, Transform transform, Vector3 localChildPosition)
|
||||
{
|
||||
m_transform = transform;
|
||||
var worldChildPosition = m_transform.TransformPoint(localChildPosition);
|
||||
m_currentTail = center != null
|
||||
? center.InverseTransformPoint(worldChildPosition)
|
||||
: worldChildPosition;
|
||||
m_prevTail = m_currentTail;
|
||||
LocalRotation = transform.localRotation;
|
||||
m_boneAxis = localChildPosition.normalized;
|
||||
m_length = localChildPosition.magnitude;
|
||||
}
|
||||
|
||||
public Vector3 Tail => m_transform.localToWorldMatrix.MultiplyPoint(m_boneAxis * m_length);
|
||||
|
||||
private Quaternion LocalRotation { get; }
|
||||
|
||||
float m_radius;
|
||||
public void SetRadius(float radius)
|
||||
{
|
||||
m_radius = radius * m_transform.UniformedLossyScale();
|
||||
}
|
||||
|
||||
private Quaternion ParentRotation =>
|
||||
m_transform.parent != null
|
||||
? m_transform.parent.rotation
|
||||
: Quaternion.identity;
|
||||
|
||||
public void Update(Transform center,
|
||||
float stiffnessForce, float dragForce, Vector3 external,
|
||||
List<SphereCollider> colliders)
|
||||
{
|
||||
var currentTail = center != null
|
||||
? center.TransformPoint(m_currentTail)
|
||||
: m_currentTail;
|
||||
var prevTail = center != null
|
||||
? center.TransformPoint(m_prevTail)
|
||||
: m_prevTail;
|
||||
|
||||
// verlet積分で次の位置を計算
|
||||
var nextTail = currentTail
|
||||
+ (currentTail - prevTail) * (1.0f - dragForce) // 前フレームの移動を継続する(減衰もあるよ)
|
||||
+ ParentRotation * LocalRotation * m_boneAxis * stiffnessForce // 親の回転による子ボーンの移動目標
|
||||
+ external; // 外力による移動量
|
||||
|
||||
// 長さをboneLengthに強制
|
||||
var position = m_transform.position;
|
||||
nextTail = position + (nextTail - position).normalized * m_length;
|
||||
|
||||
// Collisionで移動
|
||||
nextTail = Collision(colliders, nextTail);
|
||||
|
||||
m_prevTail = center != null
|
||||
? center.InverseTransformPoint(currentTail)
|
||||
: currentTail;
|
||||
|
||||
m_currentTail = center != null
|
||||
? center.InverseTransformPoint(nextTail)
|
||||
: nextTail;
|
||||
|
||||
//回転を適用
|
||||
m_transform.rotation = ApplyRotation(nextTail);
|
||||
}
|
||||
|
||||
protected virtual Quaternion ApplyRotation(Vector3 nextTail)
|
||||
{
|
||||
var rotation = ParentRotation * LocalRotation;
|
||||
return Quaternion.FromToRotation(rotation * m_boneAxis,
|
||||
nextTail - m_transform.position) * rotation;
|
||||
}
|
||||
|
||||
protected virtual Vector3 Collision(List<SpringBone.SphereCollider> colliders, Vector3 nextTail)
|
||||
{
|
||||
foreach (var collider in colliders)
|
||||
{
|
||||
var r = m_radius + collider.Radius;
|
||||
if (Vector3.SqrMagnitude(nextTail - collider.Position) <= (r * r))
|
||||
{
|
||||
// ヒット。Colliderの半径方向に押し出す
|
||||
var normal = (nextTail - collider.Position).normalized;
|
||||
var posFromCollider = collider.Position + normal * (m_radius + collider.Radius);
|
||||
// 長さをboneLengthに強制
|
||||
nextTail = m_transform.position + (posFromCollider - m_transform.position).normalized * m_length;
|
||||
}
|
||||
}
|
||||
return nextTail;
|
||||
}
|
||||
|
||||
public void DrawGizmo(Transform center, Color color)
|
||||
{
|
||||
var currentTail = center != null
|
||||
? center.TransformPoint(m_currentTail)
|
||||
: m_currentTail;
|
||||
var prevTail = center != null
|
||||
? center.TransformPoint(m_prevTail)
|
||||
: m_prevTail;
|
||||
|
||||
Gizmos.color = Color.gray;
|
||||
Gizmos.DrawLine(currentTail, prevTail);
|
||||
Gizmos.DrawWireSphere(prevTail, m_radius);
|
||||
|
||||
Gizmos.color = color;
|
||||
Gizmos.DrawLine(currentTail, m_transform.position);
|
||||
Gizmos.DrawWireSphere(currentTail, m_radius);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/VRM/Runtime/SpringBone/Logic/SpringBoneJoint.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2602939771f9eb2428b140e10fa899f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/VRM/Runtime/SpringBone/Logic/SpringBoneSettings.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace VRM.SpringBone
|
||||
{
|
||||
struct SpringBoneSettings
|
||||
{
|
||||
public float StiffnessForce;
|
||||
public Vector3 GravityDir;
|
||||
public float GravityPower;
|
||||
public float HitRadius;
|
||||
public float DragForce;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c979a822d9cd3754db84ce10c42f3b56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||