Shader code cleanupand bug fix.

This commit is contained in:
2025-02-17 22:15:27 +09:00
parent eacbbc9b8b
commit 4ce84572d0
20 changed files with 375 additions and 467 deletions

View File

@@ -1,20 +0,0 @@
namespace Misaki.HdrpToon.Editor
{
internal static class UTSShaderGUIHelpers
{
public static ShadingMode GetShadingMode(this UTSShaderGUI shaderGUI)
{
return (ShadingMode)shaderGUI.GetUIScope<SurfaceOptionsScope>().FindProperty("_Shading_Mode").floatValue;
}
public static PBRMode GetPBRMode(this UTSShaderGUI shaderGUI)
{
return (PBRMode)shaderGUI.GetUIScope<SurfaceOptionsScope>().FindProperty("_PBR_Mode").floatValue;
}
public static bool HasFeature(this UTSShaderGUI shaderGUI, SurfaceFeature feature)
{
return ((SurfaceFeature)shaderGUI.GetUIScope<SurfaceOptionsScope>().FindProperty("_Surface_Features").floatValue & feature) != 0;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 4aa9e028e20a2014ab0e2a3ea6541f0e

View File

@@ -69,23 +69,24 @@ namespace Misaki.HdrpToon.Editor
{ {
editor.ShaderProperty(Properties.outlineState, Styles.outlineStateText); editor.ShaderProperty(Properties.outlineState, Styles.outlineStateText);
using var disabledScope = new EditorGUI.DisabledScope(!Properties.outlineState.GetBooleanValue()); if (Properties.outlineState.GetBooleanValue())
EditorGUILayout.Space();
editor.TexturePropertySingleLine(Styles.outlineWidthText, Properties.outlineWidthMap, Properties.outlineWidth);
editor.TexturePropertySingleLine(Styles.outlineColorText, Properties.outlineColorMap, Properties.outlineColor);
editor.ShaderProperty(Properties.albedoAffectOutline, Styles.albedoAffectOutlineText);
editor.ShaderProperty(Properties.skyColorAffectOutline, Styles.skyColorAffectOutlineText);
if (Properties.skyColorAffectOutline.GetBooleanValue())
{ {
using var skyColorIndentLevelScope = new EditorGUI.IndentLevelScope(); EditorGUILayout.Space();
editor.ShaderProperty(Properties.skyColorIntensity, Styles.skyColorIntensityText); editor.TexturePropertySingleLine(Styles.outlineWidthText, Properties.outlineWidthMap, Properties.outlineWidth);
} editor.TexturePropertySingleLine(Styles.outlineColorText, Properties.outlineColorMap, Properties.outlineColor);
editor.ShaderProperty(Properties.albedoAffectOutline, Styles.albedoAffectOutlineText);
editor.ShaderProperty(Properties.skyColorAffectOutline, Styles.skyColorAffectOutlineText);
if (Properties.skyColorAffectOutline.GetBooleanValue())
{
using var skyColorIndentLevelScope = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.skyColorIntensity, Styles.skyColorIntensityText);
}
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.ShaderProperty(Properties.fadeIn, Styles.fadeInText); editor.ShaderProperty(Properties.fadeIn, Styles.fadeInText);
editor.ShaderProperty(Properties.fadeOut, Styles.fadeOutText); editor.ShaderProperty(Properties.fadeOut, Styles.fadeOutText);
editor.ShaderProperty(Properties.useSmoothedNormal, Styles.useSmoothedNormalText); editor.ShaderProperty(Properties.useSmoothedNormal, Styles.useSmoothedNormalText);
}
} }
} }
} }

View File

