Added HairBlending shader pass;

Added HairBlendingSetting in UTSRenderPassSetting;
Added MaterialType to UTS;
Added MaterialFeature scope to UTS material editor;

Merged HairBlendingPass and HairShadowPass into UTSPass;

Fixed the bug that character box light can not update rotation correctly according to bound light source;
This commit is contained in:
Misaki
2025-01-09 07:58:06 +09:00
parent 9290223624
commit d47641e5e2
18 changed files with 627 additions and 368 deletions

View File

@@ -1,10 +1,10 @@
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True"> <engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<engine:VisualElement data-source-type="Unity.Rendering.HighDefinition.Toon.BoxLightAdjustment, Unity.Toonshader" style="flex-grow: 1;"> <engine:VisualElement data-source-type="Misaki.HdrpToon.BoxLightAdjustment, Misaki.HdrpToon" style="flex-grow: 1;">
<engine:Label text="Rendering" style="-unity-font-style: bold; margin-top: 4px; margin-bottom: 2px;" /> <engine:Label text="Rendering" style="-unity-font-style: bold; margin-top: 4px; margin-bottom: 2px;" />
<engine:VisualElement name="renderingGroup" style="padding-left: 8px;"> <engine:VisualElement name="renderingGroup" style="padding-left: 8px;">
<editor:RenderingLayerMaskField label="Layer Mask" value="DynamicTransform" type="UnityEngine.Rendering.HighDefinition.RenderingLayerMask, Unity.RenderPipelines.HighDefinition.Runtime"> <editor:RenderingLayerMaskField label="Layer Mask" value="DynamicTransform" type="UnityEngine.Rendering.HighDefinition.RenderingLayerMask, Unity.RenderPipelines.HighDefinition.Runtime">
<Bindings> <Bindings>
<engine:DataBinding property="value" data-source-path="LayerMask" data-source-type="Unity.Rendering.HighDefinition.Toon.BoxLightAdjustment, Unity.Toonshader" binding-mode="TwoWay" /> <engine:DataBinding property="value" data-source-path="LayerMask" binding-mode="TwoWay" />
</Bindings> </Bindings>
</editor:RenderingLayerMaskField> </editor:RenderingLayerMaskField>
<editor:ObjectField label="Source Light" type="UnityEngine.Light, UnityEngine.CoreModule"> <editor:ObjectField label="Source Light" type="UnityEngine.Light, UnityEngine.CoreModule">
@@ -30,21 +30,11 @@
<engine:DataBinding property="index" data-source-path="followGameObjectPosition" binding-mode="TwoWay" /> <engine:DataBinding property="index" data-source-path="followGameObjectPosition" binding-mode="TwoWay" />
</Bindings> </Bindings>
</engine:DropdownField> </engine:DropdownField>
<engine:DropdownField label="Follow Rotation" choices="Disable,Enable" index="0"> <engine:FloatField label="Distance Offset" value="20">
<Bindings> <Bindings>
<engine:DataBinding property="index" data-source-path="followGameObjectRotation" binding-mode="TwoWay" /> <engine:DataBinding property="value" data-source-path="distanceOffset" binding-mode="TwoWay" />
</Bindings> </Bindings>
</engine:DropdownField> </engine:FloatField>
<engine:Vector3Field label="Position Offset">
<Bindings>
<engine:DataBinding property="value" data-source-path="positionOffset" binding-mode="TwoWay" />
</Bindings>
</engine:Vector3Field>
<engine:Vector3Field label="Rotation Offset">
<Bindings>
<engine:DataBinding property="value" data-source-path="rotationOffset" binding-mode="TwoWay" source-to-ui-converters="QuaternionToVector3Converter" ui-to-source-converters="QuaternionToVector3Converter" />
</Bindings>
</engine:Vector3Field>
</engine:VisualElement> </engine:VisualElement>
</engine:VisualElement> </engine:VisualElement>
</engine:UXML> </engine:UXML>

View File

