135 lines
4.6 KiB
Plaintext
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
|
|
}
|
|
}
|
|
} |