diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs
new file mode 100644
index 000000000..2d09f28a5
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs
@@ -0,0 +1,10 @@
+namespace UniGLTF
+{
+ public enum UrpLitBlendMode
+ {
+ Alpha = 0,
+ Premultiply = 1,
+ Additive = 2,
+ Multiply = 3,
+ }
+}
\ No newline at end of file
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs.meta
new file mode 100644
index 000000000..81c0e8029
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitBlendMode.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 307c409e09f74fed8caaaedfdf794ef9
+timeCreated: 1722351228
\ No newline at end of file
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitContext.cs
index 2d07220d9..f34d7e7fc 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitContext.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/ShaderUtil/Lit/UrpLitContext.cs
@@ -1,8 +1,20 @@
-using UnityEngine;
+using System;
+using UnityEngine;
using UnityEngine.Rendering;
namespace UniGLTF
{
+ ///
+ /// "Universal Render Pipeline/Lit" シェーダーのプロパティを操作するためのクラス
+ ///
+ /// glTF との読み書きに必要な機能だけ実装する
+ ///
+ /// 非対応項目
+ /// - Detail Texture
+ /// - Specular Highlights Toggle
+ /// - Environment Reflections Toggle
+ /// - Sorting Priority
+ ///
public sealed class UrpLitContext
{
private readonly Material _mat;
@@ -10,6 +22,7 @@ namespace UniGLTF
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");
@@ -19,7 +32,7 @@ namespace UniGLTF
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 SmoothnessTextureChannel = Shader.PropertyToID("_SmoothnessTextureChannel");
+ 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");
@@ -27,6 +40,9 @@ namespace UniGLTF
private static readonly int BumpScaleProp = Shader.PropertyToID("_BumpScale");
private static readonly int BumpMapProp = Shader.PropertyToID("_BumpMap");
private static readonly int EmissionEnabled = Shader.PropertyToID("_EmissionEnabled");
+ 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";
@@ -36,6 +52,11 @@ namespace UniGLTF
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)
{
@@ -48,12 +69,7 @@ namespace UniGLTF
set
{
_mat.SetFloat(WorkflowMode, (float)value);
- var isSpecularSetup = value == UrpLitWorkflowType.Specular;
- _mat.SetKeyword(SpecularSetupKeyword, isSpecularSetup);
-
- var glossMapName = isSpecularSetup ? SpecGlossMapProp : MetallicGlossMapProp;
- var hasGlossMap = _mat.GetTexture(glossMapName) != null;
- _mat.SetKeyword(MetallicSpecGlossMapKeyword, hasGlossMap);
+ ValidateShaderKeywords();
}
}
@@ -63,20 +79,38 @@ namespace UniGLTF
set
{
_mat.SetFloat(Surface, (float)value);
- _mat.SetKeyword(SurfaceTypeTransparentKeyword, value != UrpLitSurfaceType.Opaque);
+ ValidateShaderKeywords();
}
}
- public bool AlphaClipping
+ public UrpLitBlendMode BlendMode
+ {
+ get => (UrpLitBlendMode)_mat.GetFloat(Blend);
+ set
+ {
+ _mat.SetFloat(Blend, (float)value);
+ ValidateShaderKeywords();
+ }
+ }
+
+ public bool IsAlphaClipEnabled
{
get => _mat.GetFloat(AlphaClip) >= 0.5f;
- set => _mat.SetFloat(AlphaClip, value ? 1.0f : 0.0f);
+ set
+ {
+ _mat.SetFloat(AlphaClip, value ? 1.0f : 0.0f);
+ ValidateShaderKeywords();
+ }
}
public CullMode CullMode
{
get => (CullMode)_mat.GetFloat(Cull);
- set => _mat.SetFloat(Cull, (float)value);
+ set
+ {
+ _mat.SetFloat(Cull, (float)value);
+ _mat.doubleSidedGI = value != CullMode.Back;
+ }
}
public Color BaseColorSrgb
@@ -88,16 +122,19 @@ namespace UniGLTF
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
@@ -112,15 +149,14 @@ namespace UniGLTF
set => _mat.SetFloat(SmoothnessProp, value);
}
- public UrpLitSmoothnessMapChannel SmoothnessMapChannel
+ public UrpLitSmoothnessMapChannel SmoothnessTextureChannel
{
// NOTE: Float Prop 以外に条件があるので、Keyword から読み取った方が確実
get => _mat.IsKeywordEnabled(SmoothnessTextureAlbedoChannelAKeyword) ? UrpLitSmoothnessMapChannel.AlbedoAlpha : UrpLitSmoothnessMapChannel.SpecularMetallicAlpha;
set
{
- _mat.SetFloat(SmoothnessTextureChannel, (float)value);
- var isOpaque = SurfaceType == UrpLitSurfaceType.Opaque;
- _mat.SetKeyword(SmoothnessTextureAlbedoChannelAKeyword, isOpaque && value == UrpLitSmoothnessMapChannel.AlbedoAlpha);
+ _mat.SetFloat(SmoothnessTextureChannelProp, (float)value);
+ ValidateShaderKeywords();
}
}
@@ -188,6 +224,12 @@ namespace UniGLTF
get => _mat.GetTexture(EmissionMap);
}
+ public float OcclusionStrength
+ {
+ get => _mat.GetFloat(OcclusionStrengthProp);
+ set => _mat.SetFloat(OcclusionStrengthProp, value);
+ }
+
public Texture OcclusionTexture
{
get => _mat.GetTexture(OcclusionMap);
@@ -198,6 +240,12 @@ namespace UniGLTF
}
}
+ public float Parallax
+ {
+ get => _mat.GetFloat(ParallaxProp);
+ set => _mat.SetFloat(ParallaxProp, value);
+ }
+
public Texture ParallaxTexture
{
get => _mat.GetTexture(ParallaxMap);
@@ -207,5 +255,72 @@ namespace UniGLTF
_mat.SetKeyword(ParallaxMapKeyword, value != null);
}
}
+
+ ///
+ /// 複数のプロパティに関連して設定されるキーワードを更新する。
+ ///
+ public void ValidateShaderKeywords()
+ {
+ // Workflow
+ var workflowType = (UrpLitWorkflowType)_mat.GetFloat(WorkflowMode);
+ var isSpecularSetup = workflowType == UrpLitWorkflowType.Specular;
+ _mat.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);
+
+ // Render Settings
+ var alphaClip = _mat.GetFloat(AlphaClip) >= 0.5f;
+ var blendMode = (UrpLitBlendMode)_mat.GetFloat(Blend);
+ var zWrite = surfaceType == UrpLitSurfaceType.Opaque;
+ _mat.SetKeyword(AlphaTestOnKeyword, alphaClip);
+ _mat.SetKeyword(AlphaPremultiplyOnKeyword, blendMode == UrpLitBlendMode.Premultiply);
+ _mat.SetKeyword(AlphaModulateOnKeyword, blendMode == UrpLitBlendMode.Additive);
+ _mat.SetFloat(ZWrite, zWrite ? 1.0f : 0.0f);
+ _mat.SetShaderPassEnabled("DepthOnly", zWrite);
+ _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,
+ };
+
+ // SmoothnessTextureChannel
+ var isOpaque = surfaceType == UrpLitSurfaceType.Opaque;
+ var smoothnessMapChannel = (UrpLitSmoothnessMapChannel)_mat.GetFloat(SmoothnessTextureChannelProp);
+ _mat.SetKeyword(SmoothnessTextureAlbedoChannelAKeyword, isOpaque && smoothnessMapChannel == UrpLitSmoothnessMapChannel.AlbedoAlpha);
+ }
}
}
\ No newline at end of file