@@ -108,7 +108,7 @@ namespace UnityEditor.Rendering.Toon
internal const string ShaderPropReceiveHairShadow = "_Is_ReceiveHairShadow"; internal const string ShaderPropReceiveHairShadow = "_Is_ReceiveHairShadow";
internal const string ShaderPropEyeParallax = "_Is_EyeParallax"; internal const string ShaderPropEyeParallax = "_Is_EyeParallax";
internal const string ShaderPropEyebrowSeethrough = "_Is_EyebrowSeethrough"; internal const string ShaderPropHairBlendingTarget = "_Is_HairBlendingTarget";
internal const string ShaderPropSimpleUI = "_simpleUI"; internal const string ShaderPropSimpleUI = "_simpleUI";
internal const string ShaderPropAutoRenderQueue = "_AutoRenderQueue"; internal const string ShaderPropAutoRenderQueue = "_AutoRenderQueue";
@@ -128,6 +128,7 @@ namespace UnityEditor.Rendering.Toon
internal const string ShaderPropUtsVersionZ = "_utsVersionZ"; internal const string ShaderPropUtsVersionZ = "_utsVersionZ";
internal const string ShaderPropIsUnityToonShader = "_isUnityToonshader"; internal const string ShaderPropIsUnityToonShader = "_isUnityToonshader";
internal const string ShaderPropShadowMode = "_Shadow_Mode"; internal const string ShaderPropShadowMode = "_Shadow_Mode";
internal const string ShaderPropMaterialType = "_Material_Type";
internal const string ShaderPropPBR = "_PBR_Mode"; internal const string ShaderPropPBR = "_PBR_Mode";
internal const string ShaderPropOutline = "_OUTLINE"; internal const string ShaderPropOutline = "_OUTLINE";
internal const string ShaderPropNormalMapToHighColor = "_Is_NormalMapToHighColor"; internal const string ShaderPropNormalMapToHighColor = "_Is_NormalMapToHighColor";
@@ -211,6 +212,8 @@ namespace UnityEditor.Rendering.Toon
protected readonly string[] ClippingModeNames = { "Off", "On", "Clip Transparency" }; protected readonly string[] ClippingModeNames = { "Off", "On", "Clip Transparency" };
protected readonly string[] StencilModeNames = { "Off", "Draw If Not Equal to", "Replace Stencil Buffer with" }; protected readonly string[] StencilModeNames = { "Off", "Draw If Not Equal to", "Replace Stencil Buffer with" };
protected readonly string[] ZTestModeNames = { "Disabled", "Never", "Less", "Equal", "LessEqual", "Greater", "NotEqual", "GreaterEqual", "Always" }; protected readonly string[] ZTestModeNames = { "Disabled", "Never", "Less", "Equal", "LessEqual", "Greater", "NotEqual", "GreaterEqual", "Always" };
protected readonly string[] materialTypeDefines = { "MATERIAL_TYPE_STANDARD", "MATERIAL_TYPE_FRONT_HAIR", "MATERIAL_TYPE_FACE", "MATERIAL_TYPE_EYE" };
protected readonly string[] PbrModeDefines = { "_PBR_Mode_OFF", "_PBR_Mode_ST", "_PBR_Mode_ANISO", "_PBR_Mode_KK", "_PBR_Mode_TOON" }; protected readonly string[] PbrModeDefines = { "_PBR_Mode_OFF", "_PBR_Mode_ST", "_PBR_Mode_ANISO", "_PBR_Mode_KK", "_PBR_Mode_TOON" };
public enum UTS_ClippingMode public enum UTS_ClippingMode
@@ -279,6 +282,14 @@ namespace UnityEditor.Rendering.Toon
Normal, SDF Normal, SDF
} }
public enum MaterialType
{
Standard,
FrontHair,
Face,
Eye
}
public enum PBRMode public enum PBRMode
{ {
Off, Standard, Anisotropy, KKHair, Toon Off, Standard, Anisotropy, KKHair, Toon
@@ -314,18 +325,19 @@ namespace UnityEditor.Rendering.Toon
Shader = 1 << 0, Shader = 1 << 0,
Basic = 1 << 1, Basic = 1 << 1,
ShadingStepAndFeather = 1 << 2, ShadingStepAndFeather = 1 << 2,
NormalMap = 1 << 3, MaterialFeature = 1 << 3,
Highlight = 1 << 4, PBR = 1 << 4,
Rimlight = 1 << 5, Highlight = 1 << 5,
MatCap = 1 << 6, Rimlight = 1 << 6,
AngelRing = 1 << 7, MatCap = 1 << 7,
Emission = 1 << 8, AngelRing = 1 << 8,
Outline = 1 << 9, Emission = 1 << 9,
TessellationLegacy = 1 << 10, Outline = 1 << 10,
TessellationHDRP = 1 << 11, TessellationLegacy = 1 << 11,
SceneLight = 1 << 12, TessellationHDRP = 1 << 12,
EnvironmentalLightEffectiveness = 1 << 13, SceneLight = 1 << 13,
MetaverseSettings = 1 << 14, EnvironmentalLightEffectiveness = 1 << 14,
MetaverseSettings = 1 << 15,
} }
// variables which must be gotten from shader at the beggning of GUI // variables which must be gotten from shader at the beggning of GUI
@@ -333,6 +345,7 @@ namespace UnityEditor.Rendering.Toon
internal int m_renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry; internal int m_renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
// variables which just to be held. // variables which just to be held.
internal ShadowMode m_shadowMode; internal ShadowMode m_shadowMode;
internal MaterialType m_materialType;
internal PBRMode m_pbrMode; internal PBRMode m_pbrMode;
internal OutlineMode m_outlineMode; internal OutlineMode m_outlineMode;
internal CullingMode m_cullingMode; internal CullingMode m_cullingMode;
@@ -397,7 +410,7 @@ namespace UnityEditor.Rendering.Toon
protected MaterialProperty set_2nd_ShadePosition = null; protected MaterialProperty set_2nd_ShadePosition = null;
protected MaterialProperty shadingGradeMap = null; protected MaterialProperty shadingGradeMap = null;
protected MaterialProperty hairBlendingMap = null;
protected MaterialProperty highColor_Tex = null; protected MaterialProperty highColor_Tex = null;
protected MaterialProperty highColor = null; protected MaterialProperty highColor = null;
@@ -491,6 +504,7 @@ namespace UnityEditor.Rendering.Toon
set_2nd_ShadePosition = FindProperty(ShaderProp_Set_2nd_ShadePosition, props, false); set_2nd_ShadePosition = FindProperty(ShaderProp_Set_2nd_ShadePosition, props, false);
shadingGradeMap = FindProperty(ShaderProp_ShadingGradeMap, props, false); shadingGradeMap = FindProperty(ShaderProp_ShadingGradeMap, props, false);
hairBlendingMap = FindProperty("_HairBlendingMap", props);
highColor_Tex = FindProperty(ShaderProp_HighColor_Tex, props); highColor_Tex = FindProperty(ShaderProp_HighColor_Tex, props);
highColor = FindProperty("_HighColor", props); highColor = FindProperty("_HighColor", props);
@@ -615,7 +629,8 @@ namespace UnityEditor.Rendering.Toon
public static readonly GUIContent shaderFoldout = EditorGUIUtility.TrTextContent("Shader Settings", "Shader Settings provides basic settings that are not specific to cel-shading but are needed for general CG."); public static readonly GUIContent shaderFoldout = EditorGUIUtility.TrTextContent("Shader Settings", "Shader Settings provides basic settings that are not specific to cel-shading but are needed for general CG.");
public static readonly GUIContent basicColorFoldout = EditorGUIUtility.TrTextContent("Shading Color Settings", "Three Color Map and Control Map Settings provide very basic settings for cel-shading in Unity Toon Shader."); public static readonly GUIContent basicColorFoldout = EditorGUIUtility.TrTextContent("Shading Color Settings", "Three Color Map and Control Map Settings provide very basic settings for cel-shading in Unity Toon Shader.");
public static readonly GUIContent shadingStepAndFeatherFoldout = EditorGUIUtility.TrTextContent("Shading Step and Feather Settings", "Basic 3 color step and feather settings."); public static readonly GUIContent shadingStepAndFeatherFoldout = EditorGUIUtility.TrTextContent("Shading Step and Feather Settings", "Basic 3 color step and feather settings.");
public static readonly GUIContent normalMapFoldout = EditorGUIUtility.TrTextContent("PBR Settings", "PBR settings. The settings for PBR effect, such as specular and IBL."); public static readonly GUIContent materialFeatureFoldout = EditorGUIUtility.TrTextContent("Material Feature", "Material Feature Setting. The settings for special material feature like hair shadow, hair blending, etc");
public static readonly GUIContent pbrFoldout = EditorGUIUtility.TrTextContent("PBR Settings", "PBR settings. The settings for PBR effect, such as specular and IBL.");
public static readonly GUIContent highlightFoldout = EditorGUIUtility.TrTextContent("Highlight Settings", "Highlight settings. Such as power, show or hide, light shape and so on."); public static readonly GUIContent highlightFoldout = EditorGUIUtility.TrTextContent("Highlight Settings", "Highlight settings. Such as power, show or hide, light shape and so on.");
public static readonly GUIContent rimLightFoldout = EditorGUIUtility.TrTextContent("Rim Light Settings", "Rim Light Settings. Such as color, direction, inverted rim light and so on."); public static readonly GUIContent rimLightFoldout = EditorGUIUtility.TrTextContent("Rim Light Settings", "Rim Light Settings. Such as color, direction, inverted rim light and so on.");
public static readonly GUIContent matCapFoldout = EditorGUIUtility.TrTextContent("Material Capture (MatCap) Settings", "MatCap settings. Sphere maps for metallic or unusual expressions."); public static readonly GUIContent matCapFoldout = EditorGUIUtility.TrTextContent("Material Capture (MatCap) Settings", "MatCap settings. Sphere maps for metallic or unusual expressions.");
@@ -635,6 +650,8 @@ namespace UnityEditor.Rendering.Toon
public static readonly GUIContent SDFShadowText = new GUIContent("SDF Shadow Map", "Specify SDF shadow map"); public static readonly GUIContent SDFShadowText = new GUIContent("SDF Shadow Map", "Specify SDF shadow map");
public static readonly GUIContent firstShadeColorText = new GUIContent("1st Shading Map", "The map used for the brighter portions of the shadow."); public static readonly GUIContent firstShadeColorText = new GUIContent("1st Shading Map", "The map used for the brighter portions of the shadow.");
public static readonly GUIContent secondShadeColorText = new GUIContent("2nd Shading Map", "The map used for the darker portions of the shadow."); public static readonly GUIContent secondShadeColorText = new GUIContent("2nd Shading Map", "The map used for the darker portions of the shadow.");
public static readonly GUIContent materialTypeText = new GUIContent("Material Type", "Specifies the material type.");
public static readonly GUIContent hairBlendingTargetMapText = new GUIContent("Blending Map", "Specifies the texture to blend with hair.");
public static readonly GUIContent normalMapText = new GUIContent("Normal Map", "A texture that dictates the bumpiness of the material."); public static readonly GUIContent normalMapText = new GUIContent("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent pbrModeText = new GUIContent("PBR Mode", "Specifies PBR model mode."); public static readonly GUIContent pbrModeText = new GUIContent("PBR Mode", "Specifies PBR model mode.");
public static readonly GUIContent highColorText = new GUIContent("Highlight", "Highlight : Texture(sRGB) x Color(RGB) Default:White"); public static readonly GUIContent highColorText = new GUIContent("Highlight", "Highlight : Texture(sRGB) x Color(RGB) Default:White");
@@ -660,7 +677,6 @@ namespace UnityEditor.Rendering.Toon
public static readonly GUIContent transparentModeText = new GUIContent("Transparency", "Enable different modes that allow the simulation of a variety of transparent objects. "); public static readonly GUIContent transparentModeText = new GUIContent("Transparency", "Enable different modes that allow the simulation of a variety of transparent objects. ");
public static readonly GUIContent stencilVauleText = new GUIContent("Stencil Value", "Stencil value that is submitted to the stencil buffer for controlling the per-pixel drawing."); public static readonly GUIContent stencilVauleText = new GUIContent("Stencil Value", "Stencil value that is submitted to the stencil buffer for controlling the per-pixel drawing.");
public static readonly GUIContent workflowModeText = new GUIContent("Mode", "The UTS mode that controls what settings are exposed in the shader."); public static readonly GUIContent workflowModeText = new GUIContent("Mode", "The UTS mode that controls what settings are exposed in the shader.");
public static readonly GUIContent materialTypeText = new GUIContent("Material Type", "The PBR model type of the material");
// ----------------------------------------------------- // -----------------------------------------------------
public static readonly GUIContent clippingmodeModeText = new GUIContent("Trans Clipping", "Select trans clipping mode that fits your purpose. "); public static readonly GUIContent clippingmodeModeText = new GUIContent("Trans Clipping", "Select trans clipping mode that fits your purpose. ");
@@ -686,6 +702,7 @@ namespace UnityEditor.Rendering.Toon
public static readonly GUIContent hairShadowCasterText = new GUIContent("Hair Shadow Caster", "Enable to cast hair shadow"); public static readonly GUIContent hairShadowCasterText = new GUIContent("Hair Shadow Caster", "Enable to cast hair shadow");
public static readonly GUIContent receiveHairShadowText = new GUIContent("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster"); public static readonly GUIContent receiveHairShadowText = new GUIContent("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster");
public static readonly GUIContent hairBlendingTargetShadowText = new GUIContent("Hair Blending Target", "Enable to be blended with hair");
public static readonly GUIContent eyeParallaxText = new GUIContent("Eye Parallax Correction", "Enables parallax correction for eye material"); public static readonly GUIContent eyeParallaxText = new GUIContent("Eye Parallax Correction", "Enables parallax correction for eye material");
public static readonly GUIContent eyebrowSeethroughText = new GUIContent("Eyebrow Seethrough", "Enable for eyebrow material to be blended with hair. Must configure HairShadowPass to work."); public static readonly GUIContent eyebrowSeethroughText = new GUIContent("Eyebrow Seethrough", "Enable for eyebrow material to be blended with hair. Must configure HairShadowPass to work.");
@@ -822,9 +839,9 @@ namespace UnityEditor.Rendering.Toon
label: "Eye Parallax Amount", tooltip: "Distance of parallax correction", label: "Eye Parallax Amount", tooltip: "Distance of parallax correction",
propName: "_EyeParallaxAmount", defaultValue: 0.1f, min: 0.0f, max: 0.4f); propName: "_EyeParallaxAmount", defaultValue: 0.1f, min: 0.0f, max: 0.4f);
public static readonly RangeProperty eyeBrowBlendingFactor = new RangeProperty( public static readonly RangeProperty hairBlendingFactor = new RangeProperty(
label: "Eyebrow Blending Factor", tooltip: "Blend Factor of Eyebrows on Hair", label: "Hair Blending Factor", tooltip: "Blend Factor of Hair Blending Target on Hair",
propName: "_EyeBrowBlendingFactor", defaultValue: 0.5f, min: 0.0f, max: 1.0f); propName: "_HairBlendingFactor", defaultValue: 0.5f, min: 0.0f, max: 1.0f);
public static readonly RangeProperty shaderPropStepOffsetText = new RangeProperty( public static readonly RangeProperty shaderPropStepOffsetText = new RangeProperty(
label: "Step Offset", tooltip: "Fine tunes light steps (boundaries) added in the ForwardAdd pass, such as real-time point lights.", label: "Step Offset", tooltip: "Fine tunes light steps (boundaries) added in the ForwardAdd pass, such as real-time point lights.",
@@ -1003,7 +1020,8 @@ namespace UnityEditor.Rendering.Toon
m_MaterialScopeList.RegisterHeaderScope(Styles.shaderFoldout, Expandable.Shader, DrawShaderOptions, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.shaderFoldout, Expandable.Shader, DrawShaderOptions, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.basicColorFoldout, Expandable.Basic, GUI_BasicThreeColors, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.basicColorFoldout, Expandable.Basic, GUI_BasicThreeColors, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.shadingStepAndFeatherFoldout, Expandable.ShadingStepAndFeather, GUI_StepAndFeather, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.shadingStepAndFeatherFoldout, Expandable.ShadingStepAndFeather, GUI_StepAndFeather, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.normalMapFoldout, Expandable.NormalMap, GUI_PBRSettings, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.materialFeatureFoldout, Expandable.MaterialFeature, GUI_MaterialFeature, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.pbrFoldout, Expandable.PBR, GUI_PBRSettings, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.highlightFoldout, Expandable.Highlight, GUI_HighlightSettings, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.highlightFoldout, Expandable.Highlight, GUI_HighlightSettings, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.rimLightFoldout, Expandable.Rimlight, GUI_RimLight, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.rimLightFoldout, Expandable.Rimlight, GUI_RimLight, (uint)UTS_TransparentMode.Off, isTessellation: 0);
m_MaterialScopeList.RegisterHeaderScope(Styles.matCapFoldout, Expandable.MatCap, GUI_MatCap, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.matCapFoldout, Expandable.MatCap, GUI_MatCap, (uint)UTS_TransparentMode.Off, isTessellation: 0);
@@ -1494,13 +1512,6 @@ namespace UnityEditor.Rendering.Toon
{ {
GUI_AdditionalLookdevs(material); GUI_AdditionalLookdevs(material);
} }
EditorGUILayout.Separator();
GUI_HairShadow(material);
GUI_EyeParallax(material);
GUI_EyebrowSeethrough(material);
} }
void GUI_SystemShadows(Material material) void GUI_SystemShadows(Material material)
@@ -1518,69 +1529,71 @@ namespace UnityEditor.Rendering.Toon
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
} }
void GUI_HairShadow(Material material) void GUI_MaterialFeature(Material material)
{ {
var isCastEnable = GUI_Toggle(material, Styles.hairShadowCasterText, ShaderPropCastHairShadow, var materialTypeSetting = MaterialGetInt(material, ShaderPropMaterialType);
MaterialGetInt(material, ShaderPropCastHairShadow) != 0); m_materialType = (MaterialType)materialTypeSetting;
var isReceiveEnabled = GUI_Toggle(material, Styles.receiveHairShadowText, ShaderPropReceiveHairShadow, m_materialType = (MaterialType)EditorGUILayout.EnumPopup(Styles.materialTypeText, m_materialType);
EditorGUI.indentLevel++;
switch (m_materialType)
{
case MaterialType.FrontHair:
GUI_FrontHair(material);
break;
case MaterialType.Eye:
GUI_EyeParallax(material);
break;
default:
break;
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
var isReceiveHairShadowEnabled = GUI_Toggle(material, Styles.receiveHairShadowText, ShaderPropReceiveHairShadow,
MaterialGetInt(material, ShaderPropReceiveHairShadow) != 0); MaterialGetInt(material, ShaderPropReceiveHairShadow) != 0);
material.SetKeyword(new LocalKeyword(material.shader, "_RECEIVE_HAIR_SHADOW"), isReceiveHairShadowEnabled);
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, isCastEnable); var isHairBlendingTargetEnabled = GUI_Toggle(material, Styles.hairBlendingTargetShadowText, ShaderPropHairBlendingTarget,
material.SetKeyword(new LocalKeyword(material.shader, "_RECEIVE_HAIR_SHADOW"), isReceiveEnabled); MaterialGetInt(material, ShaderPropHairBlendingTarget) != 0);
if (isHairBlendingTargetEnabled)
{
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.hairBlendingTargetMapText, hairBlendingMap);
EditorGUI.indentLevel--;
}
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, isHairBlendingTargetEnabled);
SwitchKeyword(m_materialType);
material.SetFloat(ShaderPropMaterialType, (float)m_materialType);
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, m_materialType == MaterialType.FrontHair);
void SwitchKeyword(MaterialType target)
{
for (var i = 0; i < materialTypeDefines.Length; i++)
{
var localKeyword = new LocalKeyword(material.shader, materialTypeDefines[i]);
if ((int)target == i)
{
material.EnableKeyword(localKeyword);
}
else
{
material.DisableKeyword(localKeyword);
}
}
}
}
void GUI_FrontHair(Material material)
{
GUI_RangeProperty(material, Styles.hairBlendingFactor);
} }
void GUI_EyeParallax(Material material) void GUI_EyeParallax(Material material)
{ {
var isEnabled = GUI_Toggle(material, Styles.eyeParallaxText, ShaderPropEyeParallax,
MaterialGetInt(material, ShaderPropEyeParallax) != 0);
EditorGUI.BeginDisabledGroup(!isEnabled);
{
EditorGUI.indentLevel++;
GUI_RangeProperty(material, Styles.eyeParallaxAmount); GUI_RangeProperty(material, Styles.eyeParallaxAmount);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
EditorGUI.EndDisabledGroup();
if (isEnabled)
{
material.EnableKeyword(new LocalKeyword(material.shader, "_EYE_PARALLAX"));
}
else
{
material.DisableKeyword(new LocalKeyword(material.shader, "_EYE_PARALLAX"));
}
}
void GUI_EyebrowSeethrough(Material material)
{
var isEnabled = GUI_Toggle(material, Styles.eyebrowSeethroughText, ShaderPropEyebrowSeethrough,
MaterialGetInt(material, ShaderPropEyebrowSeethrough) != 0);
EditorGUI.BeginDisabledGroup(!isEnabled);
{
EditorGUI.indentLevel++;
GUI_RangeProperty(material, Styles.eyeBrowBlendingFactor);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
EditorGUI.EndDisabledGroup();
if (isEnabled)
{
material.EnableKeyword(new LocalKeyword(material.shader, "_EYEBROW_SEETHROUGH"));
}
else
{
material.DisableKeyword(new LocalKeyword(material.shader, "_EYEBROW_SEETHROUGH"));
}
} }
void GUI_ShadingStepAndFeatherSettings(Material material) void GUI_ShadingStepAndFeatherSettings(Material material)

View File

@@ -9,8 +9,9 @@ namespace Misaki.HdrpToon.Editor
{ {
class Styles class Styles
{ {
public static GUIContent outline = new("Outline Setting"); public static GUIContent hairShadow = new("Hair Shadow");
public static GUIContent hairShadow = new("Hair Shadow Setting"); public static GUIContent hairBlending = new("Hair Blending");
public static GUIContent outline = new("Outline");
} }
private SerializedObject _customSettings; private SerializedObject _customSettings;
@@ -28,15 +29,16 @@ namespace Misaki.HdrpToon.Editor
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline);
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow); EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow);
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairBlendingSetting"), Styles.hairBlending);
EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline);
_customSettings.ApplyModifiedPropertiesWithoutUndo();
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
UTSRenderPassRegistrar.NotifyRendererSettingChanged(); UTSRenderPassRegistrar.NotifyRendererSettingChanged();
} }
_customSettings.ApplyModifiedPropertiesWithoutUndo();
} }
public static bool IsSettingsAvailable() public static bool IsSettingsAvailable()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

