81 lines
2.9 KiB
HLSL
81 lines
2.9 KiB
HLSL
#ifndef BLUR_FULLSCREEN_INCLUDED
|
|
#define BLUR_FULLSCREEN_INCLUDED
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
|
|
|
float _BlurRadius;
|
|
float _GlowThreshold;
|
|
float _GlowIntensity;
|
|
|
|
TEXTURE2D_X(_BlurSource);
|
|
SAMPLER(sampler_BlurSource);
|
|
float4 _BlurSource_TexelSize;
|
|
|
|
float Hash(float2 p)
|
|
{
|
|
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
|
}
|
|
|
|
float3 ApplyGlowThreshold(float3 color)
|
|
{
|
|
float luminance = dot(color, float3(0.2126, 0.7152, 0.0722));
|
|
float mask = smoothstep(_GlowThreshold, _GlowThreshold + 0.3, luminance);
|
|
return color * mask;
|
|
}
|
|
|
|
void Blur_float
|
|
(
|
|
float2 UV,
|
|
bool IsVertical,
|
|
out float3 Output
|
|
)
|
|
{
|
|
float rawDepth = SampleSceneDepth(UV);
|
|
float depthMeters = LinearEyeDepth(rawDepth, _ZBufferParams);
|
|
float depthFactor = smoothstep(3, 20, depthMeters);
|
|
|
|
float stepY = (_BlurRadius * depthFactor) / 6.0;
|
|
float stepX = stepY * (_BlurSource_TexelSize.w / _BlurSource_TexelSize.z);
|
|
float jitter = (Hash(UV * _BlurSource_TexelSize.zw) - 0.5) * _BlurRadius * depthFactor * 20.0;
|
|
|
|
float2 dir = IsVertical ? float2(0.0, stepY) : float2(stepX, 0.0);
|
|
|
|
const int TAPS = 13;
|
|
const float offsets[13] = { -6.0, -4.7, -3.2, -2.1, -1.2, -0.4, 0.0, 0.4, 1.2, 2.1, 3.2, 4.7, 6.0 };
|
|
const float weights[13] =
|
|
{
|
|
0.00650, 0.02981, 0.07810, 0.14624, 0.22230, 0.27240,
|
|
0.29000,
|
|
0.27240, 0.22230, 0.14624, 0.07810, 0.02981, 0.00650
|
|
};
|
|
|
|
float3 centerColor = SAMPLE_TEXTURE2D_X(_BlurSource, sampler_BlurSource, UV).rgb;
|
|
float3 result = float3(0.0, 0.0, 0.0);
|
|
float totalWeight = 0.0;
|
|
|
|
for (int i = 0; i < TAPS; i++)
|
|
{
|
|
float2 offsetUV = UV + dir * (offsets[i] + jitter);
|
|
float tapRawDepth = SampleSceneDepth(offsetUV);
|
|
float tapDepth = LinearEyeDepth(tapRawDepth, _ZBufferParams);
|
|
float depthDiff = abs(tapDepth - depthMeters);
|
|
float depthWeight = exp(-depthDiff * 0.5);
|
|
float sw = weights[i] * depthWeight;
|
|
float3 tapColor = SAMPLE_TEXTURE2D_X(_BlurSource, sampler_BlurSource, offsetUV).rgb;
|
|
|
|
// GlowIntensity = 0 → full color blur, GlowIntensity = 1 → bright pixels only
|
|
float3 contribution = lerp(tapColor, ApplyGlowThreshold(tapColor), saturate(_GlowIntensity));
|
|
result += contribution * sw;
|
|
totalWeight += sw;
|
|
}
|
|
|
|
float3 center = lerp(centerColor, ApplyGlowThreshold(centerColor), saturate(_GlowIntensity));
|
|
|
|
// Scene color for additive glow compositing
|
|
float3 sceneColor = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_LinearClamp, UV).rgb;
|
|
float3 blurred = totalWeight > 0.01 ? result / totalWeight : center;
|
|
|
|
// GlowIntensity = 0 → pure blur, GlowIntensity > 0 → scene + additive glow
|
|
Output = lerp(blurred, sceneColor + blurred, saturate(_GlowIntensity));
|
|
}
|
|
#endif |