后处理
锐化¶
锐化算法用于增强图像中的细节和边缘的技术,即增强边缘上的差异,来突出边缘周围像素间颜色亮度值
边缘检测¶
- 为了识别数字图像中亮度变化明显的点 有以下常见的方式
- 一阶导数法:基于亮度的一阶导数进行检测
- 在亮度梯度中寻找峰值
- 用一维卷积可以表示为
|-1/2|0|1/2|
- 二阶导数法:
- 基于亮度的二阶导数进行检测,检测二阶导数中过零点的位置
- 表示为
|1|-2|1|
(泰勒展开)
- 计算出到术后,设置一个阈值来确定哪里是边缘位置即可
锐化算子¶
- 拉普拉斯算子
- \(\left(\begin{array}{ccc}-1&-1&-1\\-1&9&-1\\-1&-1&-1\end{array}\right)\)
- 对整个图片中每个像素做上麦那的卷积,将结果加回到原始的图像即可实现锐化
- 对噪声敏感,可能会导致图像噪声的增加
- 高斯-拉普拉斯算子锐化(LoG)
- 更好的对边缘进行检测,先用高斯核对图像进行平滑降噪,再用拉普拉斯核对图像进行边缘检测锐化
- 提升了对噪声的抑制能力
- Roberts 算子锐化
- 最为简易锐化核之一
- \(\left(\begin{array}{ccc}-1&0\\0&-1\end{array}\right)\)\(\left(\begin{array}{ccc}0&-1\\-1&0\end{array}\right)\)
- 不具备抗噪声的能力,适用于边缘陡峭但是噪声较少的图像
- sobel 算子锐化
- 可以增强图像中的水平和垂直边缘
- \(\left(\begin{array}{ccc}-1&-2&-1\\0&0&0\\1&2&1\end{array}\right)\)\(\left(\begin{array}{ccc}-1&0&1\\-2&0&2\\-1&0&1\end{array}\right)\)
工程实践¶
高斯模糊锐化(LoG)¶
Shader "FGSR/LumaGatedUnsharp"
{
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
Texture2D<float4> inputColor;
float4 displaySize;
float _SharpenStrength;
float _SharpenThreshold;
SamplerState smpLinearClamp;
float3 SampleSrc(float2 uv)
{ return inputColor.SampleLevel(smpLinearClamp, uv, 0).xyz;
}
float4 SampleSrc4(float2 uv)
{ return inputColor.SampleLevel(smpLinearClamp, uv, 0);
} float4 FragSharpen(Varyings input) : SV_Target
{
// 邻域偏移
float2 du = float2(displaySize.z, 0);
float2 dv = float2(0, displaySize.w);
float2 uv = input.positionCS.xy * displaySize.zw;
// 采样 3x3 real4 c4 = SampleSrc4(uv);
real3 c = c4.xyz;
real3 n = SampleSrc(uv - dv);
real3 s = SampleSrc(uv + dv);
real3 w = SampleSrc(uv - du);
real3 e = SampleSrc(uv + du);
real3 nw = SampleSrc(uv - du - dv);
real3 ne = SampleSrc(uv + du - dv);
real3 sw = SampleSrc(uv - du + dv);
real3 se = SampleSrc(uv + du + dv);
// 3x3 高斯近似(权重和=1)
real3 blur =
(nw + ne + sw + se) * 0.0625 // 1/16
+ (n + s + w + e) * 0.125 // 1/8
+ c * 0.25; // 1/4
float3 detail = c - blur;
// 阈值门控,避免放大噪点
float lumaMag = abs(dot(detail, float3(0.299, 0.587, 0.114)));
float weight = saturate((lumaMag - _SharpenThreshold) / max(lumaMag, 1e-6));
float3 gated = detail * weight;
// 软限幅,抑制边缘过冲(可调 0.25~0.75)
const float limit = 0.5;
float3 limited = clamp(gated, -limit, limit);
float3 outRGB = c + limited * (_SharpenStrength * c4.a);
return float4(outRGB, 1.0);
} ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass {
Name "LumaGatedUnsharp"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragSharpen
#pragma target 4.5
ENDHLSL
}
}}
FSR RCAS 锐化¶