View File

@@ -1,117 +0,0 @@
fileFormatVersion: 2
guid: 3d00a7a6a88c70c4ca4bb89ca1e3e842
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,8 +6,10 @@ namespace Misaki.HdrpToon
{ {
public const string OUTLINE_PASS_NAME = "Outline"; public const string OUTLINE_PASS_NAME = "Outline";
public const string HAIR_SHADOW_CASTER_PASS_NAME = "HairShadowCaster"; public const string HAIR_SHADOW_CASTER_PASS_NAME = "HairShadowCaster";
public const string HAIR_BLENDING_TARGET_PASS_NAME = "HairBlendingTarget";
public static readonly ShaderTagId outlinePassId = new(OUTLINE_PASS_NAME); public static readonly ShaderTagId outlinePassId = new(OUTLINE_PASS_NAME);
public static readonly ShaderTagId hairShadowCasterPassId = new(HAIR_SHADOW_CASTER_PASS_NAME); public static readonly ShaderTagId hairShadowCasterPassId = new(HAIR_SHADOW_CASTER_PASS_NAME);
public static readonly ShaderTagId hairBlendingTargetPassId = new(HAIR_BLENDING_TARGET_PASS_NAME);
} }
} }

View File

@@ -26,10 +26,7 @@ namespace Misaki.HdrpToon
public Transform trackedTransform; public Transform trackedTransform;
public bool followGameObjectPosition = false; public bool followGameObjectPosition = false;
public bool followGameObjectRotation = false; public float distanceOffset = 20.0f;
public Vector3 positionOffset;
public Quaternion rotationOffset;
[CreateProperty] [CreateProperty]
public Light BindingSourceLight public Light BindingSourceLight
@@ -64,8 +61,8 @@ namespace Misaki.HdrpToon
return; return;
} }
UpdateShadowLayer(_bindingSourceLightData, _layerMask, value); UpdateShadowLayer(_bindingSourceLightData, value);
UpdateShadowLayer(_targetBoxLightData, _layerMask, value); UpdateShadowLayer(_targetBoxLightData, value);
_layerMask = value; _layerMask = value;
} }
@@ -92,13 +89,9 @@ namespace Misaki.HdrpToon
{ {
Initialize(); Initialize();
} }
// Start is called before the first frame update
private void Start()
{
}
// Update is called once per frame // Update is called once per frame
private void LateUpdate() private void Update()
{ {
Initialize(); Initialize();
@@ -125,16 +118,12 @@ namespace Misaki.HdrpToon
_targetBoxLight.enabled = _bindingSourceLight.enabled; _targetBoxLight.enabled = _bindingSourceLight.enabled;
_targetBoxLight.intensity = _bindingSourceLight.intensity; _targetBoxLight.intensity = _bindingSourceLight.intensity;
if (trackedTransform != null) if (trackedTransform != null && followGameObjectPosition)
{ {
if (followGameObjectPosition) var desiredPosition = trackedTransform.position - _bindingSourceLight.transform.forward * distanceOffset;
{
_targetBoxLight.transform.position = trackedTransform.transform.position + positionOffset; _targetBoxLight.transform.position = desiredPosition;
} _targetBoxLight.transform.rotation = _bindingSourceLight.transform.rotation;
if (followGameObjectRotation)
{
_targetBoxLight.transform.rotation = trackedTransform.transform.rotation * rotationOffset;
}
} }
} }
@@ -187,7 +176,7 @@ namespace Misaki.HdrpToon
#if UNITY_EDITOR #if UNITY_EDITOR
Undo.RegisterCreatedObjectUndo(lightGameObject, "Created Boxlight adjustment"); Undo.RegisterCreatedObjectUndo(lightGameObject, "Created Boxlight adjustment");
#endif #endif
var hdLightData = lightGameObject.AddHDLight(LightType.Box); var hdLightData = lightGameObject.AddHDLight(UnityEngine.LightType.Box);
// light size // light size
hdLightData.SetBoxSpotSize(new Vector2(10.0f, 10.0f)); // Size should be culculated with more acculacy? hdLightData.SetBoxSpotSize(new Vector2(10.0f, 10.0f)); // Size should be culculated with more acculacy?
var boxLightAdjustment = lightGameObject.GetComponent<BoxLightAdjustment>(); var boxLightAdjustment = lightGameObject.GetComponent<BoxLightAdjustment>();
@@ -228,12 +217,11 @@ namespace Misaki.HdrpToon
return lightGameObject; return lightGameObject;
} }
private void UpdateShadowLayer(HDAdditionalLightData lightData, uint oldValue, uint newValue) private void UpdateShadowLayer(HDAdditionalLightData lightData, uint newValue)
{ {
lightData.linkShadowLayers = false; lightData.linkShadowLayers = false;
var oldShadowLayer = lightData.GetShadowLayers(); var lightLayer = lightData.GetLightLayers();
oldShadowLayer &= ~oldValue; var newShadowLayer = lightLayer | newValue | UnityEngine.RenderingLayerMask.defaultRenderingLayerMask;
var newShadowLayer = oldShadowLayer | newValue;
lightData.SetShadowLightLayer((UnityEngine.Rendering.HighDefinition.RenderingLayerMask)newShadowLayer); lightData.SetShadowLightLayer((UnityEngine.Rendering.HighDefinition.RenderingLayerMask)newShadowLayer);
} }
@@ -256,8 +244,7 @@ namespace Misaki.HdrpToon
if (_targetBoxLight != null) if (_targetBoxLight != null)
{ {
positionOffset = _targetBoxLight.transform.position - trackedTransform.transform.position; distanceOffset = Mathf.Abs(Vector3.Distance(_targetBoxLight.transform.position, trackedTransform.transform.position));
rotationOffset = Quaternion.Inverse(trackedTransform.transform.rotation) * _targetBoxLight.transform.rotation;
} }
_initialized = true; _initialized = true;