@@ -3,6 +3,8 @@ using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.RimLight;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class RimLightScope : MaterialUIScope<ShaderGUIExpandable> public class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
@@ -10,67 +12,61 @@ namespace Misaki.HdrpToon.Editor
private static class Properties private static class Properties
{ {
public static MaterialProperty rimLightColor; public static MaterialProperty rimLightColor;
public static MaterialProperty rimLightStrength; public static MaterialProperty rimLightIntensity;
public static MaterialProperty screenSpaceRimLight;
public static MaterialProperty rimLightLevel; public static MaterialProperty rimLightLevel;
public static MaterialProperty colorBlendingMode; public static MaterialProperty rimLightClipping;
public static MaterialProperty adjustRimLightArea; public static MaterialProperty rimLightClippingLevel;
public static MaterialProperty rimLightFeatherOff;
public static MaterialProperty lightDirection; public static MaterialProperty lightBaseRimLight;
public static MaterialProperty lightDirectionRimLightLevel; public static MaterialProperty lightDirectionRimLightLevel;
public static MaterialProperty invertedDirectionRimLight;
public static MaterialProperty invertedRimLightColor; //public static MaterialProperty lightDirection;
public static MaterialProperty inversedRimLightLevel; //public static MaterialProperty invertedDirectionRimLight;
public static MaterialProperty invertedRimLightFeatherOff; //public static MaterialProperty invertedRimLightColor;
public static MaterialProperty rimLightMaskMap; //public static MaterialProperty inversedRimLightLevel;
public static MaterialProperty rimLightMaskLevel; //public static MaterialProperty invertedRimLightFeatherOff;
//public static MaterialProperty rimLightMaskMap;
//public static MaterialProperty rimLightMaskLevel;
} }
private static class Styles private static class Styles
{ {
public static readonly GUIContent rimLightColorText = public static readonly GUIContent rimLightColorText = new("Rim Light Color", "Specifies the color of rim light.");
new("Rim Light Color", "Specifies the color of rim light."); public static readonly GUIContent rimLightIntensityText = new("Rim Light Strength", "Specifies Rim Light strength.");
public static readonly GUIContent rimLightStrengthText = public static readonly GUIContent screenSpaceRimLightText = new("Screen Space Rim Light", "Enable to make the rim light width constant in screen space.");
new("Rim Light Strength", "Specifies Rim Light strength."); public static readonly GUIContent rimLightLevelText = new("Rim Light Level", "Specifies Rim Light power intensity.");
public static readonly GUIContent rimLightClippingText = new("Rim Light Clipping", "Enable to Clip the rim light at specific level");
public static readonly GUIContent rimLightClippingLevelText = new("Clipping Level", "The Clipping value of the rim light.");
public static readonly GUIContent rimLightLevelText = public static readonly GUIContent lightBaseRimLightText = new("Light Base Rim Light", "Enable to let rim light calculate per light.");
new("Rim Light Level", "Specifies Rim Light power intensity."); public static readonly GUIContent lightDirectionRimLightLevelText = new("Light Direction Level", "Specifies intensity of Rim Light in the light source direction,");
public static readonly GUIContent colorBlendingModeText = //public static readonly GUIContent lightDirectionText =
new("Color Blending Mode", "Rim light color blending mode. Multiply or Add."); // new("Light Direction",
// "When Enabled, rim light is generated only in the direction of the light source.");
public static readonly GUIContent adjustRimLightAreaText =
new("Adjust Rim Light Area", "Increasing this value narrows the area of influence of Rim Light.");
public static readonly GUIContent rimLightFeatherOffText = //public static readonly GUIContent invertedDirectionRimLightText =
new("Rim Light Feather Off", "Disable Rim light feather."); // new("Inverted Direction Rim Light", "Rim light from inverted/antipodean direction.");
public static readonly GUIContent lightDirectionText = //public static readonly GUIContent invertedRimLightColorText =
new("Light Direction", // new("Inverted Rim Light Color", "Specifies the color of inverted/antipodean rim light.");
"When Enabled, rim light is generated only in the direction of the light source.");
public static readonly GUIContent lightDirectionRimLightLevelText = //public static readonly GUIContent inversedRimLightLevelText =
new("Light Direction Rim Light Level", // new("Inversed Rim Light Level", "Specifies Inverted/Antipodean Rim Light Level.");
"Specifies intensity of Rim Light in the light source direction,");
public static readonly GUIContent invertedDirectionRimLightText = //public static readonly GUIContent invertedRimLightFeatherOffText =
new("Inverted Direction Rim Light", "Rim light from inverted/antipodean direction."); // new("Inverted Rim Light Feather Off", "Disable Inverted Rim light feather.");
public static readonly GUIContent invertedRimLightColorText = //public static readonly GUIContent rimLightMaskMapText = new("Rim Light Mask",
new("Inverted Rim Light Color", "Specifies the color of inverted/antipodean rim light."); // "Rim Light Mask : Texture(linear). The white part of the texture is displayed as Rim Light, and the black part is masked and not displayed.");
public static readonly GUIContent inversedRimLightLevelText = //public static readonly GUIContent rimLightMaskLevelText =
new("Inversed Rim Light Level", "Specifies Inverted/Antipodean Rim Light Level."); // new("Rim Light Mask Level",
// "-1 gives 0% for the Rim Light effect, 0 gives 100% for the Rim Light and Mask effect, 1 gives 100% for the Rim Light and 0% for the Mask effect.");
public static readonly GUIContent invertedRimLightFeatherOffText =
new("Inverted Rim Light Feather Off", "Disable Inverted Rim light feather.");
public static readonly GUIContent rimLightMaskMapText = new("Rim Light Mask",
"Rim Light Mask : Texture(linear). The white part of the texture is displayed as Rim Light, and the black part is masked and not displayed.");
public static readonly GUIContent rimLightMaskLevelText =
new("Rim Light Mask Level",
"-1 gives 0% for the Rim Light effect, 0 gives 100% for the Rim Light and Mask effect, 1 gives 100% for the Rim Light and 0% for the Mask effect.");
} }
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Rimlight; protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Rimlight;
@@ -79,50 +75,69 @@ namespace Misaki.HdrpToon.Editor
public override void LoadMaterialProperties() public override void LoadMaterialProperties()
{ {
Properties.rimLightColor = FindProperty("_RimLightColor"); Properties.rimLightColor = FindProperty(RIM_LIGHT_COLOR);
Properties.rimLightStrength = FindProperty("_RimLightStrength"); Properties.rimLightIntensity = FindProperty(RIM_LIGHT_INTENSITY);
Properties.rimLightLevel = FindProperty("_RimLightLevel");
Properties.colorBlendingMode = FindProperty("_Is_BlendAddToRimColor"); Properties.screenSpaceRimLight = FindProperty(SCREEN_SPACE_RIM_LIGHT);
Properties.adjustRimLightArea = FindProperty("_RimLight_InsideMask"); Properties.rimLightLevel = FindProperty(RIM_LIGHT_LEVEL);
Properties.rimLightFeatherOff = FindProperty("_RimLight_FeatherOff"); Properties.rimLightClipping = FindProperty(RIM_LIGHT_CLIPPING);
Properties.lightDirection = FindProperty("_LightDirection_MaskOn"); Properties.rimLightClippingLevel = FindProperty(RIM_LIGHT_CLIPPING_LEVEL);
Properties.lightDirectionRimLightLevel = FindProperty("_Tweak_LightDirection_MaskLevel");
Properties.invertedDirectionRimLight = FindProperty("_Add_Antipodean_RimLight"); Properties.lightBaseRimLight = FindProperty(LIGHT_BASE_RIM_LIGHT);
Properties.invertedRimLightColor = FindProperty("_Ap_RimLightColor"); Properties.lightDirectionRimLightLevel = FindProperty(LIGHT_DIRECTION_RIM_LIGHT_LEVEL);
Properties.inversedRimLightLevel = FindProperty("_Ap_RimLight_Power");
Properties.invertedRimLightFeatherOff = FindProperty("_Ap_RimLight_FeatherOff"); //Properties.lightDirection = FindProperty(LIGHT_DIRECTION);
Properties.rimLightMaskMap = FindProperty("_Set_RimLightMask"); //Properties.invertedDirectionRimLight = FindProperty(INVERTED_DIRECTION_RIM_LIGHT);
Properties.rimLightMaskLevel = FindProperty("_Tweak_RimLightMaskLevel"); //Properties.invertedRimLightColor = FindProperty(INVERTED_RIM_LIGHT_COLOR);
//Properties.inversedRimLightLevel = FindProperty(INVERSED_RIM_LIGHT_LEVEL);
//Properties.invertedRimLightFeatherOff = FindProperty(INVERTED_RIM_LIGHT_FEATHER_OFF);
//Properties.rimLightMaskMap = FindProperty(RIM_LIGHT_MASK_MAP);
//Properties.rimLightMaskLevel = FindProperty(RIM_LIGHT_MASK_LEVEL);
} }
protected override void DrawContent() protected override void DrawContent()
{ {
editor.ShaderProperty(Properties.rimLightColor, Styles.rimLightColorText); editor.ShaderProperty(Properties.rimLightColor, Styles.rimLightColorText);
editor.ShaderProperty(Properties.rimLightStrength, Styles.rimLightStrengthText); editor.ShaderProperty(Properties.rimLightIntensity, Styles.rimLightIntensityText);
editor.ShaderProperty(Properties.screenSpaceRimLight, Styles.screenSpaceRimLightText);
editor.ShaderProperty(Properties.rimLightLevel, Styles.rimLightLevelText); editor.ShaderProperty(Properties.rimLightLevel, Styles.rimLightLevelText);
editor.ShaderProperty(Properties.colorBlendingMode, Styles.colorBlendingModeText);
editor.ShaderProperty(Properties.adjustRimLightArea, Styles.adjustRimLightAreaText);
editor.ShaderProperty(Properties.rimLightFeatherOff, Styles.rimLightFeatherOffText);
editor.ShaderProperty(Properties.lightDirection, Styles.lightDirectionText);
using (var lightDisabledGroup = new EditorGUI.DisabledScope(!Properties.lightDirection.GetBooleanValue())) if (!Properties.screenSpaceRimLight.GetBooleanValue())
{ {
using var lightIndentLevelScope = new EditorGUI.IndentLevelScope(); editor.ShaderProperty(Properties.rimLightClipping, Styles.rimLightClippingText);
if (Properties.rimLightClipping.GetBooleanValue())
editor.ShaderProperty(Properties.lightDirectionRimLightLevel, Styles.lightDirectionRimLightLevelText); {
editor.ShaderProperty(Properties.invertedDirectionRimLight, Styles.invertedDirectionRimLightText); using var clippingLevelIndentLevelScope = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.rimLightClippingLevel, Styles.rimLightClippingLevelText);
using var invertedDirectionDisabledGroup = new EditorGUI.DisabledScope(!Properties.invertedDirectionRimLight.GetBooleanValue()); }
using var invertedDirectionIndentLevelScope = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.invertedRimLightColor, Styles.invertedRimLightColorText);
editor.ShaderProperty(Properties.inversedRimLightLevel, Styles.inversedRimLightLevelText);
editor.ShaderProperty(Properties.invertedRimLightFeatherOff, Styles.invertedRimLightFeatherOffText);
} }
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.TexturePropertySingleLine(Styles.rimLightMaskMapText, Properties.rimLightMaskMap); editor.ShaderProperty(Properties.lightBaseRimLight, Styles.lightBaseRimLightText);
editor.ShaderProperty(Properties.rimLightMaskLevel, Styles.rimLightMaskLevelText); if (Properties.lightBaseRimLight.GetBooleanValue())
{
editor.ShaderProperty(Properties.lightDirectionRimLightLevel, Styles.lightDirectionRimLightLevelText);
}
//using (var lightDisabledGroup = new EditorGUI.DisabledScope(!Properties.lightDirection.GetBooleanValue()))
//{
// using var lightIndentLevelScope = new EditorGUI.IndentLevelScope();
// editor.ShaderProperty(Properties.lightDirectionRimLightLevel, Styles.lightDirectionRimLightLevelText);
// editor.ShaderProperty(Properties.invertedDirectionRimLight, Styles.invertedDirectionRimLightText);
// using var invertedDirectionDisabledGroup = new EditorGUI.DisabledScope(!Properties.invertedDirectionRimLight.GetBooleanValue());
// using var invertedDirectionIndentLevelScope = new EditorGUI.IndentLevelScope();
// editor.ShaderProperty(Properties.invertedRimLightColor, Styles.invertedRimLightColorText);
// editor.ShaderProperty(Properties.inversedRimLightLevel, Styles.inversedRimLightLevelText);
// editor.ShaderProperty(Properties.invertedRimLightFeatherOff, Styles.invertedRimLightFeatherOffText);
//}
//EditorGUILayout.Space();
//editor.TexturePropertySingleLine(Styles.rimLightMaskMapText, Properties.rimLightMaskMap);
//editor.ShaderProperty(Properties.rimLightMaskLevel, Styles.rimLightMaskLevelText);
} }
} }
} }

