Added hair blending support.

This commit is contained in:
2025-05-06 23:39:49 +09:00
parent 10331b93ff
commit 961db806e9
12 changed files with 161 additions and 115 deletions

View File

@@ -26,6 +26,16 @@ namespace Misaki.HdrpToon.Editor
return (PBRMode)material.GetInteger(SurfaceOptions.PBR_MODE); return (PBRMode)material.GetInteger(SurfaceOptions.PBR_MODE);
} }
public static MaterialType GetMaterialType(this Material material)
{
if (!material.HasProperty(SurfaceOptions.MATERIAL_TYPE))
{
return MaterialType.Standard;
}
return (MaterialType)material.GetInteger(SurfaceOptions.MATERIAL_TYPE);
}
public static bool HasFeature(this Material material, SurfaceFeature feature) public static bool HasFeature(this Material material, SurfaceFeature feature)
{ {
if (!material.HasProperty(SurfaceOptions.SURFACE_FEATURE)) if (!material.HasProperty(SurfaceOptions.SURFACE_FEATURE))
@@ -36,5 +46,10 @@ namespace Misaki.HdrpToon.Editor
var value = (SurfaceFeature)material.GetInteger(SurfaceOptions.SURFACE_FEATURE); var value = (SurfaceFeature)material.GetInteger(SurfaceOptions.SURFACE_FEATURE);
return (value & feature) != 0; return (value & feature) != 0;
} }
public static bool IsHairBlendingTarget(this Material material)
{
return material.GetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME);
}
} }
} }

View File

@@ -34,6 +34,8 @@ namespace Misaki.HdrpToon.Editor
public static MaterialProperty sdfShadowLevel; public static MaterialProperty sdfShadowLevel;
public static MaterialProperty sdfSmoothLevel; public static MaterialProperty sdfSmoothLevel;
public static MaterialProperty sdfHighlightStrength; public static MaterialProperty sdfHighlightStrength;
public static MaterialProperty hairBlendingFactor;
} }
private static class Styles private static class Styles
@@ -59,6 +61,8 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent shadingRampMaskMapText = new("Shading Ramp Mask Map", "A texture that contains the mask for the shading ramp map."); public static readonly GUIContent shadingRampMaskMapText = new("Shading Ramp Mask Map", "A texture that contains the mask for the shading ramp map.");
public static readonly GUIContent sdfHighlightStrengthText = new("SDF Highlight Strength", "Control the strength of the highlight in the SDF shading map."); public static readonly GUIContent sdfHighlightStrengthText = new("SDF Highlight Strength", "Control the strength of the highlight in the SDF shading map.");
public static readonly GUIContent hairBlendingFactorText = new("Hair Blending Factor", "The blending factor for hair shading.");
} }
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.ShadingColor; protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.ShadingColor;
@@ -108,6 +112,8 @@ namespace Misaki.HdrpToon.Editor
Properties.sdfShadowLevel = FindProperty("_SDFShadowLevel"); Properties.sdfShadowLevel = FindProperty("_SDFShadowLevel");
Properties.sdfSmoothLevel = FindProperty("_SDFShadowSmoothLevel"); Properties.sdfSmoothLevel = FindProperty("_SDFShadowSmoothLevel");
Properties.sdfHighlightStrength = FindProperty("_SDFHighlightStrength"); Properties.sdfHighlightStrength = FindProperty("_SDFHighlightStrength");
Properties.hairBlendingFactor = FindProperty("_HairBlendingFactor");
} }
protected override void DrawContent() protected override void DrawContent()
@@ -144,6 +150,12 @@ namespace Misaki.HdrpToon.Editor
editor.ShaderProperty(Properties.sdfHighlightStrength, Styles.sdfHighlightStrengthText); editor.ShaderProperty(Properties.sdfHighlightStrength, Styles.sdfHighlightStrengthText);
} }
if (materials.All(material => material.GetMaterialType() == MaterialType.FrontHair))
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.hairBlendingFactor, Styles.hairBlendingFactorText);
}
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.TextureScaleOffsetProperty(Properties.baseColorMap); editor.TextureScaleOffsetProperty(Properties.baseColorMap);
} }