View File

@@ -5,17 +5,30 @@ using UnityEngine;
namespace Misaki.HdrpToon namespace Misaki.HdrpToon
{ {
[Serializable] internal enum BufferQuality
internal struct UTSOutlineSetting
{ {
public bool enable; Low,
High
} }
[Serializable] [Serializable]
internal struct UtsHairShadowSetting internal struct UtsHairShadowSetting
{ {
public bool enable; public bool enable;
public UTSHairShadowPass.ShadowQuality shadowQuality; public BufferQuality quality;
}
[Serializable]
internal struct UtsHairBlendingSetting
{
public bool enable;
public BufferQuality quality;
}
[Serializable]
internal struct UTSOutlineSetting
{
public bool enable;
} }
[CreateAssetMenu(fileName = "UTSRenderSetting", menuName = "UTS/RenderSetting")] [CreateAssetMenu(fileName = "UTSRenderSetting", menuName = "UTS/RenderSetting")]
@@ -25,10 +38,12 @@ namespace Misaki.HdrpToon
public const string UTS_RENDERING_SETTINGS_PATH = "Assets/Resources/Settings/UTSRenderSettings.asset"; public const string UTS_RENDERING_SETTINGS_PATH = "Assets/Resources/Settings/UTSRenderSettings.asset";
public const string UTS_RENDERING_SETTINGS_RESOURCES_PATH = "Settings/UTSRenderSettings"; public const string UTS_RENDERING_SETTINGS_RESOURCES_PATH = "Settings/UTSRenderSettings";
[SerializeField]
internal UTSOutlineSetting outlineSetting;
[SerializeField] [SerializeField]
internal UtsHairShadowSetting hairShadowSetting; internal UtsHairShadowSetting hairShadowSetting;
[SerializeField]
internal UtsHairBlendingSetting hairBlendingSetting;
[SerializeField]
internal UTSOutlineSetting outlineSetting;
internal static UTSRenderPassSettings GetOrCreateSettings() internal static UTSRenderPassSettings GetOrCreateSettings()
{ {

View File

@@ -22,6 +22,9 @@ Shader "HDRP/Toon"
_BaseColorMap("BaseColorMap", 2D) = "white" {} _BaseColorMap("BaseColorMap", 2D) = "white" {}
[HideInInspector] _BaseColorMap_MipInfo("_BaseColorMap_MipInfo", Vector) = (0, 0, 0, 0) [HideInInspector] _BaseColorMap_MipInfo("_BaseColorMap_MipInfo", Vector) = (0, 0, 0, 0)
_HairBlendingMap("HairBlendingMap", 2D) = "black" {}
[KeywordEnum(OFF, FrontHair, Face, Eye)] _Material_Type("Material Type", Float) = 0
[KeywordEnum(OFF, ST, ANISO, KK, TOON)] _PBR_Mode("PBR MODE", Float) = 0 [KeywordEnum(OFF, ST, ANISO, KK, TOON)] _PBR_Mode("PBR MODE", Float) = 0
_Metallic("_Metallic", Range(0.0, 1.0)) = 0 _Metallic("_Metallic", Range(0.0, 1.0)) = 0
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 _Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5
@@ -330,8 +333,8 @@ Shader "HDRP/Toon"
_EyeParallaxAmount("EyeParallaxAmount", Float) = 0.1 _EyeParallaxAmount("EyeParallaxAmount", Float) = 0.1
// Eyebrow Seethrough // Eyebrow Seethrough
[Togle(_)] _Is_EyebrowSeethrough("_Is_EyebrowSeethrough", Float) = 0 [Togle(_)] _Is_HairBlendingTarget("_Is_HairBlendingTarget", Float) = 0
_EyeBrowBlendingFactor("EyeBrowBlendingFactor", Float) = 0.5 _HairBlendingFactor("EyeBrowBlendingFactor", Float) = 0.5
//v.2.0.6 //v.2.0.6
_BaseColor_Step("BaseColor_Step", Range(0, 1)) = 0.5 _BaseColor_Step("BaseColor_Step", Range(0, 1)) = 0.5
@@ -516,8 +519,6 @@ Shader "HDRP/Toon"
// Variant // Variant
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#pragma shader_feature _HAIR_SHADOWS
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature_local _DEPTHOFFSET_ON #pragma shader_feature_local _DEPTHOFFSET_ON
#pragma shader_feature_local _DOUBLESIDED_ON #pragma shader_feature_local _DOUBLESIDED_ON
@@ -530,15 +531,6 @@ Shader "HDRP/Toon"
#pragma shader_feature_local _NORMALMAP_TANGENT_SPACE #pragma shader_feature_local _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local _ _REQUIRE_UV2 _REQUIRE_UV3 #pragma shader_feature_local _ _REQUIRE_UV2 _REQUIRE_UV3
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _DISABLE_DECALS
#pragma shader_feature_local _DISABLE_SSR
#pragma shader_feature_local _MASKMAP
#pragma shader_feature_local _ANISOTROPYMAP
#pragma shader_feature_local _SDFShadow
#pragma shader_feature_local _SPECULARCOLORMAP
#pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT #pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT
#pragma shader_feature_local _TRANSPARENT_WRITES_MOTION_VEC #pragma shader_feature_local _TRANSPARENT_WRITES_MOTION_VEC
@@ -963,7 +955,7 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
// #pragma multi_compile _ UTS_DEBUG_SHADOWMAP_BINALIZATION //#pragma multi_compile _ UTS_DEBUG_SHADOWMAP_BINALIZATION
#pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ DEBUG_DISPLAY
#pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DIRLIGHTMAP_COMBINED
@@ -974,9 +966,10 @@ Shader "HDRP/Toon"
#pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON #pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON
// Supported shadow modes per light type // Supported shadow modes per light type
#pragma multi_compile SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH #pragma multi_compile SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH
#pragma multi_compile MATERIAL_TYPE_STANDARD MATERIAL_TYPE_FRONT_HAIR MATERIAL_TYPE_FACE MATERIAL_TYPE_EYE
#pragma multi_compile _PBR_Mode_OFF _PBR_Mode_ST _PBR_Mode_ANISO _PBR_Mode_KK _PBR_Mode_TOON #pragma multi_compile _PBR_Mode_OFF _PBR_Mode_ST _PBR_Mode_ANISO _PBR_Mode_KK _PBR_Mode_TOON
#define LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #define LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
// #pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST //#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#define AREA_SHADOW_LOW #define AREA_SHADOW_LOW
#define SHADERPASS SHADERPASS_FORWARD #define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI) // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
@@ -998,12 +991,16 @@ Shader "HDRP/Toon"
//Probe volume //Probe volume
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
// Sample Face Shadow #pragma shader_feature ENABLE_UTS_HAIR_SHAOW
#pragma shader_feature ENABLE_UTS_HAIR_BLENDING
#pragma shader_feature_local _MASKMAP
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _ANISOTROPYMAP
#pragma shader_feature_local _SPECULARCOLORMAP
#pragma shader_feature_local _SDFShadow
#pragma shader_feature_local _RECEIVE_HAIR_SHADOW #pragma shader_feature_local _RECEIVE_HAIR_SHADOW
// Eye parallax
#pragma shader_feature_local _EYE_PARALLAX
// Eyebrow Blending with hair
#pragma shader_feature_local _EYEBROW_SEETHROUGH
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"
@@ -1110,7 +1107,6 @@ Shader "HDRP/Toon"
Cull Front Cull Front
Blend SrcAlpha OneMinusSrcAlpha Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM HLSLPROGRAM
@@ -1185,6 +1181,39 @@ Shader "HDRP/Toon"
ENDHLSL ENDHLSL
} }
Pass
{
Name "HairBlendingTarget"
Tags{ "LightMode" = "HairBlendingTarget" }
Cull[_CullMode]
ZClip [_ZClip]
ZWrite On
ZTest LEqual
HLSLPROGRAM
#define SHADERPASS SHADERPASS_FORWARD
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl"
#ifdef DEBUG_DISPLAY
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl"
#endif
#include "HDRPToonHead.hlsl"
#include "HDRPToonHairBlending.hlsl"
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
} }
SubShader SubShader

View File

@@ -0,0 +1,127 @@
#undef unity_ObjectToWorld
#undef unity_WorldToObject
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
// PackedVaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
// VaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return PackVaryingsType(varyingsType);
}
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
, out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#ifdef _IS_CLIPPING_MASK
if (_ClippingMaskMode != 0)
{
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
//v.2.0.5
if (_ZOverDrawMode > 0.99f)
{
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
return;
}
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _MainTex));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
}
// End of File