View File

@@ -157,7 +157,7 @@ namespace Misaki.HdrpToon.Editor
editor.ShaderProperty(Properties.emissiveIntensity, Styles.emissiveIntensityText); editor.ShaderProperty(Properties.emissiveIntensity, Styles.emissiveIntensityText);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
editor.ApplyChange(material => foreach (var material in editor.GetMaterials())
{ {
if (material.HasProperty(EMISSIVE_COLOR_LDR) && material.HasProperty(EMISSIVE_INTENSITY) && material.HasProperty(EMISSIVE_COLOR)) if (material.HasProperty(EMISSIVE_COLOR_LDR) && material.HasProperty(EMISSIVE_INTENSITY) && material.HasProperty(EMISSIVE_COLOR))
{ {
@@ -167,7 +167,7 @@ namespace Misaki.HdrpToon.Editor
var emissiveColorLDRLinear = new Color(Mathf.GammaToLinearSpace(emissiveColorLDR.r), Mathf.GammaToLinearSpace(emissiveColorLDR.g), Mathf.GammaToLinearSpace(emissiveColorLDR.b)); var emissiveColorLDRLinear = new Color(Mathf.GammaToLinearSpace(emissiveColorLDR.r), Mathf.GammaToLinearSpace(emissiveColorLDR.g), Mathf.GammaToLinearSpace(emissiveColorLDR.b));
material.SetColor(EMISSIVE_COLOR, emissiveColorLDRLinear * material.GetFloat(EMISSIVE_INTENSITY)); material.SetColor(EMISSIVE_COLOR, emissiveColorLDRLinear * material.GetFloat(EMISSIVE_INTENSITY));
} }
}); }
} }
EditorGUILayout.Space(); EditorGUILayout.Space();

View File

@@ -72,7 +72,16 @@ namespace Misaki.HdrpToon.Editor
editor.ShaderProperty(Properties.cullMode, Styles.cullingModeText); editor.ShaderProperty(Properties.cullMode, Styles.cullingModeText);
editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText); editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText);
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(Properties.materialType, Styles.materialTypeText); editor.ShaderProperty(Properties.materialType, Styles.materialTypeText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in editor.GetMaterials())
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, Properties.materialType.GetEnumValue<MaterialType>() == MaterialType.FrontHair);
}
}
editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText); editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText);
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();

View File

