8 Commits

Author SHA1 Message Date
Misaki
e6b58cb321 Added UtsAreaLight.hlsl;
Fixed the problem that the appearence of direct diffuse is incorrect when area light intensity is low.

Changed the file name of PBR.hlsl to UtsPBR.hlsl
Changed the file name of EnvLighting.hlsl to UtsEnvLighting.hlsl
2025-01-18 14:14:00 +09:00
Misaki
12a03e9c3c Added UTSPolygonFormFactor and UTSComputeEdgeFactor 2025-01-17 18:47:37 +09:00
Misaki
b838223551 Changed area light calculation, need feature clean up 2025-01-17 18:45:41 +09:00
Misaki
b1ef8afc8d Update version to 2.1.0; 2025-01-09 15:32:35 +09:00
75a71635a0 Merge pull request 'feature/hair-eye-blending' (#1) from feature/hair-eye-blending into main
Reviewed-on: #1
2025-01-09 06:29:07 +00:00
Misaki
d47641e5e2 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;
2025-01-09 07:58:06 +09:00
Misaki
9290223624 Merge branch 'main' of https://git.personalnas.com/Misaki/com.misaki.hdrp-toon into feature/hair-eye-blending
# Conflicts:
#	README.md
2025-01-08 23:20:17 +09:00
Misaki
140734dc06 Update README; 2024-12-16 19:28:18 +09:00
27 changed files with 918 additions and 462 deletions

View File

@@ -2,6 +2,20 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [2.1.0] - 09-Jan-2025
### Added
- Added HairBlending shader pass;
- Added HairBlendingSetting in UTSRenderPassSetting;
- Added MaterialType to UTS;
- Added MaterialFeature scope to UTS material editor;
### Changed
- Merged HairBlendingPass and HairShadowPass into UTSPass;
### Fixed
- Fixed the bug that character box light can not update rotation correctly according to bound light source;
## [2.0.5] - 08-Jan-2025 ## [2.0.5] - 08-Jan-2025
### Added ### Added

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,12 +9,17 @@ 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;
private SerializedProperty _hairShadowSetting;
private SerializedProperty _hairBlendingSetting;
private SerializedProperty _outlineSetting;
public UTSRendererSettingProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null) : base(path, scopes, keywords) public UTSRendererSettingProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null) : base(path, scopes, keywords)
{ {
} }
@@ -22,21 +27,26 @@ namespace Misaki.HdrpToon.Editor
public override void OnActivate(string searchContext, VisualElement rootElement) public override void OnActivate(string searchContext, VisualElement rootElement)
{ {
_customSettings = UTSRenderPassSettings.GetSerializedSettings(); _customSettings = UTSRenderPassSettings.GetSerializedSettings();
_hairShadowSetting = _customSettings.FindProperty("hairShadowSetting");
_hairBlendingSetting = _customSettings.FindProperty("hairBlendingSetting");
_outlineSetting = _customSettings.FindProperty("outlineSetting");
} }
public override void OnGUI(string searchContext) public override void OnGUI(string searchContext)
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline); EditorGUILayout.PropertyField(_hairShadowSetting, Styles.hairShadow);
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow); EditorGUILayout.PropertyField(_hairBlendingSetting, Styles.hairBlending);
EditorGUILayout.PropertyField(_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()

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) <year> <copyright holders> Copyright (c) 2024 Enjie Huang
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

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