View File

@@ -1,7 +1,6 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 1580a7086ede7984db4d52ba831a7516 guid: a528382509a1bca4b9da190eb68e40d4
folderAsset: yes ShaderIncludeImporter:
DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:
assetBundleName: assetBundleName:

View File

@@ -194,7 +194,7 @@ void Frag(PackedVaryingsToPS packedInput,
#ifdef VARYINGS_NEED_POSITION_WS #ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS); float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#ifdef _EYE_PARALLAX #ifdef MATERIAL_TYPE_EYE
// Must have view Dir to work // Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld); float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT; float2 parallaxOffset = viewT;
@@ -878,7 +878,7 @@ void Frag(PackedVaryingsToPS packedInput,
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation // We directly calculate custome main light during the light loop in upper code to avoid extra calculation
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight); //customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
#if _SDFShadow || _RECEIVE_HAIR_SHADOW #if _SDFShadow || (_RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW)
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz); float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity)); float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
@@ -910,7 +910,7 @@ void Frag(PackedVaryingsToPS packedInput,
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor; utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif #endif
#ifdef _RECEIVE_HAIR_SHADOW #if _RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW
// Push the face fragment view space position towards the light for a little bit // Push the face fragment view space position towards the light for a little bit
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1))); float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
@@ -921,6 +921,10 @@ void Frag(PackedVaryingsToPS packedInput,
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth; float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY); float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
shadowLength.y *= camDirFactor;
float2 samplingPoint = (input.positionSS.xy + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions. float2 samplingPoint = (input.positionSS.xy + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
// Then sample the hair buffer, to see if the fragment lands in shadow. // Then sample the hair buffer, to see if the fragment lands in shadow.
@@ -958,29 +962,13 @@ void Frag(PackedVaryingsToPS packedInput,
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha)); outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif #endif
#ifdef _EYEBROW_SEETHROUGH #if MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
// By Suomi, 20230915 float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
// The eyebrow should use transparent pass and utilize the hair depth texture we have from HairShadowPass float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
float2 samplingPoint = posInput.positionNDC; outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
float cDepth = SampleCameraDepth(samplingPoint); // Camera Depth. At transparent queue we should have all the opaque object by now
float mDepth = posInput.deviceDepth; // Depth of this fragment
float3 hDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, samplingPoint); // r: Depth of hair g: Depth of Eyebrow
float hairPixel = step(0.001, hDepth.r);
float magic = 0.075;
mDepth = hairPixel > 0.1 ? max(hDepth.r, mDepth) + magic : mDepth; // Move this part of eyebrow in front of the hair
// Added a max here to prevent sampling of hair in the back
if(cDepth - mDepth > 0.02) // Manual Depth Test
{
discard;
}
outColor.a = _EyeBrowBlendingFactor;
outColor.a = hairPixel > 0.01 ? outColor.a : 1 ;
#endif #endif
#if defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW) #if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
outColor.rgb = 1; outColor.rgb = 1;
#ifdef UTS_DEBUG_SELFSHADOW #ifdef UTS_DEBUG_SELFSHADOW
outColor.rgb = min(finalColor, outColor.rgb); outColor.rgb = min(finalColor, outColor.rgb);