@@ -21,6 +21,29 @@ namespace Misaki.HdrpToon
public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight"; public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight";
} }
public static class RimLight
{
public const string RIM_LIGHT_COLOR = "_RimLightColor";
public const string RIM_LIGHT_INTENSITY = "_RimLightIntensity";
public const string RIM_LIGHT_LEVEL = "_RimLightLevel";
public const string SCREEN_SPACE_RIM_LIGHT = "_Screen_Space_Rim_Light";
public const string LIGHT_BASE_RIM_LIGHT = "_Light_Base_Rim_Light";
public const string LIGHT_DIRECTION_RIM_LIGHT_LEVEL = "_LightDirectionRimLightLevel";
public const string COLOR_BLENDING_MODE = "_Is_BlendAddToRimColor";
public const string RIM_LIGHT_CLIPPING = "_RimLightClipping";
public const string RIM_LIGHT_CLIPPING_LEVEL = "_RimLightClippingLevel";
public const string LIGHT_DIRECTION = "_LightDirection_MaskOn";
public const string INVERTED_DIRECTION_RIM_LIGHT = "_Add_Antipodean_RimLight";
public const string INVERTED_RIM_LIGHT_COLOR = "_Ap_RimLightColor";
public const string INVERSED_RIM_LIGHT_LEVEL = "_Ap_RimLight_Power";
public const string INVERTED_RIM_LIGHT_FEATHER_OFF = "_Ap_RimLight_FeatherOff";
public const string RIM_LIGHT_MASK_MAP = "_Set_RimLightMask";
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
}
public static class Outline public static class Outline
{ {
public const string OUTLINE_STATE = "_OutlineState"; public const string OUTLINE_STATE = "_OutlineState";

View File

@@ -6,6 +6,14 @@ namespace Misaki.HdrpToon
SDF, SDF,
} }
internal enum MaterialType
{
Standard,
FrontHair,
Face,
Eye
}
internal enum PBRMode internal enum PBRMode
{ {
Off, Off,

View File

@@ -224,7 +224,7 @@ Shader "HDRP/Toon"
[KeywordEnum(Standard, SDF)] _Shading_Mode("Shading mode", Integer) = 0 [KeywordEnum(Standard, SDF)] _Shading_Mode("Shading mode", Integer) = 0
[KeywordEnum(Standard, FrontHair, Face, Eye)] _Material_Type("Material Type", Integer) = 0 [KeywordEnum(Standard, FrontHair, Face, Eye)] _Material_Type("Material Type", Integer) = 0
[KeywordEnum(Off, Standard, Anisotropy, KKHair, Toon)] _PBR_Mode("PBR Mode", Integer) = 0 [KeywordEnum(Off, Standard, Anisotropy, KKHair, Toon)] _PBR_Mode("PBR Mode", Integer) = 0
[ToggleUI] _HairBlendingTarget("Hair Blending Target", Integer) = 0 [PassPopup(HairBlendingTarget)] _HairBlendingTarget("Hair Blending Target", Integer) = 0
[EnumFlagsUI(Misaki.HdrpToon.SurfaceFeature, Misaki.HdrpToon)]_SurfaceFeatures("Surface Features", Integer) = 0 [EnumFlagsUI(Misaki.HdrpToon.SurfaceFeature, Misaki.HdrpToon)]_SurfaceFeatures("Surface Features", Integer) = 0
// Shading Color // Shading Color
@@ -255,8 +255,8 @@ Shader "HDRP/Toon"
// Shadow // Shadow
[Popup] _Receive_Light_Shadow("Receive Light Shadow", Integer) = 0 [Popup] _Receive_Light_Shadow("Receive Light Shadow", Integer) = 0
[Popup] _Receive_Screen_Space_Shadow("Receive Screen Space Shadow", Float) = 0 [Popup] _Receive_Screen_Space_Shadow("Receive Screen Space Shadow", Integer) = 0
[Popup] _Receive_Hair_Shadow("Receive Hair Shadow", Float) = 0 [Popup] _Receive_Hair_Shadow("Receive Hair Shadow", Integer) = 0
_ShadowDistanceBias("ShadowBias", Range(0.0, 5.0)) = 0.0 _ShadowDistanceBias("ShadowBias", Range(0.0, 5.0)) = 0.0
_ShadowNormalBias("ShadowNormalBias", Range(0.0, 5.0)) = 0.0 _ShadowNormalBias("ShadowNormalBias", Range(0.0, 5.0)) = 0.0
@@ -317,17 +317,21 @@ Shader "HDRP/Toon"
//_Set_HighColorMask("Set_HighColorMask", 2D) = "white" {} //_Set_HighColorMask("Set_HighColorMask", 2D) = "white" {}
//_Tweak_HighColorMaskLevel("Tweak_HighColorMaskLevel", Range(-1, 1)) = 0 //_Tweak_HighColorMaskLevel("Tweak_HighColorMaskLevel", Range(-1, 1)) = 0
//[Toggle(_)] _RimLight("RimLight", Float) = 0 //[Toggle(_)] _RimLight("RimLight", Float) = 0
_RimLightColor("RimLightColor", Color) = (1, 1, 1, 1)
_RimLightStrength("RimLight_Strength", Range(0, 10)) = 1 _RimLightColor("Rim Light Color", Color) = (1, 1, 1, 1)
_RimLightIntensity("Rim Light Intensity", Range(0, 10)) = 1
[Popup] _Screen_Space_Rim_Light ("Screen Space Rim Light", Integer) = 0
_RimLightLevel("RimLight Level", Range(0, 1)) = 0.1
[ToggleUI] _RimLightClipping("Rim Light Clipping", Float) = 0.25
_RimLightClippingLevel("Rim Light Clipping Level", Range(0.0001, 1)) = 0.0001
[Popup] _Light_Base_Rim_Light ("Light Base Rim Light", Integer) = 0
_LightDirectionRimLightLevel("Light Direction Rim Light Level", Range(0, 0.5)) = 0
[ToggleUI] _Is_LightColor_RimLight("Is_LightColor_RimLight", Float) = 1 [ToggleUI] _Is_LightColor_RimLight("Is_LightColor_RimLight", Float) = 1
[ToggleUI] _Is_NormalMapToRimLight("Is_NormalMapToRimLight", Float) = 0 [ToggleUI] _Is_NormalMapToRimLight("Is_NormalMapToRimLight", Float) = 0
_RimLightLevel("RimLight Level", Range(0, 1)) = 0.1
_RimLight_InsideMask("RimLight_InsideMask", Range(0.0001, 1)) = 0.0001
[ToggleUI] _RimLight_FeatherOff("RimLight_FeatherOff", Float) = 0
[ToggleUI] _LightDirection_MaskOn("LightDirection_MaskOn", Float) = 0 [ToggleUI] _LightDirection_MaskOn("LightDirection_MaskOn", Float) = 0
_Tweak_LightDirection_MaskLevel("Tweak_LightDirection_MaskLevel", Range(0, 0.5)) = 0
[ToggleUI] _Add_Antipodean_RimLight("Add_Antipodean_RimLight", Float) = 0 [ToggleUI] _Add_Antipodean_RimLight("Add_Antipodean_RimLight", Float) = 0
_Ap_RimLightColor("Ap_RimLightColor", Color) = (1, 1, 1, 1) _Ap_RimLightColor("Ap_RimLightColor", Color) = (1, 1, 1, 1)
[ToggleUI] _Is_LightColor_Ap_RimLight("Is_LightColor_Ap_RimLight", Float) = 1 [ToggleUI] _Is_LightColor_Ap_RimLight("Is_LightColor_Ap_RimLight", Float) = 1
@@ -345,8 +349,8 @@ Shader "HDRP/Toon"
_AngelRingOffsetV("Angel Ring Offset V", Range(0, 1)) = 0 _AngelRingOffsetV("Angel Ring Offset V", Range(0, 1)) = 0
// Outline // Outline
[PassPopup(Outline)] _OutlineState("Outline State", Integer) = 0 [PassPopup(Outline)] _OutlineState("Outline State", Integer) = 1
_OutlineWidth("Outline Width", Float) = 0 _OutlineWidth("Outline Width", Float) = 0.25
_OutlineWidthMap("Outline Tex", 2D) = "white" {} _OutlineWidthMap("Outline Tex", 2D) = "white" {}
_OutlineColor("Outline Color", Color) = (0.5, 0.5, 0.5, 1) _OutlineColor("Outline Color", Color) = (0.5, 0.5, 0.5, 1)
_OutlineColorMap("Outline Color Map", 2D) = "white" {} _OutlineColorMap("Outline Color Map", 2D) = "white" {}
@@ -968,9 +972,9 @@ Shader "HDRP/Toon"
Name "ForwardOnly" Name "ForwardOnly"
Tags { "LightMode" = "ForwardOnly" } Tags { "LightMode" = "ForwardOnly" }
ZWrite[_ZWriteMode] ZWrite [_ZWriteMode]
ZTest [_ZTestMode] ZTest [_ZTestMode]
Cull[_CullMode] Cull [_CullMode]
Blend SrcAlpha OneMinusSrcAlpha Blend SrcAlpha OneMinusSrcAlpha
Stencil { Stencil {
@@ -996,6 +1000,9 @@ 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
#pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST #pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
//Probe volume
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#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)
// Don't do it with debug display mode as it is possible there is no depth prepass in this case // Don't do it with debug display mode as it is possible there is no depth prepass in this case
@@ -1012,8 +1019,6 @@ Shader "HDRP/Toon"
// controlling mask rendering // controlling mask rendering
#pragma shader_feature _ _IS_CLIPPING_MATTE #pragma shader_feature _ _IS_CLIPPING_MATTE
#pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION #pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION
//Probe volume
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#pragma shader_feature ENABLE_UTS_HAIR_SHAOW #pragma shader_feature ENABLE_UTS_HAIR_SHAOW
#pragma shader_feature ENABLE_UTS_HAIR_BLENDING #pragma shader_feature ENABLE_UTS_HAIR_BLENDING
@@ -1031,6 +1036,9 @@ Shader "HDRP/Toon"
#pragma shader_feature_local_fragment _INDIRECT_DIFFUSE_MODE_OFF _INDIRECT_DIFFUSE_MODE_IBL _INDIRECT_DIFFUSE_MODE_MATCAP _INDIRECT_DIFFUSE_MODE_RAMP #pragma shader_feature_local_fragment _INDIRECT_DIFFUSE_MODE_OFF _INDIRECT_DIFFUSE_MODE_IBL _INDIRECT_DIFFUSE_MODE_MATCAP _INDIRECT_DIFFUSE_MODE_RAMP
#pragma shader_feature_local_fragment _INDIRECT_SPECULAR_MODE_OFF _INDIRECT_SPECULAR_MODE_IBL _INDIRECT_SPECULAR_MODE_MATCAP #pragma shader_feature_local_fragment _INDIRECT_SPECULAR_MODE_OFF _INDIRECT_SPECULAR_MODE_IBL _INDIRECT_SPECULAR_MODE_MATCAP
#pragma shader_feature_local_fragment _SCREEN_SPACE_RIM_LIGHT_ON
#pragma shader_feature_local_fragment _LIGHT_BASE_RIM_LIGHT_ON
#pragma shader_feature_local_fragment _MASKMAP #pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local_fragment _NORMALMAP #pragma shader_feature_local_fragment _NORMALMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP #pragma shader_feature_local_fragment _ANISOTROPYMAP
@@ -1040,12 +1048,6 @@ Shader "HDRP/Toon"
#pragma shader_feature_local_fragment _OUTLINECOLORMAP #pragma shader_feature_local_fragment _OUTLINECOLORMAP
#if _PBR_MODE_OFF
#undef _MASKMAP
#undef _ANISOTROPYMAP
#undef _SPECULARCOLORMAP
#endif
#define PUNCTUAL_SHADOW_MEDIUM #define PUNCTUAL_SHADOW_MEDIUM
#define DIRECTIONAL_SHADOW_MEDIUM #define DIRECTIONAL_SHADOW_MEDIUM
#define AREA_SHADOW_MEDIUM #define AREA_SHADOW_MEDIUM
@@ -1133,8 +1135,6 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
#define SHADERPASS SHADERPASS_CONSTANT #define SHADERPASS SHADERPASS_CONSTANT
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"

View File

@@ -4,13 +4,14 @@
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl" #include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl"
#define UTS_LAYER_VISIBILITY #define UTS_LAYER_VISIBILITY
#ifndef DIRECTIONAL
# define DIRECTIONAL
#endif
#define FP_BUFFER 1 #define FP_BUFFER 1
#if _PBR_MODE_OFF
#undef _MASKMAP
#undef _ANISOTROPYMAP
#undef _SPECULARCOLORMAP
#endif
#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER) #if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)
#undef FOG_LINEAR #undef FOG_LINEAR

View File

@@ -1,28 +1,44 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION #ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION #define UTS_SURFACE_FEATURE_EVALUATION
// Rim light is calculated per light DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
float3 UtsEvaluateColor_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, float3 L, float3 lightColor) #if _LIGHT_BASE_RIM_LIGHT_ON
, float3 L, float3 lightColor
#endif
)
{ {
float clampNdotV = ClampNdotV(preLightData.NdotV); DirectLighting lighting;
float rimLightWeight = 1.0 - clampNdotV; ZERO_INITIALIZE(DirectLighting, lighting);
rimLightWeight = pow(rimLightWeight, exp2(lerp(3.0, 0.0, _RimLightLevel)));
float3 rimLightColor = _RimLightColor.rgb * _RimLightIntensity;
#if _SCREEN_SPACE_RIM_LIGHT_ON
float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS)); float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS));
float2 depthUV = posInput.positionNDC.xy + normalVS * (_RimLightLevel * 0.05 / posInput.linearDepth); float2 depthUV = posInput.positionNDC.xy + normalVS.xy * (_RimLightLevel * 0.05 / posInput.linearDepth);
float offsetedDepth = SampleCameraDepth(depthUV); float offsetedDepth = SampleCameraDepth(depthUV);
float depthDiff = saturate(posInput.deviceDepth - offsetedDepth); float depthDiff = saturate(posInput.deviceDepth - offsetedDepth);
float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5; float rimLightMask = step(0.0025 / posInput.linearDepth, depthDiff);
//float rimLightMask = lerp(0.5 * lambert + 0.5, saturate(lambert), _Tweak_LightDirection_MaskLevel * 2.0); #else
float rimLightMask = saturate(smoothstep(_Tweak_LightDirection_MaskLevel, 1.0, halfLambert)); float clampNdotV = ClampNdotV(preLightData.NdotV);
float rimLightMask = pow(1.0 - clampNdotV, exp2(lerp(3.0, 0.0, _RimLightLevel)));
rimLightMask = lerp(rimLightMask, step(_RimLightClippingLevel, rimLightMask), _RimLightClipping);
#endif
rimLightWeight = step(0.0025 / posInput.linearDepth, depthDiff); #if _LIGHT_BASE_RIM_LIGHT_ON
float3 outColor = rimLightWeight * lightColor * _RimLightColor * _RimLightStrength; float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5;
return outColor * rimLightMask; float lightBaseMask = saturate(smoothstep(_LightDirectionRimLightLevel, 1.0, halfLambert));
rimLightMask *= lightBaseMask;
rimLightColor *= lightColor;
#endif
lighting.diffuse = rimLightMask * rimLightColor;
return lighting;
} }
DirectLighting UtsEvaluateAngelRing(FragInputs input, float3 normalWS, float3 V) DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS, float3 V)
{ {
DirectLighting lighting; DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting); ZERO_INITIALIZE(DirectLighting, lighting);
@@ -40,13 +56,13 @@ DirectLighting UtsEvaluateAngelRing(FragInputs input, float3 normalWS, float3 V)
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy; float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
arOffsetU = arOffsetU * 0.5 + 0.5; arOffsetU = arOffsetU * 0.5 + 0.5;
float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll), 0.5, 1.0); float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0);
float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV)); float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV));
float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity; float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity;
float weight = saturate(dot(normalize(V), normalWS)); float weight = saturate(dot(normalize(V), normalWS));
lighting.specular += angelRingColor.r * angelRingColor.a * weight; lighting.specular = angelRingColor.r * angelRingColor.a * weight;
return lighting; return lighting;
} }