View File

@@ -12,28 +12,30 @@ namespace Misaki.HdrpToon.Editor
{ {
private static class Properties private static class Properties
{ {
public static MaterialProperty NormalMap; public static MaterialProperty normalMap;
public static MaterialProperty NormalMapScale; public static MaterialProperty normalMapScale;
public static MaterialProperty MaskMap; public static MaterialProperty maskMap;
public static MaterialProperty Metallic; public static MaterialProperty metallic;
public static MaterialProperty MetallicRemapMin; public static MaterialProperty metallicRemapMin;
public static MaterialProperty MetallicRemapMax; public static MaterialProperty metallicRemapMax;
public static MaterialProperty AORemapMin; public static MaterialProperty aoRemapMin;
public static MaterialProperty AORemapMax; public static MaterialProperty aoRemapMax;
public static MaterialProperty Smoothness; public static MaterialProperty smoothness;
public static MaterialProperty SmoothnessRemapMin; public static MaterialProperty smoothnessRemapMin;
public static MaterialProperty SmoothnessRemapMax; public static MaterialProperty smoothnessRemapMax;
public static MaterialProperty AnisotropyMap; public static MaterialProperty anisotropyMap;
public static MaterialProperty Anisotropy; public static MaterialProperty anisotropy;
public static MaterialProperty KKColor; public static MaterialProperty kkColor;
public static MaterialProperty BSDFContribution; public static MaterialProperty bsdfContribution;
public static MaterialProperty SpecularColorMap; public static MaterialProperty specularColorMap;
public static MaterialProperty SpecularColor; public static MaterialProperty specularColor;
public static MaterialProperty SpecularFeather; public static MaterialProperty specularFeather;
public static MaterialProperty SpecularStep; public static MaterialProperty specularStep;
public static MaterialProperty hairBlendingMap;
public static MaterialProperty emissiveColorLDR; public static MaterialProperty emissiveColorLDR;
public static MaterialProperty emissiveColorMap; public static MaterialProperty emissiveColorMap;
@@ -45,21 +47,23 @@ namespace Misaki.HdrpToon.Editor
private static class Styles private static class Styles
{ {
public static readonly GUIContent NormalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material."); public static readonly GUIContent normalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent MaskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness"); public static readonly GUIContent maskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness");
public static readonly GUIContent MetallicText = new("Metallic", "Specifies the metallic value of the material."); public static readonly GUIContent metallicText = new("Metallic", "Specifies the metallic value of the material.");
public static readonly GUIContent MetallicRemap = new("Metallic Remap", "Remap the max and min value of metallic"); public static readonly GUIContent metallicRemap = new("Metallic Remap", "Remap the max and min value of metallic");
public static readonly GUIContent AORemap = new("AO Remap", "Remap the max and min value of ambient occlusion"); public static readonly GUIContent aoRemap = new("AO Remap", "Remap the max and min value of ambient occlusion");
public static readonly GUIContent SmoothnessText = new("Smoothness", "Specifies the smoothness of the material."); public static readonly GUIContent smoothnessText = new("Smoothness", "Specifies the smoothness of the material.");
public static readonly GUIContent SmoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness"); public static readonly GUIContent smoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness");
public static readonly GUIContent AnisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material."); public static readonly GUIContent anisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material.");
public static readonly GUIContent KKColorText = new("KK specular Color", "Specifies the color of KK specular."); public static readonly GUIContent kkColorText = new("KK specular Color", "Specifies the color of KK specular.");
public static readonly GUIContent BSDFContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation"); public static readonly GUIContent bsdfContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation");
public static readonly GUIContent SpecularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material."); public static readonly GUIContent specularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material.");
public static readonly GUIContent SpecRemap = new("Specular Remap", "Feather and step value of Toon Specular"); public static readonly GUIContent specRemap = new("Specular Remap", "Feather and step value of Toon Specular");
public static readonly GUIContent hairBlenderMapText = new("Hair Blending Map", "Specifies the hair blending map of the material.");
public static readonly GUIContent emissiveColorText = new("Emissive Color", "The color and color map to set for emissive effect."); public static readonly GUIContent emissiveColorText = new("Emissive Color", "The color and color map to set for emissive effect.");
public static readonly GUIContent albedoAffectEmissiveText = new("Albedo Affect Emissive", "Enable to affect emissive color with base color"); public static readonly GUIContent albedoAffectEmissiveText = new("Albedo Affect Emissive", "Enable to affect emissive color with base color");
@@ -73,28 +77,30 @@ namespace Misaki.HdrpToon.Editor
public override void LoadMaterialProperties() public override void LoadMaterialProperties()
{ {
Properties.NormalMap = FindProperty("_NormalMap"); Properties.normalMap = FindProperty("_NormalMap");
Properties.NormalMapScale = FindProperty("_NormalScale"); Properties.normalMapScale = FindProperty("_NormalScale");
Properties.MaskMap = FindProperty("_MaskMap"); Properties.maskMap = FindProperty("_MaskMap");
Properties.Metallic = FindProperty("_Metallic"); Properties.metallic = FindProperty("_Metallic");
Properties.MetallicRemapMin = FindProperty("_MetallicRemapMin"); Properties.metallicRemapMin = FindProperty("_MetallicRemapMin");
Properties.MetallicRemapMax = FindProperty("_MetallicRemapMax"); Properties.metallicRemapMax = FindProperty("_MetallicRemapMax");
Properties.AORemapMin = FindProperty("_AORemapMin"); Properties.aoRemapMin = FindProperty("_AORemapMin");
Properties.AORemapMax = FindProperty("_AORemapMax"); Properties.aoRemapMax = FindProperty("_AORemapMax");
Properties.SmoothnessRemapMin = FindProperty("_SmoothnessRemapMin"); Properties.smoothnessRemapMin = FindProperty("_SmoothnessRemapMin");
Properties.SmoothnessRemapMax = FindProperty("_SmoothnessRemapMax"); Properties.smoothnessRemapMax = FindProperty("_SmoothnessRemapMax");
Properties.Smoothness = FindProperty("_Smoothness"); Properties.smoothness = FindProperty("_Smoothness");
Properties.AnisotropyMap = FindProperty("_AnisotropyMap"); Properties.anisotropyMap = FindProperty("_AnisotropyMap");
Properties.Anisotropy = FindProperty("_Anisotropy"); Properties.anisotropy = FindProperty("_Anisotropy");
Properties.KKColor = FindProperty("_KKColor"); Properties.kkColor = FindProperty("_KKColor");
Properties.BSDFContribution = FindProperty("_BSDFContribution"); Properties.bsdfContribution = FindProperty("_BSDFContribution");
Properties.SpecularColorMap = FindProperty("_SpecularColorMap"); Properties.specularColorMap = FindProperty("_SpecularColorMap");
Properties.SpecularColor = FindProperty("_SpecularColor"); Properties.specularColor = FindProperty("_SpecularColor");
Properties.SpecularFeather = FindProperty("_ToonSpecularFeather"); Properties.specularFeather = FindProperty("_ToonSpecularFeather");
Properties.SpecularStep = FindProperty("_ToonSpecularStep"); Properties.specularStep = FindProperty("_ToonSpecularStep");
Properties.hairBlendingMap = FindProperty("_HairBlendingMap");
Properties.emissiveColorLDR = FindProperty(EMISSIVE_COLOR_LDR); Properties.emissiveColorLDR = FindProperty(EMISSIVE_COLOR_LDR);
Properties.emissiveColorMap = FindProperty(EMISSIVE_COLOR_MAP); Properties.emissiveColorMap = FindProperty(EMISSIVE_COLOR_MAP);
@@ -106,46 +112,51 @@ namespace Misaki.HdrpToon.Editor
protected override void DrawContent() protected override void DrawContent()
{ {
editor.KeywordTexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale); editor.KeywordTexturePropertySingleLine(Styles.normalMapText, Properties.normalMap, Properties.normalMapScale);
if (materials.All(mat => mat.GetPBRMode() != PBRMode.Off)) if (materials.All(mat => mat.GetPBRMode() != PBRMode.Off))
{ {
if (editor.KeywordTexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap)) if (editor.KeywordTexturePropertySingleLine(Styles.maskMapText, Properties.maskMap))
{ {
editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1, Styles.MetallicRemap); editor.MinMaxShaderProperty(Properties.metallicRemapMin, Properties.metallicRemapMax, 0, 1, Styles.metallicRemap);
editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap); editor.MinMaxShaderProperty(Properties.aoRemapMin, Properties.aoRemapMax, 0, 1, Styles.aoRemap);
editor.MinMaxShaderProperty(Properties.SmoothnessRemapMin, Properties.SmoothnessRemapMax, 0, 1, Styles.SmoothnessRemapText); editor.MinMaxShaderProperty(Properties.smoothnessRemapMin, Properties.smoothnessRemapMax, 0, 1, Styles.smoothnessRemapText);
} }
else else
{ {
if (materials.All(mat => mat.GetPBRMode() != PBRMode.KKHair)) if (materials.All(mat => mat.GetPBRMode() != PBRMode.KKHair))
{ {
editor.ShaderProperty(Properties.Metallic, Styles.MetallicText); editor.ShaderProperty(Properties.metallic, Styles.metallicText);
} }
editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText); editor.ShaderProperty(Properties.smoothness, Styles.smoothnessText);
} }
} }
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.KKHair)) if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.KKHair))
{ {
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap, Properties.Anisotropy); editor.KeywordTexturePropertySingleLine(Styles.anisotropyMapText, Properties.anisotropyMap, Properties.anisotropy);
if (materials.All(mat => mat.GetPBRMode() == PBRMode.KKHair)) if (materials.All(mat => mat.GetPBRMode() == PBRMode.KKHair))
{ {
editor.ShaderProperty(Properties.KKColor, Styles.KKColorText); editor.ShaderProperty(Properties.kkColor, Styles.kkColorText);
editor.ShaderProperty(Properties.BSDFContribution, Styles.BSDFContributionText); editor.ShaderProperty(Properties.bsdfContribution, Styles.bsdfContributionText);
} }
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.LabelField("Anisotropy Map only ST"); EditorGUILayout.LabelField("Anisotropy Map only ST");
editor.TextureScaleOffsetProperty(Properties.AnisotropyMap); editor.TextureScaleOffsetProperty(Properties.anisotropyMap);
} }
else if (materials.All(mat => mat.GetPBRMode() == PBRMode.Toon)) else if (materials.All(mat => mat.GetPBRMode() == PBRMode.Toon))
{ {
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap, Properties.SpecularColor); editor.KeywordTexturePropertySingleLine(Styles.specularColorMapText, Properties.specularColorMap, Properties.specularColor);
editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1, Styles.SpecRemap); editor.MinMaxShaderProperty(Properties.specularFeather, Properties.specularStep, 0, 1, Styles.specRemap);
}
if (materials.All(mat => mat.IsHairBlendingTarget()))
{
editor.TexturePropertySingleLine(Styles.hairBlenderMapText, Properties.hairBlendingMap);
} }
EditorGUILayout.Space(); EditorGUILayout.Space();