View File

@@ -30,6 +30,9 @@ SAMPLER(sampler_DiffuseLightingMap);
TEXTURE2D(_BaseColorMap); TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap); SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_HairBlendingMap);
SAMPLER(sampler_HairBlendingMap);
TEXTURE2D(_MaskMap); TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap); SAMPLER(sampler_MaskMap);
TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map
@@ -81,7 +84,7 @@ TEXTURE2D(_SDFShadowTex);
SAMPLER(sampler_SDFShadowTex); SAMPLER(sampler_SDFShadowTex);
TEXTURE2D(_HairShadowTex); TEXTURE2D(_HairShadowTex);
//SAMPLER(sampler_HairShadowTex); //registered number of this sampler is more than 16, so we can't use this sampler, use s_trilinear_clamp_sampler instead TEXTURE2D(_HairBlendingTex);
#else #else
@@ -351,3 +354,5 @@ float _HairShadowDistanceScaleFactor;
float _HairShadowDepthBias; float _HairShadowDepthBias;
float _HairShadowFadeInDistance; float _HairShadowFadeInDistance;
float _HairShadowFadeOutDistance; float _HairShadowFadeOutDistance;
float4 _HairBlendingRTHandleScale;

View File

@@ -23,7 +23,7 @@ float _SDFNoseHighlightCoef;
float _SDFNoseHighlightSmoothRange; float _SDFNoseHighlightSmoothRange;
float _EyeParallaxAmount; float _EyeParallaxAmount;
float _EyeBrowBlendingFactor; float _HairBlendingFactor;
float _BaseColor_Step; float _BaseColor_Step;
float _BaseShade_Feather; float _BaseShade_Feather;

View File