@@ -17,19 +17,21 @@ namespace Misaki.HdrpToon
private bool _initialized = false; private bool _initialized = false;
private bool _srpCallbackInitialized = false; private bool _srpCallbackInitialized = false;
[SerializeField]
private HDAdditionalLightData _bindingSourceLightData; private HDAdditionalLightData _bindingSourceLightData;
[SerializeField]
private HDAdditionalLightData _targetBoxLightData; private HDAdditionalLightData _targetBoxLightData;
[SerializeField]
private uint _layerMask; private uint _layerMask;
[SerializeField]
private Light _bindingSourceLight; private Light _bindingSourceLight;
[SerializeField]
private Light _targetBoxLight; private Light _targetBoxLight;
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 +66,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 +94,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 +123,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;
}
} }
} }
@@ -170,11 +164,6 @@ namespace Misaki.HdrpToon
Release(); Release();
} }
private void UpdateObjectLightLayers()
{
Initialize();
}
internal static GameObject CreateBoxLight(Transform transform) internal static GameObject CreateBoxLight(Transform transform)
{ {
if (transform == null) if (transform == null)
@@ -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

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a528382509a1bca4b9da190eb68e40d4
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -2,6 +2,8 @@
//nobuyuki@unity3d.com //nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP) //toshiyuki@unity3d.com (Universal RP/HDRP)
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
#if SHADERPASS != SHADERPASS_FORWARD #if SHADERPASS != SHADERPASS_FORWARD
#error SHADERPASS_is_not_correctly_define #error SHADERPASS_is_not_correctly_define
#endif #endif
@@ -14,7 +16,8 @@
#endif #endif
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
#include "EnvLighting.hlsl" #include "UtsEnvLighting.hlsl"
#include "UtsAreaLight.hlsl"
#include "HDRPToonFunction.hlsl" #include "HDRPToonFunction.hlsl"
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
@@ -194,7 +197,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;
@@ -503,7 +506,6 @@ void Frag(PackedVaryingsToPS packedInput,
uint v_lightListOffset = 0; uint v_lightListOffset = 0;
uint v_lightIdx = lightStart; uint v_lightIdx = lightStart;
float channelAlpha = 0.0f;
[loop] // vulkan shader compiler can not unroll. [loop] // vulkan shader compiler can not unroll.
while (v_lightListOffset < lightCount) while (v_lightListOffset < lightCount)
{ {
@@ -530,14 +532,14 @@ void Frag(PackedVaryingsToPS packedInput,
float4 distances; // {d, d^2, 1/d, d_proj} float4 distances; // {d, d^2, 1/d, d_proj}
GetPunctualLightVectors(posInput.positionWS, s_lightData, lightDirection, distances); GetPunctualLightVectors(posInput.positionWS, s_lightData, lightDirection, distances);
float4 lightColor = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirection, distances); float4 lightColor = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirection, distances);
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb) * lightColor.a; float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb);
const float notDirectional = 1.0f; const float notDirectional = 1.0f;
UTSLightData utsLightData; UTSLightData utsLightData;
utsLightData.lightColor = additionalLightColor; utsLightData.lightColor = additionalLightColor;
utsLightData.lightDirection = lightDirection; utsLightData.lightDirection = lightDirection;
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer; utsLightData.diffuseDimmer = saturate(s_lightData.diffuseDimmer * lightColor.a);
utsLightData.specularDimmer = s_lightData.specularDimmer; utsLightData.specularDimmer = saturate(s_lightData.specularDimmer * lightColor.a);
utsLightData.shadowTint = s_lightData.shadowTint; utsLightData.shadowTint = s_lightData.shadowTint;
utsLightData.penumbraTint = s_lightData.penumbraTint; utsLightData.penumbraTint = s_lightData.penumbraTint;
@@ -635,13 +637,13 @@ void Frag(PackedVaryingsToPS packedInput,
float4 ltcValue; float4 ltcValue;
// Diffuse // Diffuse
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f, s_lightData.cookieMode, s_lightData.cookieScaleOffset); ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f, true, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
//utsLightData.diffuseDimmer *= ltcValue.a * intensity; utsLightData.diffuseDimmer *= saturate(ltcValue.a * intensity);
utsLightData.lightColor *= ltcValue.rgb * ltcValue.a * intensity; utsLightData.lightColor *= ltcValue.rgb;
// Specular // Specular
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness, s_lightData.cookieMode, s_lightData.cookieScaleOffset); ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness, false, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
utsLightData.specularDimmer *= ltcValue.a * intensity; utsLightData.specularDimmer *= saturate(ltcValue.a * intensity);
if (isRectLight) if (isRectLight)
{ {
@@ -670,162 +672,6 @@ void Frag(PackedVaryingsToPS packedInput,
//utsAggregateLighting.directDiffuse += intensity; //utsAggregateLighting.directDiffuse += intensity;
#endif #endif
/*
if(s_lightData.lightType == GPULIGHTTYPE_RECTANGLE)
{
#if SHADEROPTIONS_BARN_DOOR
// Apply the barn door modification to the light data
RectangularLightApplyBarnDoor(s_lightData, posInput.positionWS);
#endif
if (dot(s_lightData.forward, unL) < FLT_EPS)
{
float3x3 lightToWorld = float3x3(s_lightData.right, s_lightData.up, -s_lightData.forward);
unL = mul(unL, transpose(lightToWorld));
float halfWidth = s_lightData.size.x * 0.5;
float halfHeight = s_lightData.size.y * 0.5;
float range = s_lightData.range;
float3 invHalfDim = rcp(float3(range + halfWidth, range + halfHeight, range));
float intensity;
// Compute the light attenuation.
#ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#else
// The attenuation volume is an axis-aligned box s.t.
// hX = (r + w / 2), hY = (r + h / 2), hZ = r.
intensity = BoxDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#endif
if(intensity != 0.0f)
{
utsLightData.diffuseDimmer *= intensity;
utsLightData.specularDimmer *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
s_lightData.positionRWS -= posInput.positionWS;
float4x3 lightVerts;
// TODO: some of this could be precomputed.
lightVerts[0] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * -halfHeight; // LL
lightVerts[1] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * halfHeight; // UL
lightVerts[2] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * halfHeight; // UR
lightVerts[3] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * -halfHeight; // LR
// Rotate the endpoints into the local coordinate system.
lightVerts = mul(lightVerts, transpose(preLightData.orthoBasisViewNormal));
float3 ltcValue;
// Evaluate the diffuse part
// Polygon irradiance in the transformed configuration.
float4x3 LD = mul(lightVerts, preLightData.ltcTransformDiffuse);
float3 formFactorD;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorD = PolygonFormFactor(LD, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorD);
#else
ltcValue = PolygonIrradiance(LD);
#endif
utsLightData.diffuseDimmer *= ltcValue;
// Evaluate the specular part
// Polygon irradiance in the transformed configuration.
float4x3 LS = mul(lightVerts, preLightData.ltcTransformSpecular);
float3 formFactorS;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorS = PolygonFormFactor(LS, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorS);
#else
ltcValue = PolygonIrradiance(LS);
#endif
utsLightData.specularDimmer *= ltcValue;
//Evaluate the shadow part
float shadow;
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
{
shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex);
}
else
#endif
{
shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
}
context.shadowValue = shadow;
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
}
else if(s_lightData.lightType == GPULIGHTTYPE_TUBE)
{
float len = s_lightData.size.x;
float3 T = s_lightData.right;
// Pick the major axis of the ellipsoid.
float3 axis = s_lightData.right;
// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.
// TODO: This could be precomputed.
float range = s_lightData.range;
float invAspectRatio = saturate(range / (range + (0.5 * len)));
// Compute the light attenuation.
float intensity = EllipsoidalDistanceAttenuation(unL, axis, invAspectRatio, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
if(intensity != 0.0f)
{
utsLightData.diffuseDimmer *= intensity;
utsLightData.specularDimmer *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
s_lightData.positionRWS -= posInput.positionWS;
// TODO: some of this could be precomputed.
float3 P1 = s_lightData.positionRWS - T * (0.5 * len);
float3 P2 = s_lightData.positionRWS + T * (0.5 * len);
// Rotate the endpoints into the local coordinate system.
P1 = mul(P1, transpose(preLightData.orthoBasisViewNormal));
P2 = mul(P2, transpose(preLightData.orthoBasisViewNormal));
// Compute the binormal in the local coordinate system.
float3 B = normalize(cross(P1, P2));
float ltcValue;
// Evaluate the diffuse part
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
utsLightData.diffuseDimmer *= ltcValue;
// Evaluate the specular part
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
utsLightData.specularDimmer *= ltcValue;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
*/
} }
s_lightData = FetchLight(lightStart, min(++i, last)); s_lightData = FetchLight(lightStart, min(++i, last));
@@ -878,7 +724,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 +756,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 +767,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.
@@ -936,8 +786,8 @@ void Frag(PackedVaryingsToPS packedInput,
#endif #endif
// Ambient // Ambient
utsAggregateLighting.indirectDiffuse = ComputeIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity; utsAggregateLighting.indirectDiffuse = EvaluateIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity;
utsAggregateLighting.indirectSpecular = ComputeIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity; utsAggregateLighting.indirectSpecular = EvaluateIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity;
float3 finalColorWoEmissive = AccumulateAggregateLighting(utsAggregateLighting); float3 finalColorWoEmissive = AccumulateAggregateLighting(utsAggregateLighting);
@@ -958,29 +808,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

@@ -2,8 +2,9 @@
//nobuyuki@unity3d.com //nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP) //toshiyuki@unity3d.com (Universal RP/HDRP)
#include "PBR.hlsl" #include "UtsPBR.hlsl"
void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLightData utsLightData, SurfaceData surfaceData, BSDFData bsdfData, int lightType, float3 i_normalDir, float notDirectional, out float channelOutAlpha, inout UTSAggregateLighting utsAggregateLighting) void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLightData utsLightData, SurfaceData surfaceData, BSDFData bsdfData, int lightType, float3 i_normalDir, float notDirectional,
out float channelOutAlpha, inout UTSAggregateLighting utsAggregateLighting)
{ {
channelOutAlpha = 1.0f; channelOutAlpha = 1.0f;
@@ -48,35 +49,38 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
shadowAttenuation = saturate(shadowAttenuation); shadowAttenuation = saturate(shadowAttenuation);
#endif #endif
float _HalfLambert_var = 0.5 * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5;
//v.2.0.5: //v.2.0.5:
float3 addPassLightColor; float3 addPassLightColor;
if (lightType == GPULIGHTTYPE_TUBE) if (lightType == GPULIGHTTYPE_TUBE)
{ {
addPassLightColor = (0.5f * (preLightData.diffuseFGD * utsLightData.diffuseDimmer) + 0.5f) / PI * additionalLightColor.rgb; addPassLightColor = (0.5f * preLightData.diffuseFGD + 0.5f) / PI * additionalLightColor.rgb;
} }
else if (lightType == GPULIGHTTYPE_RECTANGLE) else if (lightType == GPULIGHTTYPE_RECTANGLE)
{ {
addPassLightColor = ((preLightData.diffuseFGD * utsLightData.diffuseDimmer)) * additionalLightColor.rgb; addPassLightColor = preLightData.diffuseFGD * additionalLightColor.rgb;
} }
else else
{ {
addPassLightColor = (0.5f * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5f) * additionalLightColor.rgb ; addPassLightColor = _HalfLambert_var * additionalLightColor.rgb;
} }
float pureIntencity = max(0.001, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b)); float pureIntensity = max(0.001, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b));
float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntencity), notDirectional), _Is_Filter_LightColor)); float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntensity), notDirectional), _Is_Filter_LightColor));
float3 halfDirection = normalize(viewDirection + lightDirection); // has to be recalced here. float3 halfDirection = normalize(viewDirection + lightDirection); // has to be recalced here.
//v.2.0.5:
//v.2.0.5: //v.2.0.5:
_1st_ShadeColor_Step = saturate(_1st_ShadeColor_Step + _StepOffset); _1st_ShadeColor_Step = saturate(_1st_ShadeColor_Step + _StepOffset);
_2nd_ShadeColor_Step = saturate(_2nd_ShadeColor_Step + _StepOffset); _2nd_ShadeColor_Step = saturate(_2nd_ShadeColor_Step + _StepOffset);
// //
//v.2.0.5: If Added lights is directional, set 0 as _LightIntensity //v.2.0.5: If Added lights is directional, set 0 as _LightIntensity
float _LightIntensity = lerp(0, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b), notDirectional); float _LightIntensity = lerp(0, pureIntensity, notDirectional);
//v.2.0.5: Filtering the high intensity zone of PointLights //v.2.0.5: Filtering the high intensity zone of PointLights
float3 Set_LightColor = lightColor; float3 Set_LightColor = lightColor;
// //
float3 Set_BaseColor = lerp((_BaseColor.rgb * _MainTex_var.rgb * _LightIntensity), ((_BaseColor.rgb * _MainTex_var.rgb) * Set_LightColor), _Is_LightColor_Base); float3 Set_BaseColor = lerp((_BaseColor.rgb * _MainTex_var.rgb * _LightIntensity), ((_BaseColor.rgb * _MainTex_var.rgb) * Set_LightColor), _Is_LightColor_Base);
#ifdef UTS_LAYER_VISIBILITY #ifdef UTS_LAYER_VISIBILITY
float Set_BaseColorAlpha = _BaseColorVisible; float Set_BaseColorAlpha = _BaseColorVisible;
float4 overridingColor = lerp(_BaseColorMaskColor, float4(_BaseColorMaskColor.w, _BaseColorMaskColor.w, _BaseColorMaskColor.w, 1.0f), _ComposerMaskMode); float4 overridingColor = lerp(_BaseColorMaskColor, float4(_BaseColorMaskColor.w, _BaseColorMaskColor.w, _BaseColorMaskColor.w, 1.0f), _ComposerMaskMode);
@@ -85,6 +89,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
Set_BaseColor *= _BaseColorVisible; Set_BaseColor *= _BaseColorVisible;
#endif //#ifdef UTS_LAYER_VISIBILITY #endif //#ifdef UTS_LAYER_VISIBILITY
//v.2.0.5 //v.2.0.5
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st); float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 Set_1st_ShadeColor = lerp((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb * _LightIntensity), ((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_1st_Shade); float3 Set_1st_ShadeColor = lerp((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb * _LightIntensity), ((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_1st_Shade);
@@ -97,6 +102,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
} }
float Set_1st_ShadeAlpha = _FirstShadeVisible; float Set_1st_ShadeAlpha = _FirstShadeVisible;
#endif //#ifdef UTS_LAYER_VISIBILITY //v.2.0.5 #endif //#ifdef UTS_LAYER_VISIBILITY //v.2.0.5
//v.2.0.5 //v.2.0.5
float4 _2nd_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_2nd_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _2nd_ShadeMap)), _1st_ShadeMap_var, _Use_1stAs2nd); float4 _2nd_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_2nd_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _2nd_ShadeMap)), _1st_ShadeMap_var, _Use_1stAs2nd);
float3 Set_2nd_ShadeColor = lerp((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb * _LightIntensity), ((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_2nd_Shade); float3 Set_2nd_ShadeColor = lerp((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb * _LightIntensity), ((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_2nd_Shade);
@@ -110,8 +116,6 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
} }
#endif //#ifdef UTS_LAYER_VISIBILITY #endif //#ifdef UTS_LAYER_VISIBILITY
float _HalfLambert_var = 0.5 * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5;
// //v.2.0.5: // //v.2.0.5:
//SGM //SGM
//v.2.0.6 //v.2.0.6
@@ -119,10 +123,10 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
//v.2.0.6 //v.2.0.6
//Minmimum value is same as the Minimum Feather's value with the Minimum Step's value as threshold. //Minmimum value is same as the Minimum Feather's value with the Minimum Step's value as threshold.
float _SystemShadowsLevel_var = (shadowAttenuation*0.5)+0.5+_Tweak_SystemShadowsLevel > 0.001 ? (shadowAttenuation*0.5)+0.5+_Tweak_SystemShadowsLevel : 0.0001; float _SystemShadowsLevel_var = (shadowAttenuation * 0.5) + 0.5 + _Tweak_SystemShadowsLevel > 0.001 ? (shadowAttenuation * 0.5) + 0.5 + _Tweak_SystemShadowsLevel : 0.0001;
float _ShadingGradeMapLevel_var = _ShadingGradeMap_var.r < 0.95 ? _ShadingGradeMap_var.r + _Tweak_ShadingGradeMapLevel : 1; float _ShadingGradeMapLevel_var = _ShadingGradeMap_var.r < 0.95 ? _ShadingGradeMap_var.r + _Tweak_ShadingGradeMapLevel : 1;
float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var)*lerp( _HalfLambert_var, (_HalfLambert_var*saturate(_SystemShadowsLevel_var)), _Set_SystemShadowsToBase ); float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var)*lerp( _HalfLambert_var, (_HalfLambert_var * saturate(_SystemShadowsLevel_var)), _Set_SystemShadowsToBase );
//float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var) * lerp(_HalfLambert_var, (_HalfLambert_var * saturate(1.0 + _Tweak_SystemShadowsLevel)), _Set_SystemShadowsToBase); //float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var) * lerp(_HalfLambert_var, (_HalfLambert_var * saturate(1.0 + _Tweak_SystemShadowsLevel)), _Set_SystemShadowsToBase);
@@ -131,8 +135,8 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
float _2ndColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0f, max(_SecondShadeOverridden, _ComposerMaskMode)); float _2ndColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0f, max(_SecondShadeOverridden, _ComposerMaskMode));
// //
float Set_FinalShadowMask = saturate((1.0 + ((Set_ShadingGrade - (_1st_ShadeColor_Step - _1stColorFeatherForMask)) * (0.0 - 1.0)) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - _1stColorFeatherForMask)))); float Set_FinalShadowMask = saturate(1.0 + (Set_ShadingGrade - (_1st_ShadeColor_Step - _1stColorFeatherForMask)) * (0.0 - 1.0) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - _1stColorFeatherForMask)));
float Set_ShadeShadowMask = saturate((1.0 + ((Set_ShadingGrade - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)) * (0.0 - 1.0)) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)))); // 1st and 2nd Shades Mask float Set_ShadeShadowMask = saturate(1.0 + (Set_ShadingGrade - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)) * (0.0 - 1.0) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask))); // 1st and 2nd Shades Mask
//SGM //SGM
@@ -147,11 +151,13 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
Set_ShadeShadowMask Set_ShadeShadowMask
), ),
Set_FinalShadowMask); Set_FinalShadowMask);
#ifdef UTS_LAYER_VISIBILITY #ifdef UTS_LAYER_VISIBILITY
float Set_2nd_ShadeAlpha = _SecondShadeVisible; float Set_2nd_ShadeAlpha = _SecondShadeVisible;
channelOutAlpha = channelOutAlpha =
lerp(Set_BaseColorAlpha, lerp(Set_1st_ShadeAlpha, Set_2nd_ShadeAlpha, Set_ShadeShadowMask), Set_FinalShadowMask); lerp(Set_BaseColorAlpha, lerp(Set_1st_ShadeAlpha, Set_2nd_ShadeAlpha, Set_ShadeShadowMask), Set_FinalShadowMask);
#endif #endif
//v.2.0.6: Add HighColor if _Is_Filter_HiCutPointLightColor is False //v.2.0.6: Add HighColor if _Is_Filter_HiCutPointLightColor is False
float4 _Set_HighColorMask_var = tex2D(_Set_HighColorMask, TRANSFORM_TEX(Set_UV0, _Set_HighColorMask)); float4 _Set_HighColorMask_var = tex2D(_Set_HighColorMask, TRANSFORM_TEX(Set_UV0, _Set_HighColorMask));
@@ -224,22 +230,25 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
//Specular Term //Specular Term
float3 specularTerm = 0; float3 specularTerm = 0;
#ifndef _PBR_Mode_OFF
if(lightType == GPULIGHTTYPE_RECTANGLE || lightType == GPULIGHTTYPE_TUBE) if(lightType == GPULIGHTTYPE_RECTANGLE || lightType == GPULIGHTTYPE_TUBE)
{ {
specularTerm = preLightData.specularFGD * Set_LightColor * utsLightData.specularDimmer; specularTerm = preLightData.specularFGD * Set_LightColor;
#ifdef _PBR_Mode_TOON #ifdef _PBR_Mode_TOON
specularTerm = StepFeatherToon(specularTerm, _ToonSpecularStep, _ToonSpecularFeather); specularTerm = StepFeatherToon(specularTerm, _ToonSpecularStep, _ToonSpecularFeather);
#endif #endif
} }
else else
{ {
specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * Set_LightColor * utsLightData.specularDimmer; specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * Set_LightColor;
} }
#endif
specularTerm = specularTerm * (1.0 - Set_FinalShadowMask) * PI * surfaceData.specularColor; specularTerm = specularTerm * (1.0 - Set_FinalShadowMask) * PI * surfaceData.specularColor;
diffuseTerm = diffuseTerm * albedoIntensity; diffuseTerm = diffuseTerm * albedoIntensity;
utsAggregateLighting.directDiffuse += diffuseTerm; utsAggregateLighting.directDiffuse += diffuseTerm * utsLightData.diffuseDimmer;
utsAggregateLighting.directSpecular += specularTerm; utsAggregateLighting.directSpecular += specularTerm * utsLightData.specularDimmer;
#endif // _SDFShadow #endif // _SDFShadow
} }