View File

@@ -137,7 +137,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount); GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #else
lightCount = _PunctualLightCount; lightCount = _PunctualLightCount;
lightStart = 0; lightStart = 0;
#endif #endif
@@ -374,9 +374,17 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif #endif
} }
#ifndef _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{
DirectLighting lighting = UtsEvaluateLighting_RimLight(posInput, bsdfData, preLightData);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#endif
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING)) if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
{ {
DirectLighting lighting = UtsEvaluateAngelRing(fragInputs, bsdfData.normalWS, V); DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting); AccumulateDirectLighting(lighting, aggregateLighting);
} }

View File

@@ -159,7 +159,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden)); float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
float baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - firstColorFeatherForMask)) / (_1stShadeColorStep - (_1stShadeColorStep - firstColorFeatherForMask))); float baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - firstColorFeatherForMask)) / (_1stShadeColorStep - (_1stShadeColorStep - firstColorFeatherForMask)));
baseShadeMask *= shadow; baseShadeMask *= shadow.x;
float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode)); float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - secondColorFeatherForMask)) / (_2ndShadeColorStep - (_2ndShadeColorStep - secondColorFeatherForMask))); float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - secondColorFeatherForMask)) / (_2ndShadeColorStep - (_2ndShadeColorStep - secondColorFeatherForMask)));
@@ -167,7 +167,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask); diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask);
specularTerm *= baseShadeMask; specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF #elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * shadow; float shadeMask = sdfShadowMask * sdfTexture.b * shadow.x;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask); diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask);
specularTerm = (specularTerm + sdfHighlight) * shadeMask; specularTerm = (specularTerm + sdfHighlight) * shadeMask;
@@ -177,10 +177,15 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer; lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer; lighting.specular += specularTerm * lightColor * specularDimmer;
#if _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT)) if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{ {
lighting.diffuse += UtsEvaluateColor_RimLight(posInput, bsdfData, preLightData, L, lightColor); DirectLighting rimLightLighting = UtsEvaluateLighting_RimLight(posInput, bsdfData, preLightData, L, lightColor);
lighting.diffuse += rimLightLighting.diffuse;
lighting.specular += rimLightLighting.specular;
} }
#endif
} }
return lighting; return lighting;