@@ -10,12 +10,6 @@ namespace Misaki.HdrpToon
[HideInInspector] [HideInInspector]
internal class UTSHairShadowPass : DrawRenderersCustomPass internal class UTSHairShadowPass : DrawRenderersCustomPass
{ {
public enum ShadowQuality
{
Low,
High
}
private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale"; private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale";
private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance"; private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance";
private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor"; private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor";
@@ -23,13 +17,13 @@ namespace Misaki.HdrpToon
private const string Hair_Shadow_FadeIn_Prop_Name = "_HairShadowFadeInDistance"; private const string Hair_Shadow_FadeIn_Prop_Name = "_HairShadowFadeInDistance";
private const string Hair_Shadow_Fade_Out_Prop_Name = "_HairShadowFadeOutDistance"; private const string Hair_Shadow_Fade_Out_Prop_Name = "_HairShadowFadeOutDistance";
private const string Output_RT_Name = "_HairShadowTex"; private const string Output_RT_Prop_Name = "_HairShadowTex";
private RTHandle _outputRTHandle; private RTHandle _outputRTHandle;
private bool _needReallocate; private bool _needReallocate;
private ShadowQuality _shadowQuality = ShadowQuality.High; private BufferQuality _shadowQuality = BufferQuality.High;
internal ShadowQuality CurrentShadowQuality internal BufferQuality CurrentShadowQuality
{ {
get => _shadowQuality; get => _shadowQuality;
set set
@@ -60,21 +54,21 @@ namespace Misaki.HdrpToon
var scale = _shadowQuality switch var scale = _shadowQuality switch
{ {
ShadowQuality.Low => new Vector2(0.5f, 0.5f), BufferQuality.Low => new Vector2(0.5f, 0.5f),
ShadowQuality.High => Vector2.one, BufferQuality.High => Vector2.one,
_ => Vector2.zero _ => Vector2.zero
}; };
var format = _shadowQuality switch var format = _shadowQuality switch
{ {
ShadowQuality.Low => GraphicsFormat.D16_UNorm, BufferQuality.Low => GraphicsFormat.D16_UNorm,
ShadowQuality.High => GraphicsFormat.D32_SFloat, BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.D16_UNorm _ => GraphicsFormat.D16_UNorm
}; };
_outputRTHandle?.Release(); _outputRTHandle?.Release();
_outputRTHandle = RTHandles.Alloc(scale, colorFormat: format, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, isShadowMap: true, name: Output_RT_Name); _outputRTHandle = RTHandles.Alloc(scale, colorFormat: format, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, isShadowMap: true, useDynamicScale: true, name: Output_RT_Prop_Name);
Shader.SetGlobalTexture(Output_RT_Name, _outputRTHandle); Shader.SetGlobalTexture(Output_RT_Prop_Name, _outputRTHandle);
_needReallocate = false; _needReallocate = false;
} }
@@ -102,18 +96,11 @@ namespace Misaki.HdrpToon
return; return;
} }
var mask = RenderStateMask.Nothing;
var stateBlock = new RenderStateBlock(mask)
{
depthState = new DepthState(true, CompareFunction.LessEqual),
};
var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
renderQueueRange = GetRenderQueueRange(RenderQueueType.All), renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
sortingCriteria = SortingCriteria.CommonOpaque, sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
stateBlock = stateBlock,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));

View File

@@ -22,21 +22,12 @@ namespace Misaki.HdrpToon
Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f); Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f);
var mask = RenderStateMask.Nothing;
var stateBlock = new RenderStateBlock(mask)
{
depthState = new DepthState(depthWrite, depthCompareFunction),
// We disable the stencil when the depth is overwritten but we don't write to it, to prevent writing to the stencil.
stencilState = new StencilState(false),
};
var renderConfig = HDUtils.GetRendererConfiguration(false, false); var renderConfig = HDUtils.GetRendererConfiguration(false, false);
var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UtsShaderPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UtsShaderPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
rendererConfiguration = renderConfig, rendererConfiguration = renderConfig,
renderQueueRange = GetRenderQueueRange(RenderQueueType.All), renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
stateBlock = stateBlock,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));

View File