View File

@@ -0,0 +1,165 @@
#ifndef UTS_AREA_LIGHT_INLCUDE
#define UTS_AREA_LIGHT_INLCUDE
// The output is *not* normalized by the factor of 1/TWO_PI (this is done by the PolygonFormFactor function).
real3 UTS_ComputeEdgeFactor(real3 V1, real3 V2)
{
real V1oV2 = dot(V1, V2);
real3 V1xV2 = cross(V1, V2); // Plane normal (tangent to the unit sphere)
real sqLen = saturate(1 - V1oV2 * V1oV2); // length(V1xV2) = abs(sin(angle))
real rcpLen = rsqrt(max(FLT_EPS, sqLen)); // Make sure it is finite
#if 0
real y = rcpLen * acos(V1oV2);
#else
// Let y[x_] = ArcCos[x] / Sqrt[1 - x^2].
// Range reduction: since ArcCos[-x] == Pi - ArcCos[x], we only need to consider x on [0, 1].
real x = abs(V1oV2);
// Limit[y[x], x -> 1] == 1,
// Limit[y[x], x -> 0] == Pi/2.
// The approximation is exact at the endpoints of [0, 1].
// Max. abs. error on [0, 1] is 1.33e-6 at x = 0.0036.
// Max. rel. error on [0, 1] is 8.66e-7 at x = 0.0037.
real y = HALF_PI + x * (-0.99991 + x * (0.783393 + x * (-0.649178 + x * (0.510589 + x * (-0.326137 + x * (0.137528 + x * -0.0270813))))));
if (V1oV2 < 0)
{
y = rcpLen * PI - y;
}
#endif
return V1xV2 * y;
}
// Input: 3-5 vertices in the coordinate frame centered at the shaded point.
// Output: signed vector irradiance.
// No horizon clipping is performed.
real3 UTS_PolygonFormFactor(real4x3 L, real3 L4, uint n, bool isDiffuse)
{
// The length cannot be zero since we have already checked
// that the light has a non-zero effective area,
// and thus its plane cannot pass through the origin.
L[0] = normalize(L[0]);
L[1] = normalize(L[1]);
L[2] = normalize(L[2]);
switch (n)
{
case 3:
L[3] = L[0];
break;
case 4:
L[3] = normalize(L[3]);
L4 = L[0];
break;
case 5:
L[3] = normalize(L[3]);
L4 = normalize(L4);
break;
}
// If the magnitudes of a pair of edge factors are
// nearly the same, catastrophic cancellation may occur:
// https://en.wikipedia.org/wiki/Catastrophic_cancellation
// For the same reason, the value of the cross product of two
// nearly collinear vectors is prone to large errors.
// Therefore, the algorithm is inherently numerically unstable
// for area lights that shrink to a line (or a point) after
// projection onto the unit sphere.
real3 F = UTS_ComputeEdgeFactor(L[0], L[1]);
F += UTS_ComputeEdgeFactor(L[1], L[2]);
F += UTS_ComputeEdgeFactor(L[2], L[3]);
if (n >= 4)
F += UTS_ComputeEdgeFactor(L[3], L4);
if (n == 5)
F += UTS_ComputeEdgeFactor(L4, L[0]);
return lerp(INV_TWO_PI * F, PI * F, isDiffuse); // The output may be projected onto the tangent plane (F.z) to yield signed irradiance.
}
// See "Real-Time Area Lighting: a Journey from Research to Production", slide 102.
// Turns out, despite the authors claiming that this function "calculates an approximation of
// the clipped sphere form factor", that is simply not true.
// First of all, above horizon, the function should then just return 'F.z', which it does not.
// Secondly, if we use the correct function called DiffuseSphereLightIrradiance(), it results
// in severe light leaking if the light is placed vertically behind the camera.
// So this function is clearly a hack designed to work around these problems.
real UTS_PolygonIrradianceFromVectorFormFactor(float3 F)
{
float l = length(F);
return max(0, (l * l) / (l + 1));
}
// Expects non-normalized vertex positions.
// Output: F is the signed vector irradiance.
real UTS_PolygonIrradiance(real4x3 L, bool isDiffuse, out real3 F)
{
//APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
F = UTS_PolygonFormFactor(L, float3(0,0,1), 4, isDiffuse);
return UTS_PolygonIrradianceFromVectorFormFactor(F); // Accounts for the horizon.
}
float4 UTS_EvaluateLTC_Area(bool isRectLight, float3 center, float3 right, float3 up, float halfLength, float halfHeight,
float3x3 invM, float perceptualRoughness, bool isDiffuse, int cookieMode, float4 cookieScaleOffset)
{
float3 ortho = cross(center, right);
float orthoSq = dot(ortho, ortho);
// Check whether the light is in a vertical orientation.
bool quit = (orthoSq == 0);
// Check whether the light is entirely below the surface.
// We must test twice, since a linear transformation
// may bring the light above the surface (a side-effect).
quit = quit || (center.z + halfLength * abs(right.z) + halfHeight * abs(up.z) <= 0);
float4 ltcValue = float4(1, 1, 1, 0);
if (quit && !isDiffuse)
{
return ltcValue;
}
// Perform a sparse matrix multiplication.
float3 C = mul(invM, center);
float3 A = mul(invM, right);
float3 B = mul(invM, up);
// Check whether the light is entirely below the surface.
// We must test twice, since a linear transformation
// may bring the light below the surface (as expected).
if (C.z + halfLength * abs(A.z) + halfHeight * abs(B.z) <= 0 && !isDiffuse)
{
return ltcValue;
}
if (isRectLight)
{
float4x3 lightVerts;
lightVerts[0] = C - halfLength * A - halfHeight * B; // LL
lightVerts[1] = lightVerts[0] + (2 * halfHeight) * B; // UL
lightVerts[2] = lightVerts[1] + (2 * halfLength) * A; // UR
lightVerts[3] = lightVerts[2] - (2 * halfHeight) * B; // LR
float3 formFactor;
// Polygon irradiance in the transformed configuration.
ltcValue.a = UTS_PolygonIrradiance(lightVerts, isDiffuse, formFactor);
if (cookieMode != COOKIEMODE_NONE)
{
ltcValue.rgb = SampleAreaLightCookie(cookieScaleOffset, lightVerts, formFactor, perceptualRoughness);
}
}
else // Line light
{
float w = ComputeLineWidthFactor(invM, ortho, orthoSq);
ltcValue.a = I_diffuse_line(C, A, halfLength) * w;
}
return ltcValue;
}
#endif

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: afada69a218dd594ea0f17e7c639c533
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,3 +1,6 @@
#ifndef UTS_ENV
#define UTS_ENV
// _preIntegratedFGD and _CubemapLD are unique for each BRDF // _preIntegratedFGD and _CubemapLD are unique for each BRDF
IndirectLighting EvaluateBSDF_Env(LightLoopContext lightLoopContext, IndirectLighting EvaluateBSDF_Env(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, float3 V, PositionInputs posInput,
@@ -127,7 +130,7 @@ float3 ComputeFresnelLerp(float3 c0, float3 c1, float cosA)
return lerp(c0, c1, t); return lerp(c0, c1, t);
} }
float3 ComputeIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3 V) float3 EvaluateIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3 V)
{ {
float3 indirectDiffuse = 0.0; float3 indirectDiffuse = 0.0;
@@ -184,7 +187,7 @@ float3 ComputeIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3
return indirectDiffuse; return indirectDiffuse;
} }
float3 ComputeIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, SurfaceData surfaceData, BuiltinData builtinData, float3 V) float3 EvaluateIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, SurfaceData surfaceData, BuiltinData builtinData, float3 V)
{ {
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON) #if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
return 0; return 0;
@@ -235,3 +238,5 @@ float3 ComputeIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs
return indirectSpecular; return indirectSpecular;
#endif #endif
} }
#endif

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

