当前位置: 移动技术网 > IT编程>开发语言>Java > SMAA代码详解 - SMAALumaEdgeDetectionPS

SMAA代码详解 - SMAALumaEdgeDetectionPS

2020年07月13日  | 移动技术网IT编程  | 我要评论

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
                               ) {

  1. 计算边界阈值​​
    预测纹理(通过预计算,得到更精确的阈值,可以通过深度寻边或颜色寻边获取)。​​​​​
	 // Calculate the threshold:
    #if SMAA_PREDICATION
    float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
    #else
    float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD);
    #endif

  1. 计算亮度值(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);

  1. 计算当前像素点与左边/上边的像素的差值。
    如果小于阈值(没有边)就丢弃该像素点。结果存放在 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;

  1. 存在左边界或者上边界,计算右边界,下边界,左边的左边界,上边的上边界。
    获取最大的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);

  1. 通过计算得到的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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网