View File

@@ -90,7 +90,7 @@ namespace Misaki.HdrpToon.Editor
{ {
foreach (var material in materials) foreach (var material in materials)
{ {
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, Properties.hairBlendingTarget.floatValue == 1.0f); material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, Properties.hairBlendingTarget.GetBooleanValue());
} }
} }

View File

@@ -7,6 +7,7 @@ namespace Misaki.HdrpToon
public const string SHADING_MODE = "_Shading_Mode"; public const string SHADING_MODE = "_Shading_Mode";
public const string PBR_MODE = "_PBR_Mode"; public const string PBR_MODE = "_PBR_Mode";
public const string SURFACE_FEATURE = "_SurfaceFeatures"; public const string SURFACE_FEATURE = "_SurfaceFeatures";
public const string MATERIAL_TYPE = "_Material_Type";
} }
public static class SurfaceInputs public static class SurfaceInputs

View File

@@ -119,6 +119,8 @@ Shader "HDRP/Toon"
_SDFShadowSmoothLevel("SDFShadowSmoothLevel", Range(0.0, 0.1)) = 0.02 _SDFShadowSmoothLevel("SDFShadowSmoothLevel", Range(0.0, 0.1)) = 0.02
_SDFHighlightStrength("SDFHighlightStrength", Range(0.0, 1.0)) = 0.75 _SDFHighlightStrength("SDFHighlightStrength", Range(0.0, 1.0)) = 0.75
_HairBlendingFactor("HairBlendingFactor", Range(0.0, 1.0)) = 0.5
// 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", Integer) = 0 [Popup] _Receive_Screen_Space_Shadow("Receive Screen Space Shadow", Integer) = 0