View File

@@ -12,6 +12,7 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
float3 SampleSDFTexture(float3 L, float2 uv, out float angle) float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
{ {
// TODO: Move sdf sample result to UtsBSDFData to avoid sampleing in a loop
float2 right_uv = float2(1 - uv.x, uv.y); float2 right_uv = float2(1 - uv.x, uv.y);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb; float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb;
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb; float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb;
@@ -35,23 +36,19 @@ float GetHairShadow(PositionInputs posInput, float3 L)
if (hairShadowOpacity > 0.0) if (hairShadowOpacity > 0.0)
{ {
float3 viewLightDir = TransformWorldToViewDir(L); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face. float3 viewLightDir = TransformWorldToViewDir(L);
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
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())); float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y); float cameraDirFactor = 1 - smoothstep(0.1, 0.9, cameraDirOS.y);
shadowLength.y *= camDirFactor; shadowLength.y *= cameraDirFactor;
float2 samplingPoint = (posInput.positionSS + 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 = (posInput.positionSS + 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.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed. float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_linear_clamp_sampler, scaledUVs).r; float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r;
float shadowMask = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow);
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
shadow = lerp(1, 1.0 - hairShadowOpacity, shadowMask);
} }
return shadow; return shadow;

View File

@@ -81,7 +81,7 @@ TEXTURE2D(_SSSLutMap);
//SAMPLER(sampler_SSSLutMap); //Use s_linear_clamp_sampler instead //SAMPLER(sampler_SSSLutMap); //Use s_linear_clamp_sampler instead
TEXTURE2D(_HairShadowTex); TEXTURE2D(_HairShadowTex);
TEXTURE2D(_HairBlendingTex); TEXTURE2D_X(_HairBlendingTex);
#else #else

