mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-22 18:45:06 -05:00
Merge pull request #2400 from Santarh/urpExport2
Implements exporting materials in URP
This commit is contained in:
@@ -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
|
||||
@@ -7,18 +7,16 @@ namespace UniGLTF
|
||||
{
|
||||
public class UrpLitMaterialExporter
|
||||
{
|
||||
public string TargetShaderName { get; }
|
||||
public Shader Shader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "Universal Render Pipeline/Lit" シェーダのマテリアルをエクスポートする。
|
||||
///
|
||||
/// targetShaderName に、プロパティに互換性がある他のシェーダを指定することもできる。
|
||||
/// プロパティに互換性がある他のシェーダを指定することもできる。
|
||||
/// </summary>
|
||||
public UrpLitMaterialExporter(string targetShaderName = null)
|
||||
public UrpLitMaterialExporter(Shader shader = null)
|
||||
{
|
||||
TargetShaderName = string.IsNullOrEmpty(targetShaderName)
|
||||
? "Universal Render Pipeline/Lit"
|
||||
: targetShaderName;
|
||||
Shader = shader != null ? shader : Shader.Find("Universal Render Pipeline/Lit");
|
||||
}
|
||||
|
||||
public bool TryExportMaterial(Material src, ITextureExporter textureExporter, out glTFMaterial dst)
|
||||
@@ -26,8 +24,8 @@ namespace UniGLTF
|
||||
try
|
||||
{
|
||||
if (src == null) throw new ArgumentNullException(nameof(src));
|
||||
if (src.shader.name != TargetShaderName) throw new ArgumentException(nameof(src));
|
||||
if (textureExporter == null) throw new ArgumentNullException(nameof(textureExporter));
|
||||
if (src.shader != Shader || Shader == null) throw new UniGLTFShaderNotMatchedInternalException(src.shader);
|
||||
|
||||
dst = new glTFMaterial
|
||||
{
|
||||
@@ -54,14 +52,20 @@ namespace UniGLTF
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (UniGLTFShaderNotMatchedInternalException)
|
||||
{
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
dst = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportSurfaceSettings(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
public static void ExportSurfaceSettings(UrpBaseShaderContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
dst.alphaMode = (context.SurfaceType, context.IsAlphaClipEnabled) switch
|
||||
{
|
||||
@@ -75,7 +79,7 @@ namespace UniGLTF
|
||||
dst.doubleSided = context.CullMode != CullMode.Back; // NOTE: cull front not supported in glTF
|
||||
}
|
||||
|
||||
public static void ExportBaseColor(UrpLitContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
public static void ExportBaseColor(UrpBaseShaderContext context, glTFMaterial dst, ITextureExporter textureExporter)
|
||||
{
|
||||
dst.pbrMetallicRoughness.baseColorFactor = context.BaseColorSrgb.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
|
||||
if (context.BaseTexture != null)
|
||||
@@ -186,7 +190,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExportBaseTexTransform(UrpLitContext context, glTFTextureInfo dst)
|
||||
private static void ExportBaseTexTransform(UrpBaseShaderContext context, glTFTextureInfo dst)
|
||||
{
|
||||
GltfMaterialExportUtils.ExportTextureTransform(
|
||||
context.BaseTextureOffset,
|
||||
|
||||
@@ -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
|
||||
@@ -4,15 +4,19 @@ namespace UniGLTF
|
||||
{
|
||||
public class UrpGltfMaterialExporter : IMaterialExporter
|
||||
{
|
||||
private readonly UrpLitMaterialExporter _litExporter = new();
|
||||
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)
|
||||
{
|
||||
glTFMaterial dst;
|
||||
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;
|
||||
|
||||
if (_litExporter.TryExportMaterial(m, textureExporter, out dst)) return dst;
|
||||
|
||||
return dst;
|
||||
Debug.Log($"Material `{m.name}` fallbacks.");
|
||||
return FallbackExporter.ExportMaterial(m, textureExporter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -15,22 +15,13 @@ namespace UniGLTF
|
||||
/// - Environment Reflections Toggle
|
||||
/// - Sorting Priority
|
||||
/// </summary>
|
||||
public class UrpLitContext
|
||||
public class UrpLitContext : UrpBaseShaderContext
|
||||
{
|
||||
private readonly Material _mat;
|
||||
|
||||
private static readonly int WorkflowMode = Shader.PropertyToID("_WorkflowMode");
|
||||
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 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 CutoffProp = Shader.PropertyToID("_Cutoff");
|
||||
private static readonly int SmoothnessProp = Shader.PropertyToID("_Smoothness");
|
||||
private static readonly int SmoothnessTextureChannelProp = Shader.PropertyToID("_SmoothnessTextureChannel");
|
||||
private static readonly int MetallicProp = Shader.PropertyToID("_Metallic");
|
||||
@@ -39,131 +30,45 @@ namespace UniGLTF
|
||||
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 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 SpecularSetupKeyword = "_SPECULAR_SETUP";
|
||||
private static readonly string MetallicSpecGlossMapKeyword = "_METALLICSPECGLOSSMAP";
|
||||
private static readonly string SurfaceTypeTransparentKeyword = "_SURFACE_TYPE_TRANSPARENT";
|
||||
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 string AlphaTestOnKeyword = "_ALPHATEST_ON";
|
||||
private static readonly string AlphaPremultiplyOnKeyword = "_ALPHAPREMULTIPLY_ON";
|
||||
private static readonly string AlphaModulateOnKeyword = "_ALPHAMODULATE_ON";
|
||||
private static readonly int OcclusionStrengthProp = Shader.PropertyToID("_OcclusionStrength");
|
||||
private static readonly int ParallaxProp = Shader.PropertyToID("_Parallax");
|
||||
|
||||
public UrpLitContext(Material material)
|
||||
public UrpLitContext(Material material) : base(material)
|
||||
{
|
||||
_mat = material;
|
||||
|
||||
}
|
||||
|
||||
public Material Material => _mat;
|
||||
|
||||
/// <summary>
|
||||
/// これが有効な場合、Validate() 関数が呼ばれるべき場合でも自動的に呼ばれなくなります。
|
||||
///
|
||||
/// 処理最適化目的で使用できます。
|
||||
/// </summary>
|
||||
public bool UnsafeEditMode { get; set; } = false;
|
||||
|
||||
public UrpLitWorkflowType WorkflowType
|
||||
{
|
||||
get => (UrpLitWorkflowType)_mat.GetFloat(WorkflowMode);
|
||||
get => (UrpLitWorkflowType)Material.GetFloat(WorkflowMode);
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(WorkflowMode, (float)value);
|
||||
Material.SetFloat(WorkflowMode, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public UrpLitSurfaceType SurfaceType
|
||||
{
|
||||
get => (UrpLitSurfaceType)_mat.GetFloat(Surface);
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(Surface, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public UrpLitBlendMode BlendMode
|
||||
{
|
||||
get => (UrpLitBlendMode)_mat.GetFloat(Blend);
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(Blend, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAlphaClipEnabled
|
||||
{
|
||||
get => _mat.GetFloat(AlphaClip) >= 0.5f;
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(AlphaClip, value ? 1.0f : 0.0f);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public CullMode CullMode
|
||||
{
|
||||
get => (CullMode)_mat.GetFloat(Cull);
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(Cull, (float)value);
|
||||
_mat.doubleSidedGI = value != CullMode.Back;
|
||||
}
|
||||
}
|
||||
|
||||
public Color BaseColorSrgb
|
||||
{
|
||||
get => _mat.GetColor(BaseColorProp);
|
||||
set => _mat.SetColor(BaseColorProp, value);
|
||||
}
|
||||
|
||||
public Texture BaseTexture
|
||||
{
|
||||
get => _mat.GetTexture(BaseMap);
|
||||
set => _mat.SetTexture(BaseMap, value);
|
||||
}
|
||||
|
||||
public Vector2 BaseTextureOffset
|
||||
{
|
||||
get => _mat.GetTextureOffset(BaseMap);
|
||||
set => _mat.SetTextureOffset(BaseMap, value);
|
||||
}
|
||||
|
||||
public Vector2 BaseTextureScale
|
||||
{
|
||||
get => _mat.GetTextureScale(BaseMap);
|
||||
set => _mat.SetTextureScale(BaseMap, value);
|
||||
}
|
||||
|
||||
public float Cutoff
|
||||
{
|
||||
get => _mat.GetFloat(CutoffProp);
|
||||
set => _mat.SetFloat(CutoffProp, value);
|
||||
}
|
||||
|
||||
public float Smoothness
|
||||
{
|
||||
get => _mat.GetFloat(SmoothnessProp);
|
||||
set => _mat.SetFloat(SmoothnessProp, value);
|
||||
get => Material.GetFloat(SmoothnessProp);
|
||||
set => Material.SetFloat(SmoothnessProp, value);
|
||||
}
|
||||
|
||||
public UrpLitSmoothnessMapChannel SmoothnessTextureChannel
|
||||
{
|
||||
// NOTE: Float Prop 以外に条件があるので、Keyword から読み取った方が確実
|
||||
get => _mat.IsKeywordEnabled(SmoothnessTextureAlbedoChannelAKeyword) ? UrpLitSmoothnessMapChannel.AlbedoAlpha : UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
|
||||
get => Material.IsKeywordEnabled(SmoothnessTextureAlbedoChannelAKeyword) ? UrpLitSmoothnessMapChannel.AlbedoAlpha : UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
|
||||
set
|
||||
{
|
||||
_mat.SetFloat(SmoothnessTextureChannelProp, (float)value);
|
||||
Material.SetFloat(SmoothnessTextureChannelProp, (float)value);
|
||||
if (!UnsafeEditMode) Validate();
|
||||
}
|
||||
}
|
||||
@@ -171,179 +76,129 @@ namespace UniGLTF
|
||||
public float Metallic
|
||||
{
|
||||
// NOTE: Metallic ワークフロー専用
|
||||
get => _mat.GetFloat(MetallicProp);
|
||||
set => _mat.SetFloat(MetallicProp, value);
|
||||
get => Material.GetFloat(MetallicProp);
|
||||
set => Material.SetFloat(MetallicProp, value);
|
||||
}
|
||||
|
||||
public Texture MetallicGlossMap
|
||||
{
|
||||
// NOTE: Metallic ワークフロー専用
|
||||
get => _mat.GetTexture(MetallicGlossMapProp);
|
||||
set => _mat.SetTexture(MetallicGlossMapProp, value);
|
||||
get => Material.GetTexture(MetallicGlossMapProp);
|
||||
set => Material.SetTexture(MetallicGlossMapProp, value);
|
||||
}
|
||||
|
||||
public Color SpecColorSrgb
|
||||
{
|
||||
// NOTE: Specular ワークフロー専用
|
||||
get => _mat.GetColor(SpecColorProp);
|
||||
set => _mat.SetColor(SpecColorProp, value);
|
||||
get => Material.GetColor(SpecColorProp);
|
||||
set => Material.SetColor(SpecColorProp, value);
|
||||
}
|
||||
|
||||
public Texture SpecGlossMap
|
||||
{
|
||||
// NOTE: Specular ワークフロー専用
|
||||
get => _mat.GetTexture(SpecGlossMapProp);
|
||||
set => _mat.SetTexture(SpecGlossMapProp, value);
|
||||
get => Material.GetTexture(SpecGlossMapProp);
|
||||
set => Material.SetTexture(SpecGlossMapProp, value);
|
||||
}
|
||||
|
||||
public float BumpScale
|
||||
{
|
||||
get => _mat.GetFloat(BumpScaleProp);
|
||||
set => _mat.SetFloat(BumpScaleProp, value);
|
||||
get => Material.GetFloat(BumpScaleProp);
|
||||
set => Material.SetFloat(BumpScaleProp, value);
|
||||
}
|
||||
|
||||
public Texture BumpMap
|
||||
{
|
||||
get => _mat.GetTexture(BumpMapProp);
|
||||
get => Material.GetTexture(BumpMapProp);
|
||||
set
|
||||
{
|
||||
_mat.SetTexture(BumpMapProp, value);
|
||||
_mat.SetKeyword(NormalMapKeyword, value != null);
|
||||
Material.SetTexture(BumpMapProp, value);
|
||||
Material.SetKeyword(NormalMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmissionEnabled
|
||||
{
|
||||
get => _mat.IsKeywordEnabled(EmissionKeyword);
|
||||
get => Material.IsKeywordEnabled(EmissionKeyword);
|
||||
set
|
||||
{
|
||||
_mat.SetKeyword(EmissionKeyword, value);
|
||||
Material.SetKeyword(EmissionKeyword, value);
|
||||
if (value)
|
||||
{
|
||||
_mat.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
Material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mat.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
Material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Color EmissionColorLinear
|
||||
{
|
||||
get => _mat.GetColor(EmissionColor);
|
||||
set => _mat.SetColor(EmissionColor, value);
|
||||
get => Material.GetColor(EmissionColor);
|
||||
set => Material.SetColor(EmissionColor, value);
|
||||
}
|
||||
|
||||
public Texture EmissionTexture
|
||||
{
|
||||
get => _mat.GetTexture(EmissionMap);
|
||||
set => _mat.SetTexture(EmissionMap, value);
|
||||
get => Material.GetTexture(EmissionMap);
|
||||
set => Material.SetTexture(EmissionMap, value);
|
||||
}
|
||||
|
||||
public float OcclusionStrength
|
||||
{
|
||||
get => _mat.GetFloat(OcclusionStrengthProp);
|
||||
set => _mat.SetFloat(OcclusionStrengthProp, value);
|
||||
get => Material.GetFloat(OcclusionStrengthProp);
|
||||
set => Material.SetFloat(OcclusionStrengthProp, value);
|
||||
}
|
||||
|
||||
public Texture OcclusionTexture
|
||||
{
|
||||
get => _mat.GetTexture(OcclusionMap);
|
||||
get => Material.GetTexture(OcclusionMap);
|
||||
set
|
||||
{
|
||||
_mat.SetTexture(OcclusionMap, value);
|
||||
_mat.SetKeyword(OcclusionMapKeyword, value != null);
|
||||
Material.SetTexture(OcclusionMap, value);
|
||||
Material.SetKeyword(OcclusionMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
public float Parallax
|
||||
{
|
||||
get => _mat.GetFloat(ParallaxProp);
|
||||
set => _mat.SetFloat(ParallaxProp, value);
|
||||
get => Material.GetFloat(ParallaxProp);
|
||||
set => Material.SetFloat(ParallaxProp, value);
|
||||
}
|
||||
|
||||
public Texture ParallaxTexture
|
||||
{
|
||||
get => _mat.GetTexture(ParallaxMap);
|
||||
get => Material.GetTexture(ParallaxMap);
|
||||
set
|
||||
{
|
||||
_mat.SetTexture(ParallaxMap, value);
|
||||
_mat.SetKeyword(ParallaxMapKeyword, value != null);
|
||||
Material.SetTexture(ParallaxMap, value);
|
||||
Material.SetKeyword(ParallaxMapKeyword, value != null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 複数のプロパティに関連して設定されるキーワードやプロパティなどを更新する
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
public override void Validate()
|
||||
{
|
||||
base.Validate();
|
||||
|
||||
// Workflow
|
||||
var workflowType = (UrpLitWorkflowType)_mat.GetFloat(WorkflowMode);
|
||||
var workflowType = (UrpLitWorkflowType)Material.GetFloat(WorkflowMode);
|
||||
var isSpecularSetup = workflowType == UrpLitWorkflowType.Specular;
|
||||
_mat.SetKeyword(SpecularSetupKeyword, isSpecularSetup);
|
||||
Material.SetKeyword(SpecularSetupKeyword, isSpecularSetup);
|
||||
|
||||
// GlossMap
|
||||
var glossMapName = isSpecularSetup ? SpecGlossMapProp : MetallicGlossMapProp;
|
||||
var hasGlossMap = _mat.GetTexture(glossMapName) != null;
|
||||
_mat.SetKeyword(MetallicSpecGlossMapKeyword, hasGlossMap);
|
||||
|
||||
// Surface Type
|
||||
var surfaceType = (UrpLitSurfaceType)_mat.GetFloat(Surface);
|
||||
_mat.SetKeyword(SurfaceTypeTransparentKeyword, surfaceType != UrpLitSurfaceType.Opaque);
|
||||
var hasGlossMap = Material.GetTexture(glossMapName) != null;
|
||||
Material.SetKeyword(MetallicSpecGlossMapKeyword, hasGlossMap);
|
||||
|
||||
// SmoothnessTextureChannel
|
||||
var isOpaque = surfaceType == UrpLitSurfaceType.Opaque;
|
||||
var smoothnessMapChannel = (UrpLitSmoothnessMapChannel)_mat.GetFloat(SmoothnessTextureChannelProp);
|
||||
_mat.SetKeyword(SmoothnessTextureAlbedoChannelAKeyword, isOpaque && smoothnessMapChannel == UrpLitSmoothnessMapChannel.AlbedoAlpha);
|
||||
|
||||
// Alpha Clip
|
||||
var alphaClip = _mat.GetFloat(AlphaClip) >= 0.5f;
|
||||
_mat.SetKeyword(AlphaTestOnKeyword, alphaClip);
|
||||
|
||||
// Blend Mode
|
||||
var blendMode = (UrpLitBlendMode)_mat.GetFloat(Blend);
|
||||
_mat.SetKeyword(AlphaPremultiplyOnKeyword, blendMode == UrpLitBlendMode.Premultiply);
|
||||
_mat.SetKeyword(AlphaModulateOnKeyword, blendMode == UrpLitBlendMode.Additive);
|
||||
|
||||
// ZWrite
|
||||
var zWrite = surfaceType == UrpLitSurfaceType.Opaque;
|
||||
_mat.SetFloat(ZWrite, zWrite ? 1.0f : 0.0f);
|
||||
_mat.SetShaderPassEnabled("DepthOnly", zWrite);
|
||||
|
||||
// Render Settings
|
||||
_mat.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,
|
||||
});
|
||||
_mat.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,
|
||||
});
|
||||
_mat.SetOverrideTag("RenderType", (surfaceType, alphaClip) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, false) => "Opaque",
|
||||
(UrpLitSurfaceType.Opaque, true) => "TransparentCutout",
|
||||
(UrpLitSurfaceType.Transparent, _) => "Transparent",
|
||||
_ => "Opaque",
|
||||
});
|
||||
_mat.renderQueue = (surfaceType, alphaClip) switch
|
||||
{
|
||||
(UrpLitSurfaceType.Opaque, false) => (int)RenderQueue.Geometry,
|
||||
(UrpLitSurfaceType.Opaque, true) => (int)RenderQueue.AlphaTest,
|
||||
(UrpLitSurfaceType.Transparent, _) => (int)RenderQueue.Transparent,
|
||||
_ => _mat.shader.renderQueue,
|
||||
};
|
||||
var isOpaque = SurfaceType == UrpLitSurfaceType.Opaque;
|
||||
var smoothnessMapChannel = (UrpLitSmoothnessMapChannel)Material.GetFloat(SmoothnessTextureChannelProp);
|
||||
Material.SetKeyword(SmoothnessTextureAlbedoChannelAKeyword, isOpaque && smoothnessMapChannel == UrpLitSmoothnessMapChannel.AlbedoAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
80
Assets/UniGLTF/UniUnlit/Runtime/UniUnlitContext.cs
Normal file
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
3
Assets/UniGLTF/UniUnlit/Runtime/UniUnlitContext.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57963fbf465047bf83ed829f8a0022d3
|
||||
timeCreated: 1722613449
|
||||
Reference in New Issue
Block a user