@@ -1,9 +1,12 @@
#ifndef UTS_PBR
#define UTS_PBR
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779) #define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
float3 schlick(float f0, float hl) { float3 schlick(float f0, float hl) {
real x = 1.0 - hl; float x = 1.0 - hl;
real x2 = x * x; float x2 = x * x;
real x5 = x * x2 * x2; float x5 = x * x2 * x2;
return (1.0 - f0) * x5 + f0; return (1.0 - f0) * x5 + f0;
} }
@@ -187,3 +190,4 @@ half3 FitWithCurveApprox(half NdotL, half Curvature)
} }
#endif #endif
#endif

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

@@ -19,5 +19,19 @@
#define UTS_BSDFDEBUG_HAIR_ROUGHNESS (9) #define UTS_BSDFDEBUG_HAIR_ROUGHNESS (9)
#define UTS_BSDFDEBUG_NORMAL_WS (10) #define UTS_BSDFDEBUG_NORMAL_WS (10)
//
// Unity.Toonshader.UTS_LightingDebug: static fields
//
#define UTS_LIGHTINGDEBUG_NONE (0)
#define UTS_LIGHTINGDEBUG_DIFFUSE_LIGHTING (1)
#define UTS_LIGHTINGDEBUG_SPECULAR_LIGHTING (2)
#define UTS_LIGHTINGDEBUG_DIRECT_DIFFUSE_LIGHTING (3)
#define UTS_LIGHTINGDEBUG_DIRECT_SPECULAR_LIGHTING (4)
#define UTS_LIGHTINGDEBUG_INDIRECT_DIFFUSE_LIGHTING (5)
#define UTS_LIGHTINGDEBUG_INDIRECT_SPECULAR_LIGHTING (6)
#define UTS_LIGHTINGDEBUG_INDIRECT_DIFFUSE_OCCLUSION (7)
#define UTS_LIGHTINGDEBUG_INDIRECT_SPECULAR_OCCLUSION (8)
#define UTS_LIGHTINGDEBUG_EMISSION (9)
#endif #endif

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;
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "com.misaki.hdrp-toon", "name": "com.misaki.hdrp-toon",
"version": "2.0.5", "version": "2.1.0",
"displayName": "HDRP Toon", "displayName": "HDRP Toon",
"description": "A high quality toon shader for High Definition Render Pipeline(HDRP)", "description": "A high quality toon shader for High Definition Render Pipeline(HDRP)",
"changelogUrl": "https://git.personalnas.com/Misaki/hdrp-toon/src/branch/develop/CHANGELOG.md", "changelogUrl": "https://git.personalnas.com/Misaki/hdrp-toon/src/branch/develop/CHANGELOG.md",
@@ -17,7 +17,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.personalnas.com/Misaki/hdrp-toon.git" "url": "https://git.personalnas.com/Misaki/com.misaki.hdrp-toon.git"
}, },
"dependencies": { "dependencies": {
"com.unity.render-pipelines.high-definition": "17.0.0" "com.unity.render-pipelines.high-definition": "17.0.0"