Files
ichni_Creator_Studio/Assets/Shaders/ScriptablePostProcessor/Shaders/StrobeFlash.shader
SoulliesOfficial aee62cd637 大修
2026-03-14 02:30:26 -04:00

135 lines
4.6 KiB
Plaintext

Shader "SLS/Postprocessing/StrobeFlash"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
// --- 参数定义 ---
float4 _StrobeColorHigh;
float4 _StrobeColorLow;
float4 _StrobeParams;
float4 _StrobeAdvParams;
// x: Noise Reduction
// y: Softness
// z: Outline Thickness
// w: Outline Threshold (新增:深度差异阈值)
float4 _LuminanceWeights;
// --- 辅助函数 ---
half3 BoxBlur(float2 uv, float radius)
{
float4 offset = _BlitTexture_TexelSize.xyxy * radius * float4(-1, -1, 1, 1);
half3 c1 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.xy).rgb;
half3 c2 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.zy).rgb;
half3 c3 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.xw).rgb;
half3 c4 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.zw).rgb;
return (c1 + c2 + c3 + c4) * 0.25;
}
// 修改:增加 threshold 参数
float GetEdge(float2 uv, float thickness, float threshold)
{
if(thickness <= 0) return 0;
float2 size = _BlitTexture_TexelSize.xy * thickness;
float d1 = SampleSceneDepth(uv + size);
float d2 = SampleSceneDepth(uv - size);
float d3 = SampleSceneDepth(uv + float2(size.x, -size.y));
float d4 = SampleSceneDepth(uv + float2(-size.x, size.y));
d1 = LinearEyeDepth(d1, _ZBufferParams);
d2 = LinearEyeDepth(d2, _ZBufferParams);
d3 = LinearEyeDepth(d3, _ZBufferParams);
d4 = LinearEyeDepth(d4, _ZBufferParams);
float diff1 = abs(d1 - d2);
float diff2 = abs(d3 - d4);
// 使用传入的阈值,而不是写死的 0.1
// 只有当深度差 > threshold 时,才认为是边缘
return step(threshold, diff1 + diff2);
}
half4 StrobeFlashPassFragment(Varyings input) : SV_Target
{
half2 uv = input.texcoord;
float frequency = _StrobeParams.x;
float threshold = _StrobeParams.y;
float noiseReduction = _StrobeAdvParams.x;
float softness = _StrobeAdvParams.y;
// 新增参数获取
float outlineThickness = _StrobeAdvParams.z;
float outlineThreshold = max(0.001, _StrobeAdvParams.w); // 防止除0或负数
float3 lumWeights = _LuminanceWeights.rgb;
// 采样颜色 (带降噪)
half3 sceneColor;
if (noiseReduction > 0.01)
{
sceneColor = BoxBlur(uv, noiseReduction);
}
else
{
sceneColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb;
}
float luminance = dot(sceneColor, lumWeights);
float softRange = max(0.001, softness);
float t = smoothstep(threshold - softRange, threshold + softRange, luminance);
float isAuto = _StrobeParams.z;
float isManualInvert = _StrobeParams.w;
float invertSignal = 0;
if (isAuto > 0.5)
{
invertSignal = step(0, sin(_Time.y * frequency * PI));
}
invertSignal = max(invertSignal, isManualInvert);
// 边缘检测:传入 Thickness 和 Threshold
float edge = GetEdge(uv, outlineThickness, outlineThreshold);
t = abs(t - edge);
float3 finalColor;
if (invertSignal > 0.5)
{
finalColor = lerp(_StrobeColorHigh.rgb, _StrobeColorLow.rgb, t);
}
else
{
finalColor = lerp(_StrobeColorLow.rgb, _StrobeColorHigh.rgb, t);
}
return half4(finalColor, 1);
}
ENDHLSL
Pass
{
Name "Strobe Flash Pass"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment StrobeFlashPassFragment
ENDHLSL
}
}
}