using Unity.Toonshader; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.RendererUtils; [HideInInspector] public class UTSHairShadowPass : DrawRenderersCustomPass { private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance"; private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor"; private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias"; private const string Hair_Shadow_FadeIn_Prop_Name = "_HairShadowFadeInDistance"; private const string Hair_Shadow_Fade_Out_Prop_Name = "_HairShadowFadeOutDistance"; private const string Output_RT_Name = "_HairShadowTex"; private RTHandle _outputRTHandle; private bool _isEnable = false; protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) { _outputRTHandle?.Release(); _outputRTHandle = RTHandles.Alloc(Screen.width, Screen.height, colorFormat: GraphicsFormat.D32_SFloat, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, name: Output_RT_Name); SetEnable(true); } protected override void Execute(CustomPassContext ctx) { var utsRenderer = ctx.hdCamera.volumeStack.GetComponent(); if (utsRenderer == null || !utsRenderer.enableHairShadow.value || !utsRenderer.enable.value) { SetEnable(false); return; } if (!_isEnable) { return; } SetShadowProperty(utsRenderer); if (_outputRTHandle != null) { Shader.SetGlobalTexture(Output_RT_Name, _outputRTHandle); CoreUtils.SetRenderTarget(ctx.cmd, _outputRTHandle, ClearFlag.DepthStencil); } var mask = RenderStateMask.Nothing; var stateBlock = new RenderStateBlock(mask) { depthState = new DepthState(depthWrite, depthCompareFunction), }; var result = new RendererListDesc(HDShaderPassNames.s_DepthForwardOnlyName, ctx.cullingResults, ctx.hdCamera.camera) { renderQueueRange = GetRenderQueueRange(renderQueueType), sortingCriteria = sortingCriteria, excludeObjectMotionVectors = false, stateBlock = stateBlock, layerMask = layerMask, }; CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); } private static void SetShadowProperty(UTSRenderer utsRenderer) { 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); } protected override void Cleanup() { Release(); } public void Release() { SetEnable(false); _outputRTHandle?.Release(); } public void SetEnable(bool isEnable) { if (_isEnable != isEnable) { if (isEnable) { Shader.EnableKeyword("_HAIR_SHADOWS"); } else { Shader.DisableKeyword("_HAIR_SHADOWS"); } _isEnable = isEnable; } } }