@@ -1,10 +1,14 @@
using System; using System;
using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering.RendererUtils;
namespace Misaki.HdrpToon namespace Misaki.HdrpToon
{ {
[HideInInspector]
internal class UTSPass : CustomPass internal class UTSPass : CustomPass
{ {
private const int Adjustment_Curve_Precision = 128; private const int Adjustment_Curve_Precision = 128;
@@ -17,18 +21,256 @@ namespace Misaki.HdrpToon
private const string Toon_Light_Filter_Prop_Name = "_ToonLightHiCutFilter"; private const string Toon_Light_Filter_Prop_Name = "_ToonLightHiCutFilter";
private const string Ignore_Volume_Exposure_Prop_Name = "_ToonIgnoreExposureMultiplier"; private const string Ignore_Volume_Exposure_Prop_Name = "_ToonIgnoreExposureMultiplier";
private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale";
private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance";
private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor";
private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias";
private const string Hair_Shadow_FadeIn_Prop_Name = "_HairShadowFadeInDistance";
private const string Hair_Shadow_Fade_Out_Prop_Name = "_HairShadowFadeOutDistance";
private const string Hair_Blending_RTHandle_Scale_Prop_Name = "_HairBlendingRTHandleScale";
private const string Output_RT_Prop_Name = "_HairShadowTex";
private const string Hair_Blending_Prop_Name = "_HairBlendingTex";
private float _max; private float _max;
private float _min; private float _min;
private float[] _exposureArray; private float[] _exposureArray;
private RTHandle _hairShadowRTHandle;
private bool _needReallocateHairShadow;
private RTHandle _hairBlendingRTHandle;
private bool _needReallocateHairBlending;
private bool _enableHairShadow;
public bool EnableHairShadow
{
get => _enableHairShadow;
set
{
if (_enableHairShadow == value)
{
return;
}
_enableHairShadow = value;
if (_enableHairShadow)
{
Shader.EnableKeyword("ENABLE_UTS_HAIR_SHAOW");
}
else
{
Shader.DisableKeyword("ENABLE_UTS_HAIR_SHAOW");
_hairShadowRTHandle?.Release();
}
}
}
private bool _enableHairBlending;
public bool EnableHairBlending
{
get => _enableHairBlending;
set
{
if (_enableHairBlending == value)
{
return;
}
_enableHairBlending = value;
if (_enableHairBlending)
{
Shader.EnableKeyword("ENABLE_UTS_HAIR_BLENDING");
}
else
{
Shader.DisableKeyword("ENABLE_UTS_HAIR_BLENDING");
_hairBlendingRTHandle?.Release();
}
}
}
private BufferQuality _hairShadowQuality = BufferQuality.High;
internal BufferQuality HairShadowQuality
{
get => _hairShadowQuality;
set
{
if (_hairShadowQuality == value)
{
return;
}
_hairShadowQuality = value;
_needReallocateHairShadow = true;
}
}
private BufferQuality _hairBlendingQuality = BufferQuality.High;
internal BufferQuality HairBlendingQuality
{
get => _hairBlendingQuality;
set
{
if (_hairBlendingQuality == value)
{
return;
}
_hairBlendingQuality = value;
_needReallocateHairBlending = true;
}
}
private bool ShouldReallocateHairShadowBuffer()
{
return _hairShadowRTHandle == null || _hairShadowRTHandle.rt == null || !_hairShadowRTHandle.rt.IsCreated() || _needReallocateHairShadow;
}
private void ReallocateHairShadowBuffer()
{
#if UNITY_EDITOR
if (EditorApplication.isCompiling)
{
return;
}
#endif
var scale = _hairShadowQuality switch
{
BufferQuality.Low => new Vector2(0.5f, 0.5f),
BufferQuality.High => Vector2.one,
_ => Vector2.zero
};
var format = _hairShadowQuality switch
{
BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.D16_UNorm
};
_hairShadowRTHandle?.Release();
_hairShadowRTHandle = RTHandles.Alloc(scale, colorFormat: format, isShadowMap: true, useDynamicScale: true, name: Output_RT_Prop_Name);
Shader.SetGlobalTexture(Output_RT_Prop_Name, _hairShadowRTHandle);
_needReallocateHairShadow = false;
}
private bool ShouldReallocateHairBlendingBuffer()
{
return _hairBlendingRTHandle == null || _hairBlendingRTHandle.rt == null || !_hairBlendingRTHandle.rt.IsCreated() || _needReallocateHairBlending;
}
private void ReallocateHairBlendingBuffer()
{
#if UNITY_EDITOR
if (EditorApplication.isCompiling)
{
return;
}
#endif
var format = _hairBlendingQuality switch
{
BufferQuality.Low => GraphicsFormat.R8G8B8A8_SNorm,
BufferQuality.High => GraphicsFormat.R8G8B8A8_SRGB,
_ => GraphicsFormat.R8G8B8A8_SRGB
};
_hairBlendingRTHandle?.Release();
_hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, colorFormat: format, useDynamicScale: true, name: Hair_Blending_Prop_Name);
Shader.SetGlobalTexture(Hair_Blending_Prop_Name, _hairBlendingRTHandle);
_needReallocateHairBlending = false;
}
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{ {
_exposureArray = new float[Adjustment_Curve_Precision]; _exposureArray = new float[Adjustment_Curve_Precision];
ReallocateHairShadowBuffer();
ReallocateHairBlendingBuffer();
} }
protected override void Execute(CustomPassContext ctx) protected override void Execute(CustomPassContext ctx)
{ {
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>(); var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>();
UpdateSceneEV(utsRenderer);
RenderHairShadow(ref ctx, utsRenderer);
RenderHairBlending(ref ctx);
}
private void RenderHairShadow(ref CustomPassContext ctx, UTSRenderer utsRenderer)
{
if (!_enableHairShadow)
{
return;
}
if (ShouldReallocateHairShadowBuffer())
{
ReallocateHairShadowBuffer();
return;
}
CoreUtils.SetRenderTarget(ctx.cmd, _hairShadowRTHandle, ClearFlag.DepthStencil);
var shouldRender = utsRenderer != null && utsRenderer.enableHairShadow.value && utsRenderer.state.value;
if (!shouldRender)
{
return;
}
var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
{
renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false,
};
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
Shader.SetGlobalVector(Hair_Shadow_RTHandle_Scale_Prop_Name, _hairShadowRTHandle.rtHandleProperties.rtHandleScale);
Shader.SetGlobalFloat(Hair_Shadow_Distance_Prop_Name, utsRenderer.shadowDistance.value);
Shader.SetGlobalFloat(Hair_Shadow_Distance_Scale_Prop_Name, utsRenderer.shadowDistanceScale.value);
Shader.SetGlobalFloat(Hair_Shadow_Depth_Bias_Prop_Name, utsRenderer.shadowDepthBias.value);
Shader.SetGlobalFloat(Hair_Shadow_FadeIn_Prop_Name, utsRenderer.shadowFadeIn.value);
Shader.SetGlobalFloat(Hair_Shadow_Fade_Out_Prop_Name, utsRenderer.shadowFadeOut.value);
}
private void RenderHairBlending(ref CustomPassContext ctx)
{
if (!_enableHairBlending)
{
return;
}
if (ShouldReallocateHairBlendingBuffer())
{
ReallocateHairBlendingBuffer();
return;
}
CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, ctx.cameraDepthBuffer, ClearFlag.Color);
var result = new RendererListDesc(UtsShaderPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera)
{
renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false,
};
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
Shader.SetGlobalVector(Hair_Blending_RTHandle_Scale_Prop_Name, _hairBlendingRTHandle.rtHandleProperties.rtHandleScale);
}
private void UpdateSceneEV(UTSRenderer utsRenderer)
{
if (utsRenderer == null) if (utsRenderer == null)
{ {
return; return;
@@ -86,6 +328,8 @@ namespace Misaki.HdrpToon
protected override void Cleanup() protected override void Cleanup()
{ {
_exposureArray = null; _exposureArray = null;
_hairShadowRTHandle?.Release();
_hairBlendingRTHandle?.Release();
} }
} }
} }

View File

@@ -11,7 +11,7 @@ namespace Misaki.HdrpToon
private static UTSRenderPassSettings _renderSetting; private static UTSRenderPassSettings _renderSetting;
private static UTSPass _utsPass; private static UTSPass _utsPass;
private static UTSHairShadowPass _hairShadowPass; //private static UTSHairShadowPass _hairShadowPass;
private static UTSOutlinePass _outlinePass; private static UTSOutlinePass _outlinePass;
static UTSRenderPassRegistrar() => RegisterCustomPasses(); static UTSRenderPassRegistrar() => RegisterCustomPasses();
@@ -32,22 +32,21 @@ namespace Misaki.HdrpToon
targetDepthBuffer = CustomPass.TargetBuffer.None, targetDepthBuffer = CustomPass.TargetBuffer.None,
}; };
_hairShadowPass = new() //_hairShadowPass = new()
{ //{
name = "UTS Hair Shadow Map", // name = "UTS Hair Shadow Map",
targetColorBuffer = CustomPass.TargetBuffer.None, // targetColorBuffer = CustomPass.TargetBuffer.None,
targetDepthBuffer = CustomPass.TargetBuffer.None, // targetDepthBuffer = CustomPass.TargetBuffer.None,
}; //};
_outlinePass = new() _outlinePass = new()
{ {
name = "UTS Outline", name = "UTS Outline",
targetColorBuffer = CustomPass.TargetBuffer.None, targetColorBuffer = CustomPass.TargetBuffer.Camera,
targetDepthBuffer = CustomPass.TargetBuffer.None, targetDepthBuffer = CustomPass.TargetBuffer.Camera,
}; };
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeRendering, _utsPass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeRendering, _utsPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _hairShadowPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass);
NotifyRendererSettingChanged(); NotifyRendererSettingChanged();
@@ -56,23 +55,21 @@ namespace Misaki.HdrpToon
public static void UnregisterGlobalCustomPass() public static void UnregisterGlobalCustomPass()
{ {
CustomPassVolume.UnregisterGlobalCustomPass(_utsPass); CustomPassVolume.UnregisterGlobalCustomPass(_utsPass);
CustomPassVolume.UnregisterGlobalCustomPass(_hairShadowPass);
CustomPassVolume.UnregisterGlobalCustomPass(_outlinePass); CustomPassVolume.UnregisterGlobalCustomPass(_outlinePass);
} }
public static void NotifyRendererSettingChanged() public static void NotifyRendererSettingChanged()
{ {
if (_hairShadowPass == null || _outlinePass == null) if (_utsPass == null || _outlinePass == null)
{ {
return; return;
} }
_hairShadowPass.enabled = _renderSetting.hairShadowSetting.enable; _utsPass.EnableHairShadow = _renderSetting.hairShadowSetting.enable;
_hairShadowPass.CurrentShadowQuality = _renderSetting.hairShadowSetting.shadowQuality; _utsPass.HairShadowQuality = _renderSetting.hairShadowSetting.quality;
if (!_renderSetting.hairShadowSetting.enable)
{ _utsPass.EnableHairBlending = _renderSetting.hairBlendingSetting.enable;
_hairShadowPass.Release(); _utsPass.HairBlendingQuality = _renderSetting.hairBlendingSetting.quality;
}
_outlinePass.enabled = _renderSetting.outlineSetting.enable; _outlinePass.enabled = _renderSetting.outlineSetting.enable;
} }