View File

@@ -44,9 +44,10 @@ float GetHairShadow(PositionInputs posInput, float3 L)
float cameraDirFactor = 1 - smoothstep(0.1, 0.9, cameraDirOS.y); float cameraDirFactor = 1 - smoothstep(0.1, 0.9, cameraDirOS.y);
shadowLength.y *= cameraDirFactor; shadowLength.y *= cameraDirFactor;
// TODO: sample point is still shifting when fov change.
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.
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 * _RTHandleScale.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 hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r; float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r;
shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow); shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow);
} }

View File

@@ -62,11 +62,11 @@ float _ToonIgnoreExposureMultiplier;
float _Outline_MaxWidth; float _Outline_MaxWidth;
float4 _HairShadowRTHandleScale;
float4 _HairBlendingRTHandleScale;
float _HairShadowDistance; float _HairShadowDistance;
float _HairShadowDistanceScaleFactor; float _HairShadowDistanceScaleFactor;
float _HairShadowDepthBias; float _HairShadowDepthBias;
float _HairShadowFadeInDistance; float _HairShadowFadeInDistance;
float _HairShadowFadeOutDistance; float _HairShadowFadeOutDistance;
// float2 _HairShadowRTHandleScale;
// float2 _HairBlendingRTHandleScale;

