Added HairBlending shader pass;
Added HairBlendingSetting in UTSRenderPassSetting; Added MaterialType to UTS; Added MaterialFeature scope to UTS material editor; Merged HairBlendingPass and HairShadowPass into UTSPass; Fixed the bug that character box light can not update rotation correctly according to bound light source;
This commit is contained in:
@@ -10,12 +10,6 @@ namespace Misaki.HdrpToon
|
||||
[HideInInspector]
|
||||
internal class UTSHairShadowPass : DrawRenderersCustomPass
|
||||
{
|
||||
public enum ShadowQuality
|
||||
{
|
||||
Low,
|
||||
High
|
||||
}
|
||||
|
||||
private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale";
|
||||
private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance";
|
||||
private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor";
|
||||
@@ -23,13 +17,13 @@ namespace Misaki.HdrpToon
|
||||
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 const string Output_RT_Prop_Name = "_HairShadowTex";
|
||||
|
||||
private RTHandle _outputRTHandle;
|
||||
private bool _needReallocate;
|
||||
|
||||
private ShadowQuality _shadowQuality = ShadowQuality.High;
|
||||
internal ShadowQuality CurrentShadowQuality
|
||||
private BufferQuality _shadowQuality = BufferQuality.High;
|
||||
internal BufferQuality CurrentShadowQuality
|
||||
{
|
||||
get => _shadowQuality;
|
||||
set
|
||||
@@ -60,21 +54,21 @@ namespace Misaki.HdrpToon
|
||||
|
||||
var scale = _shadowQuality switch
|
||||
{
|
||||
ShadowQuality.Low => new Vector2(0.5f, 0.5f),
|
||||
ShadowQuality.High => Vector2.one,
|
||||
BufferQuality.Low => new Vector2(0.5f, 0.5f),
|
||||
BufferQuality.High => Vector2.one,
|
||||
_ => Vector2.zero
|
||||
};
|
||||
|
||||
var format = _shadowQuality switch
|
||||
{
|
||||
ShadowQuality.Low => GraphicsFormat.D16_UNorm,
|
||||
ShadowQuality.High => GraphicsFormat.D32_SFloat,
|
||||
BufferQuality.Low => GraphicsFormat.D16_UNorm,
|
||||
BufferQuality.High => GraphicsFormat.D32_SFloat,
|
||||
_ => GraphicsFormat.D16_UNorm
|
||||
};
|
||||
|
||||
_outputRTHandle?.Release();
|
||||
_outputRTHandle = RTHandles.Alloc(scale, colorFormat: format, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, isShadowMap: true, name: Output_RT_Name);
|
||||
Shader.SetGlobalTexture(Output_RT_Name, _outputRTHandle);
|
||||
_outputRTHandle = RTHandles.Alloc(scale, colorFormat: format, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, isShadowMap: true, useDynamicScale: true, name: Output_RT_Prop_Name);
|
||||
Shader.SetGlobalTexture(Output_RT_Prop_Name, _outputRTHandle);
|
||||
|
||||
_needReallocate = false;
|
||||
}
|
||||
@@ -102,18 +96,11 @@ namespace Misaki.HdrpToon
|
||||
return;
|
||||
}
|
||||
|
||||
var mask = RenderStateMask.Nothing;
|
||||
var stateBlock = new RenderStateBlock(mask)
|
||||
{
|
||||
depthState = new DepthState(true, CompareFunction.LessEqual),
|
||||
};
|
||||
|
||||
var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
|
||||
{
|
||||
renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
|
||||
sortingCriteria = SortingCriteria.CommonOpaque,
|
||||
excludeObjectMotionVectors = false,
|
||||
stateBlock = stateBlock,
|
||||
};
|
||||
|
||||
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
|
||||
|
||||
@@ -22,21 +22,12 @@ namespace Misaki.HdrpToon
|
||||
|
||||
Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f);
|
||||
|
||||
var mask = RenderStateMask.Nothing;
|
||||
var stateBlock = new RenderStateBlock(mask)
|
||||
{
|
||||
depthState = new DepthState(depthWrite, depthCompareFunction),
|
||||
// We disable the stencil when the depth is overwritten but we don't write to it, to prevent writing to the stencil.
|
||||
stencilState = new StencilState(false),
|
||||
};
|
||||
|
||||
var renderConfig = HDUtils.GetRendererConfiguration(false, false);
|
||||
var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UtsShaderPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera)
|
||||
{
|
||||
rendererConfiguration = renderConfig,
|
||||
renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
|
||||
excludeObjectMotionVectors = false,
|
||||
stateBlock = stateBlock,
|
||||
};
|
||||
|
||||
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.HighDefinition;
|
||||
using UnityEngine.Rendering.RendererUtils;
|
||||
|
||||
namespace Misaki.HdrpToon
|
||||
{
|
||||
[HideInInspector]
|
||||
internal class UTSPass : CustomPass
|
||||
{
|
||||
private const int Adjustment_Curve_Precision = 128;
|
||||
@@ -17,18 +21,256 @@ namespace Misaki.HdrpToon
|
||||
private const string Toon_Light_Filter_Prop_Name = "_ToonLightHiCutFilter";
|
||||
private const string Ignore_Volume_Exposure_Prop_Name = "_ToonIgnoreExposureMultiplier";
|
||||
|
||||
private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale";
|
||||
private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance";
|
||||
private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor";
|
||||
private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias";
|
||||
private const string Hair_Shadow_FadeIn_Prop_Name = "_HairShadowFadeInDistance";
|
||||
private const string Hair_Shadow_Fade_Out_Prop_Name = "_HairShadowFadeOutDistance";
|
||||
|
||||
private const string Hair_Blending_RTHandle_Scale_Prop_Name = "_HairBlendingRTHandleScale";
|
||||
|
||||
private const string Output_RT_Prop_Name = "_HairShadowTex";
|
||||
private const string Hair_Blending_Prop_Name = "_HairBlendingTex";
|
||||
|
||||
private float _max;
|
||||
private float _min;
|
||||
private float[] _exposureArray;
|
||||
|
||||
private RTHandle _hairShadowRTHandle;
|
||||
private bool _needReallocateHairShadow;
|
||||
|
||||
private RTHandle _hairBlendingRTHandle;
|
||||
private bool _needReallocateHairBlending;
|
||||
|
||||
private bool _enableHairShadow;
|
||||
public bool EnableHairShadow
|
||||
{
|
||||
get => _enableHairShadow;
|
||||
set
|
||||
{
|
||||
if (_enableHairShadow == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enableHairShadow = value;
|
||||
|
||||
if (_enableHairShadow)
|
||||
{
|
||||
Shader.EnableKeyword("ENABLE_UTS_HAIR_SHAOW");
|
||||
}
|
||||
else
|
||||
{
|
||||
Shader.DisableKeyword("ENABLE_UTS_HAIR_SHAOW");
|
||||
_hairShadowRTHandle?.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enableHairBlending;
|
||||
public bool EnableHairBlending
|
||||
{
|
||||
get => _enableHairBlending;
|
||||
set
|
||||
{
|
||||
if (_enableHairBlending == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enableHairBlending = value;
|
||||
|
||||
if (_enableHairBlending)
|
||||
{
|
||||
Shader.EnableKeyword("ENABLE_UTS_HAIR_BLENDING");
|
||||
}
|
||||
else
|
||||
{
|
||||
Shader.DisableKeyword("ENABLE_UTS_HAIR_BLENDING");
|
||||
_hairBlendingRTHandle?.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferQuality _hairShadowQuality = BufferQuality.High;
|
||||
internal BufferQuality HairShadowQuality
|
||||
{
|
||||
get => _hairShadowQuality;
|
||||
set
|
||||
{
|
||||
if (_hairShadowQuality == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_hairShadowQuality = value;
|
||||
_needReallocateHairShadow = true;
|
||||
}
|
||||
}
|
||||
|
||||
private BufferQuality _hairBlendingQuality = BufferQuality.High;
|
||||
internal BufferQuality HairBlendingQuality
|
||||
{
|
||||
get => _hairBlendingQuality;
|
||||
set
|
||||
{
|
||||
if (_hairBlendingQuality == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_hairBlendingQuality = value;
|
||||
_needReallocateHairBlending = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldReallocateHairShadowBuffer()
|
||||
{
|
||||
return _hairShadowRTHandle == null || _hairShadowRTHandle.rt == null || !_hairShadowRTHandle.rt.IsCreated() || _needReallocateHairShadow;
|
||||
}
|
||||
|
||||
private void ReallocateHairShadowBuffer()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
var scale = _hairShadowQuality switch
|
||||
{
|
||||
BufferQuality.Low => new Vector2(0.5f, 0.5f),
|
||||
BufferQuality.High => Vector2.one,
|
||||
_ => Vector2.zero
|
||||
};
|
||||
|
||||
var format = _hairShadowQuality switch
|
||||
{
|
||||
BufferQuality.Low => GraphicsFormat.D16_UNorm,
|
||||
BufferQuality.High => GraphicsFormat.D32_SFloat,
|
||||
_ => GraphicsFormat.D16_UNorm
|
||||
};
|
||||
|
||||
_hairShadowRTHandle?.Release();
|
||||
_hairShadowRTHandle = RTHandles.Alloc(scale, colorFormat: format, isShadowMap: true, useDynamicScale: true, name: Output_RT_Prop_Name);
|
||||
Shader.SetGlobalTexture(Output_RT_Prop_Name, _hairShadowRTHandle);
|
||||
|
||||
_needReallocateHairShadow = false;
|
||||
}
|
||||
|
||||
private bool ShouldReallocateHairBlendingBuffer()
|
||||
{
|
||||
return _hairBlendingRTHandle == null || _hairBlendingRTHandle.rt == null || !_hairBlendingRTHandle.rt.IsCreated() || _needReallocateHairBlending;
|
||||
}
|
||||
|
||||
private void ReallocateHairBlendingBuffer()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
var format = _hairBlendingQuality switch
|
||||
{
|
||||
BufferQuality.Low => GraphicsFormat.R8G8B8A8_SNorm,
|
||||
BufferQuality.High => GraphicsFormat.R8G8B8A8_SRGB,
|
||||
_ => GraphicsFormat.R8G8B8A8_SRGB
|
||||
};
|
||||
|
||||
_hairBlendingRTHandle?.Release();
|
||||
_hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, colorFormat: format, useDynamicScale: true, name: Hair_Blending_Prop_Name);
|
||||
Shader.SetGlobalTexture(Hair_Blending_Prop_Name, _hairBlendingRTHandle);
|
||||
|
||||
_needReallocateHairBlending = false;
|
||||
}
|
||||
|
||||
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
|
||||
{
|
||||
_exposureArray = new float[Adjustment_Curve_Precision];
|
||||
|
||||
ReallocateHairShadowBuffer();
|
||||
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)
|
||||
{
|
||||
if (utsRenderer == null)
|
||||
{
|
||||
return;
|
||||
@@ -86,6 +328,8 @@ namespace Misaki.HdrpToon
|
||||
protected override void Cleanup()
|
||||
{
|
||||
_exposureArray = null;
|
||||
_hairShadowRTHandle?.Release();
|
||||
_hairBlendingRTHandle?.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Misaki.HdrpToon
|
||||
private static UTSRenderPassSettings _renderSetting;
|
||||
|
||||
private static UTSPass _utsPass;
|
||||
private static UTSHairShadowPass _hairShadowPass;
|
||||
//private static UTSHairShadowPass _hairShadowPass;
|
||||
private static UTSOutlinePass _outlinePass;
|
||||
|
||||
static UTSRenderPassRegistrar() => RegisterCustomPasses();
|
||||
@@ -32,22 +32,21 @@ namespace Misaki.HdrpToon
|
||||
targetDepthBuffer = CustomPass.TargetBuffer.None,
|
||||
};
|
||||
|
||||
_hairShadowPass = new()
|
||||
{
|
||||
name = "UTS Hair Shadow Map",
|
||||
targetColorBuffer = CustomPass.TargetBuffer.None,
|
||||
targetDepthBuffer = CustomPass.TargetBuffer.None,
|
||||
};
|
||||
//_hairShadowPass = new()
|
||||
//{
|
||||
// name = "UTS Hair Shadow Map",
|
||||
// targetColorBuffer = CustomPass.TargetBuffer.None,
|
||||
// targetDepthBuffer = CustomPass.TargetBuffer.None,
|
||||
//};
|
||||
|
||||
_outlinePass = new()
|
||||
{
|
||||
name = "UTS Outline",
|
||||
targetColorBuffer = CustomPass.TargetBuffer.None,
|
||||
targetDepthBuffer = CustomPass.TargetBuffer.None,
|
||||
targetColorBuffer = CustomPass.TargetBuffer.Camera,
|
||||
targetDepthBuffer = CustomPass.TargetBuffer.Camera,
|
||||
};
|
||||
|
||||
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeRendering, _utsPass);
|
||||
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _hairShadowPass);
|
||||
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass);
|
||||
|
||||
NotifyRendererSettingChanged();
|
||||
@@ -56,23 +55,21 @@ namespace Misaki.HdrpToon
|
||||
public static void UnregisterGlobalCustomPass()
|
||||
{
|
||||
CustomPassVolume.UnregisterGlobalCustomPass(_utsPass);
|
||||
CustomPassVolume.UnregisterGlobalCustomPass(_hairShadowPass);
|
||||
CustomPassVolume.UnregisterGlobalCustomPass(_outlinePass);
|
||||
}
|
||||
|
||||
public static void NotifyRendererSettingChanged()
|
||||
{
|
||||
if (_hairShadowPass == null || _outlinePass == null)
|
||||
if (_utsPass == null || _outlinePass == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_hairShadowPass.enabled = _renderSetting.hairShadowSetting.enable;
|
||||
_hairShadowPass.CurrentShadowQuality = _renderSetting.hairShadowSetting.shadowQuality;
|
||||
if (!_renderSetting.hairShadowSetting.enable)
|
||||
{
|
||||
_hairShadowPass.Release();
|
||||
}
|
||||
_utsPass.EnableHairShadow = _renderSetting.hairShadowSetting.enable;
|
||||
_utsPass.HairShadowQuality = _renderSetting.hairShadowSetting.quality;
|
||||
|
||||
_utsPass.EnableHairBlending = _renderSetting.hairBlendingSetting.enable;
|
||||
_utsPass.HairBlendingQuality = _renderSetting.hairBlendingSetting.quality;
|
||||
|
||||
_outlinePass.enabled = _renderSetting.outlineSetting.enable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user