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

@@ -4,13 +4,14 @@
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl"
#define UTS_LAYER_VISIBILITY
#ifndef DIRECTIONAL
# define DIRECTIONAL
#endif
#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)
#undef FOG_LINEAR

View File

@@ -1,28 +1,44 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION
// Rim light is calculated per light
float3 UtsEvaluateColor_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, float3 L, float3 lightColor)
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
#if _LIGHT_BASE_RIM_LIGHT_ON
, float3 L, float3 lightColor
#endif
)
{
float clampNdotV = ClampNdotV(preLightData.NdotV);
float rimLightWeight = 1.0 - clampNdotV;
rimLightWeight = pow(rimLightWeight, exp2(lerp(3.0, 0.0, _RimLightLevel)));
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 rimLightColor = _RimLightColor.rgb * _RimLightIntensity;
#if _SCREEN_SPACE_RIM_LIGHT_ON
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 depthDiff = saturate(posInput.deviceDepth - offsetedDepth);
float rimLightMask = step(0.0025 / posInput.linearDepth, depthDiff);
#else
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
#if _LIGHT_BASE_RIM_LIGHT_ON
float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5;
//float rimLightMask = lerp(0.5 * lambert + 0.5, saturate(lambert), _Tweak_LightDirection_MaskLevel * 2.0);
float rimLightMask = saturate(smoothstep(_Tweak_LightDirection_MaskLevel, 1.0, halfLambert));
float lightBaseMask = saturate(smoothstep(_LightDirectionRimLightLevel, 1.0, halfLambert));
rimLightWeight = step(0.0025 / posInput.linearDepth, depthDiff);
float3 outColor = rimLightWeight * lightColor * _RimLightColor * _RimLightStrength;
return outColor * rimLightMask;
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;
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;
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));
float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity;
float weight = saturate(dot(normalize(V), normalWS));
lighting.specular += angelRingColor.r * angelRingColor.a * weight;
lighting.specular = angelRingColor.r * angelRingColor.a * weight;
return lighting;
}

View File

@@ -137,7 +137,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
#else
lightCount = _PunctualLightCount;
lightStart = 0;
#endif
@@ -374,9 +374,17 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#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))
{
DirectLighting lighting = UtsEvaluateAngelRing(fragInputs, bsdfData.normalWS, V);
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
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 baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - firstColorFeatherForMask)) / (_1stShadeColorStep - (_1stShadeColorStep - firstColorFeatherForMask)));
baseShadeMask *= shadow;
baseShadeMask *= shadow.x;
float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
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);
specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * shadow;
float shadeMask = sdfShadowMask * sdfTexture.b * shadow.x;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask);
specularTerm = (specularTerm + sdfHighlight) * shadeMask;
@@ -177,10 +177,15 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer;
#if _LIGHT_BASE_RIM_LIGHT_ON
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;

View File

@@ -12,6 +12,7 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
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);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, 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)
{
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 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float3 viewLightDir = TransformWorldToViewDir(L);
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;
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float cameraDirFactor = 1 - smoothstep(0.1, 0.9, cameraDirOS.y);
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.
// 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.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_linear_clamp_sampler, scaledUVs).r;
float shadowMask = 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.
shadow = lerp(1, 1.0 - hairShadowOpacity, shadowMask);
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);
}
return shadow;

View File

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

View File

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

View File

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

View File

@@ -91,15 +91,10 @@ void Frag(PackedVaryingsToPS packedInput,
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#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.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
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);
@@ -111,7 +106,7 @@ void Frag(PackedVaryingsToPS packedInput,
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
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
#else
@@ -157,115 +152,6 @@ void Frag(PackedVaryingsToPS packedInput,
ZERO_INITIALIZE(LightLoopOutput, 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;
@@ -283,7 +169,7 @@ void Frag(PackedVaryingsToPS packedInput,
#if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING
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);
#endif