View File

@@ -46,8 +46,12 @@ float _SSRWeight;
//Rim Light //Rim Light
float4 _RimLightColor; float4 _RimLightColor;
float _RimLightStrength; float _RimLightIntensity;
float _RimLightLevel; float _RimLightLevel;
fixed _RimLightClipping;
float _RimLightClippingLevel;
float _LightDirectionRimLightLevel;
// Outline // Outline
float _OutlineWidth; float _OutlineWidth;
@@ -95,15 +99,10 @@ fixed _Is_BlendAddToHiColor;
fixed _Is_BlendAddToRimColor; fixed _Is_BlendAddToRimColor;
fixed _Is_UseTweakHighColorOnShadow; fixed _Is_UseTweakHighColorOnShadow;
float _TweakHighColorOnShadow; float _TweakHighColorOnShadow;
float4 _Set_HighColorMask_ST;
float _Tweak_HighColorMaskLevel;
fixed _Is_LightColor_RimLight; fixed _Is_LightColor_RimLight;
fixed _Is_NormalMapToRimLight; fixed _Is_NormalMapToRimLight;
float _RimLight_InsideMask;
fixed _RimLight_FeatherOff;
fixed _LightDirection_MaskOn; fixed _LightDirection_MaskOn;
float _Tweak_LightDirection_MaskLevel;
fixed _Add_Antipodean_RimLight; fixed _Add_Antipodean_RimLight;
float4 _Ap_RimLightColor; float4 _Ap_RimLightColor;
fixed _Is_LightColor_Ap_RimLight; fixed _Is_LightColor_Ap_RimLight;

View File

@@ -10,75 +10,38 @@ float4 _LightColor0; // not referenced in c# code ??
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
// PackedVaryingsType // PackedVaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120 // 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) PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{ {
// VaryingsType // VaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118 // https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
VaryingsType varyingsType; VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh); varyingsType.vmesh = VertMesh(inputMesh);
varyingsType.vmesh. varyingsType.vmesh.
#include "HDRPToonOutlineVertMain.hlsl" #include "HDRPToonOutlineVertMain.hlsl"
return MotionVectorVS(varyingsType, inputMesh, inputPass); return MotionVectorVS(varyingsType, inputMesh, inputPass);
} }
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
MotionVectorPositionZBias(output);
output.vpass.positionCS = input.vpass.positionCS;
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#else // _WRITE_TRANSPARENT_MOTION_VECTOR #else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh) PackedVaryingsType Vert(AttributesMesh inputMesh)
{ {
VaryingsType varyingsType; VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh); varyingsType.vmesh = VertMesh(inputMesh);
#include "HDRPToonOutlineVertMain.hlsl" #include "HDRPToonOutlineVertMain.hlsl"
return PackVaryingsType(varyingsType); return PackVaryingsType(varyingsType);
} }
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR #endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef TESSELLATION_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
#endif
#ifdef UNITY_VIRTUAL_TEXTURING #ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1 #define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2 #define EXTRA_BUFFER_TARGET SV_Target2

View File