View File

@@ -73,7 +73,6 @@ void Frag(PackedVaryingsToPS packedInput,
// The following temporary definition of unity_AmbientEquator is for HDRP only. // The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo. //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 = 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_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max( float3 envLightSource_SkyboxIntensity = max(
@@ -83,8 +82,8 @@ void Frag(PackedVaryingsToPS packedInput,
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator; float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier(); ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap)); float4 blendingTex = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a); outColor = float4(blendingTex.rgb + ambientSkyColor, blendingTex.a);
#ifdef _DEPTHOFFSET_ON #ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth; outputDepth = posInput.deviceDepth;

View File

@@ -165,9 +165,9 @@ void Frag(PackedVaryingsToPS packedInput,
outColor = float4(finalColor, 1.0); outColor = float4(finalColor, 1.0);
#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.positionSS; // * _HairBlendingRTHandleScale.xy; // Why we don't need to scale? Does unity handle it internally?
float4 hairBlendingMap = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV); float4 hairBlendingTex = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor); outColor.rgb = lerp(outColor.rgb, hairBlendingTex.rgb, hairBlendingTex.a * _HairBlendingFactor);
#endif #endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW #if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW

View File

@@ -21,15 +21,12 @@ 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_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_SHADOW_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";
@@ -43,7 +40,9 @@ namespace Misaki.HdrpToon
private RTHandle _hairShadowRTHandle; private RTHandle _hairShadowRTHandle;
private bool _needReallocateHairShadow; private bool _needReallocateHairShadow;
// TODO: Possible to avoid another RTHandle for depth?
private RTHandle _hairBlendingRTHandle; private RTHandle _hairBlendingRTHandle;
private RTHandle _hairBlendingDepthRTHandle;
private bool _needReallocateHairBlending; private bool _needReallocateHairBlending;
private bool _enableHairShadow; private bool _enableHairShadow;
@@ -142,15 +141,16 @@ namespace Misaki.HdrpToon
} }
#endif #endif
var scale = _hairShadowQuality switch // Use R8 or R16 directly?
var format = _hairShadowQuality switch
{ {
BufferQuality.Low => new Vector2(0.5f, 0.5f), BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => Vector2.one, BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => Vector2.zero _ => GraphicsFormat.R16G16B16A16_SFloat
}; };
_hairShadowRTHandle?.Release(); _hairShadowRTHandle?.Release();
_hairShadowRTHandle = RTHandles.Alloc(scale, useDynamicScale: true, format: GraphicsFormat.D16_UNorm, isShadowMap: true, name: _HAIR_SHADOW_RT_PROP_NAME); _hairShadowRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, format: format, isShadowMap: true, name: _HAIR_SHADOW_RT_PROP_NAME);
Shader.SetGlobalTexture(_HAIR_SHADOW_RT_PROP_NAME, _hairShadowRTHandle); Shader.SetGlobalTexture(_HAIR_SHADOW_RT_PROP_NAME, _hairShadowRTHandle);
_needReallocateHairShadow = false; _needReallocateHairShadow = false;
@@ -179,6 +179,13 @@ namespace Misaki.HdrpToon
_hairBlendingRTHandle?.Release(); _hairBlendingRTHandle?.Release();
_hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: format, name: _HAIR_BLENDING_PROP_NAME); _hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: format, name: _HAIR_BLENDING_PROP_NAME);
if (_hairBlendingDepthRTHandle == null || _hairBlendingDepthRTHandle.rt == null || !_hairBlendingDepthRTHandle.rt.IsCreated())
{
_hairBlendingDepthRTHandle?.Release();
_hairBlendingDepthRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.D16_UNorm, name: _HAIR_BLENDING_PROP_NAME + "_depth");
}
Shader.SetGlobalTexture(_HAIR_BLENDING_PROP_NAME, _hairBlendingRTHandle); Shader.SetGlobalTexture(_HAIR_BLENDING_PROP_NAME, _hairBlendingRTHandle);
_needReallocateHairBlending = false; _needReallocateHairBlending = false;
@@ -274,7 +281,6 @@ namespace Misaki.HdrpToon
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); 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_PROP_NAME, utsRenderer.shadowDistance.value);
Shader.SetGlobalFloat(_HAIR_SHADOW_DISTANCE_SCALE_PROP_NAME, utsRenderer.shadowDistanceScale.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_DEPTH_BIAS_PROP_NAME, utsRenderer.shadowDepthBias.value);
@@ -298,7 +304,7 @@ namespace Misaki.HdrpToon
using (new ProfilingScope(ctx.cmd, _hairBlendingProfilingSampler)) using (new ProfilingScope(ctx.cmd, _hairBlendingProfilingSampler))
{ {
CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, ctx.cameraDepthBuffer, ClearFlag.Color); CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, _hairBlendingDepthRTHandle, ClearFlag.Color | ClearFlag.Depth);
var result = new RendererListDesc(UtsShaderPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new RendererListDesc(UtsShaderPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
@@ -308,7 +314,6 @@ namespace Misaki.HdrpToon
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
Shader.SetGlobalVector(_HAIR_BLENDING_RTHANDLE_SCALE_PROP_NAME, _hairBlendingRTHandle.rtHandleProperties.rtHandleScale);
} }
} }