SMAA代码详解 - SMAALumaEdgeDetectionPS
程序员文章站
2022-06-24 16:31:45
SMAALuamaEdgeDetectionPS...
SMAALumaEdgeDetectionPS
/**
* Luma Edge Detection
*
* IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and
* thus 'colorTex' should be a non-sRGB texture.
*/
float2 SMAALumaEdgeDetectionPS(float2 texcoord,
float4 offset[3],
SMAATexture2D(colorTex)
#if SMAA_PREDICATION
, SMAATexture2D(predicationTex)
#endif
) {
- 计算边界阈值
预测纹理(通过预计算,得到更精确的阈值,可以通过深度寻边或颜色寻边获取)。
// Calculate the threshold:
#if SMAA_PREDICATION
float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
#else
float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD);
#endif
- 计算亮度值(RGB转Luma)
计算当前像素,左一像素,上一像素的亮度值
// Calculate lumas:
float3 weights = float3(0.2126, 0.7152, 0.0722);
float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights);
float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights);
float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights);
- 计算当前像素点与左边/上边的像素的差值。
如果小于阈值(没有边)就丢弃该像素点。结果存放在 delta.xy (x代表左边界,y代表上边界)
// We do the usual threshold:
float4 delta;
delta.xy = abs(L - float2(Lleft, Ltop));
float2 edges = step(threshold, delta.xy);
// Then discard if there is no edge:
if (dot(edges, float2(1.0, 1.0)) == 0.0)
discard;
- 存在左边界或者上边界,计算右边界,下边界,左边的左边界,上边的上边界。
获取最大的finalDelta值。
// Calculate right and bottom deltas:
float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights);
float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights);
delta.zw = abs(L - float2(Lright, Lbottom));
// Calculate the maximum delta in the direct neighborhood:
float2 maxDelta = max(delta.xy, delta.zw);
// Calculate left-left and top-top deltas:
float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights);
float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights);
delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop));
// Calculate the final maximum delta:
maxDelta = max(maxDelta.xy, delta.zw);
float finalDelta = max(maxDelta.x, maxDelta.y);
- 通过计算得到的finalDelta,重新对比左边界/上边界。
// Local contrast adaptation:
#if !defined(SHADER_API_OPENGL)
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
#endif
- 二次比对的目的解决出现邻近的两条边的情况,减少不必要的重复的边界。
- edgeTex颜色
edges.x == 1 : 存在左边界, == 0 :不存在左边界
edges.y == 1 : 存在上边界,== 0 :不存在上边界
因此:输出的EdgeTex存在红(1,0,0),绿(0,1,0),黄(1,1,0),黑(0,0,0) 四种颜色
本文地址:https://blog.csdn.net/weixin_43859510/article/details/107294289