@@ -92,14 +92,9 @@ void Frag(PackedVaryingsToPS packedInput,
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false); input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#endif #endif
float4 UV0 = input.texCoord0;
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer. // We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy; input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize(); uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex); PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
@@ -111,7 +106,7 @@ void Frag(PackedVaryingsToPS packedInput,
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld); float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT; float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y; parallaxOffset.y = -parallaxOffset.y;
UV0.xy = clamp(UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1); input.texCoord0.xy = clamp(input.texCoord0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif #endif
#else #else
@@ -158,115 +153,6 @@ void Frag(PackedVaryingsToPS packedInput,
UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput); UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput);
/*
#ifdef _EMISSIVE_SIMPLE
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
#elif _EMISSIVE_ANIMATION
//v.2.0.7 Calculation View Coord UV for Scroll
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
//Invert if it's "inside the mirror".
if (utsData.signMirror < 0) {
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
}
else {
_ViewCoord_UV = _ViewCoord_UV;
}
float2 emissive_uv = lerp(UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
//
float4 _time_var = _Time;
float _base_Speed_var = (_time_var.g * _Base_Speed);
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
//
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
#endif
*/
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
/*
#if _SHADOW_MODE_SDF || (_RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW)
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 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = customMainLight.lightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
#endif
#if _SHADOW_MODE_SDF
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
float angle;
bool rightside;
float2 SDF_UV = TRANSFORM_TEX(UV0, _BaseColorMap);
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
// 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)));
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
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.
// Then sample the hair buffer, to see if the fragment lands in shadow.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
float depthCorrect = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
#endif
*/
//outColor.rgb = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
//outColor.a = 1.0;
//return;
float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting; float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
#ifdef _IS_TRANSCLIPPING_OFF #ifdef _IS_TRANSCLIPPING_OFF
@@ -283,7 +169,7 @@ void Frag(PackedVaryingsToPS packedInput,
#if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING #if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy; float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV); float4 hairBlendingMap = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor); outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
#endif #endif

View File

@@ -11,27 +11,30 @@ namespace Misaki.HdrpToon
[HideInInspector] [HideInInspector]
internal class UTSPass : CustomPass internal class UTSPass : CustomPass
{ {
private const int Adjustment_Curve_Precision = 128; private const int _ADJUSTMENT_CURVE_PRECISION = 128;
private const string Compensation_Prop_Name = "_ToonEvAdjustmentCompensation"; private const string _COMPENSATION_PROP_NAME = "_ToonEvAdjustmentCompensation";
private const string Exposure_Adjustment_Prop_Name = "_ToonEvAdjustmentCurve"; private const string _EXPOSURE_ADJUSTMENT_PROP_NAME = "_ToonEvAdjustmentCurve";
private const string Exposure_Array_Prop_Name = "_ToonEvAdjustmentValueArray"; private const string _EXPOSURE_ARRAY_PROP_NAME = "_ToonEvAdjustmentValueArray";
private const string Exposure_Min_Prop_Name = "_ToonEvAdjustmentValueMin"; private const string _EXPOSURE_MIN_PROP_NAME = "_ToonEvAdjustmentValueMin";
private const string Exposure_Max_Prop_Name = "_ToonEvAdjustmentValueMax"; private const string _EXPOSURE_MAX_PROP_NAME = "_ToonEvAdjustmentValueMax";
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_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";
private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias"; private const string _HAIR_SHADOW_DEPTH_BIAS_PROP_NAME = "_HairShadowDepthBias";
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 Hair_Blending_RTHandle_Scale_Prop_Name = "_HairBlendingRTHandleScale"; private const string _HAIR_BLENDING_RTHANDLE_SCALE_PROP_NAME = "_HairBlendingRTHandleScale";
private const string Output_RT_Prop_Name = "_HairShadowTex"; private const string _HAIR_SHADOW_RT_PROP_NAME = "_HairShadowTex";
private const string Hair_Blending_Prop_Name = "_HairBlendingTex"; private const string _HAIR_BLENDING_PROP_NAME = "_HairBlendingTex";
private static readonly ProfilingSampler _hairShadowProfilingSampler = new("UTS Hair Shadow");
private static readonly ProfilingSampler _hairBlendingProfilingSampler = new("UTS Hair Blending Target");
private float _max; private float _max;
private float _min; private float _min;
@@ -146,16 +149,9 @@ namespace Misaki.HdrpToon
_ => Vector2.zero _ => Vector2.zero
}; };
var format = _hairShadowQuality switch
{
BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.D16_UNorm
};
_hairShadowRTHandle?.Release(); _hairShadowRTHandle?.Release();
_hairShadowRTHandle = RTHandles.Alloc(scale, colorFormat: format, isShadowMap: true, useDynamicScale: true, name: Output_RT_Prop_Name); _hairShadowRTHandle = RTHandles.Alloc(scale, useDynamicScale: true, format: GraphicsFormat.D16_UNorm, isShadowMap: true, name: _HAIR_SHADOW_RT_PROP_NAME);
Shader.SetGlobalTexture(Output_RT_Prop_Name, _hairShadowRTHandle); Shader.SetGlobalTexture(_HAIR_SHADOW_RT_PROP_NAME, _hairShadowRTHandle);
_needReallocateHairShadow = false; _needReallocateHairShadow = false;
} }
@@ -182,93 +178,20 @@ namespace Misaki.HdrpToon
}; };
_hairBlendingRTHandle?.Release(); _hairBlendingRTHandle?.Release();
_hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, colorFormat: format, useDynamicScale: true, name: Hair_Blending_Prop_Name); _hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: format, name: _HAIR_BLENDING_PROP_NAME);
Shader.SetGlobalTexture(Hair_Blending_Prop_Name, _hairBlendingRTHandle); Shader.SetGlobalTexture(_HAIR_BLENDING_PROP_NAME, _hairBlendingRTHandle);
_needReallocateHairBlending = false; _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(); ReallocateHairShadowBuffer();
ReallocateHairBlendingBuffer(); ReallocateHairBlendingBuffer();
} }
protected override void Execute(CustomPassContext ctx)
{
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) private void UpdateSceneEV(UTSRenderer utsRenderer)
{ {
if (utsRenderer == null) if (utsRenderer == null)
@@ -307,22 +230,98 @@ namespace Misaki.HdrpToon
{ {
_min = curve[0].time; _min = curve[0].time;
_max = curve[curve.length - 1].time; _max = curve[curve.length - 1].time;
var step = (_max - _min) / (Adjustment_Curve_Precision - 1f); var step = (_max - _min) / (_ADJUSTMENT_CURVE_PRECISION - 1f);
for (var i = 0; i < Adjustment_Curve_Precision; i++) for (var i = 0; i < _ADJUSTMENT_CURVE_PRECISION; i++)
{ {
_exposureArray[i] = curve.Evaluate(_min + step * i); _exposureArray[i] = curve.Evaluate(_min + step * i);
} }
} }
} }
Shader.SetGlobalFloatArray(Exposure_Array_Prop_Name, _exposureArray); Shader.SetGlobalFloatArray(_EXPOSURE_ARRAY_PROP_NAME, _exposureArray);
Shader.SetGlobalFloat(Exposure_Min_Prop_Name, _min); Shader.SetGlobalFloat(_EXPOSURE_MIN_PROP_NAME, _min);
Shader.SetGlobalFloat(Exposure_Max_Prop_Name, _max); Shader.SetGlobalFloat(_EXPOSURE_MAX_PROP_NAME, _max);
Shader.SetGlobalInt(Exposure_Adjustment_Prop_Name, toonEVAdjustment); Shader.SetGlobalInt(_EXPOSURE_ADJUSTMENT_PROP_NAME, toonEVAdjustment);
Shader.SetGlobalInt(Toon_Light_Filter_Prop_Name, lightIntensityLimiter); Shader.SetGlobalInt(_TOON_LIGHT_FILTER_PROP_NAME, lightIntensityLimiter);
Shader.SetGlobalInt(Ignore_Volume_Exposure_Prop_Name, ignoreVolumeExposure); Shader.SetGlobalInt(_IGNORE_VOLUME_EXPOSURE_PROP_NAME, ignoreVolumeExposure);
Shader.SetGlobalFloat(Compensation_Prop_Name, compensation); Shader.SetGlobalFloat(_COMPENSATION_PROP_NAME, compensation);
}
private void RenderHairShadow(ref CustomPassContext ctx, UTSRenderer utsRenderer)
{
if (!_enableHairShadow
|| utsRenderer == null
|| !utsRenderer.state.value
|| !utsRenderer.enableHairShadow.value)
{
return;
}
if (ShouldReallocateHairShadowBuffer())
{
ReallocateHairShadowBuffer();
return;
}
using (new ProfilingScope(ctx.cmd, _hairShadowProfilingSampler))
{
CoreUtils.SetRenderTarget(ctx.cmd, _hairShadowRTHandle, ClearFlag.Depth);
var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
{
renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
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;
}
using (new ProfilingScope(ctx.cmd, _hairBlendingProfilingSampler))
{
CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, ctx.cameraDepthBuffer, ClearFlag.Color);
var result = new RendererListDesc(UtsShaderPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera)
{
renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
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);
}
}
protected override void Execute(CustomPassContext ctx)
{
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>();
UpdateSceneEV(utsRenderer);
RenderHairShadow(ref ctx, utsRenderer);
RenderHairBlending(ref ctx);
} }
protected override void Cleanup() protected override void Cleanup()

View File

@@ -38,7 +38,7 @@ namespace Misaki.HdrpToon
targetDepthBuffer = CustomPass.TargetBuffer.Camera, targetDepthBuffer = CustomPass.TargetBuffer.Camera,
}; };
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeRendering, _utsPass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _utsPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass);
NotifyRendererSettingChanged(); NotifyRendererSettingChanged();