欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SMAA代码详解 - SMAALumaEdgeDetectionPS

程序员文章站 2022-03-23 07:51:39
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
                               ) {

  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

  • 二次比对的目的解决出现邻近的两条边的情况,减少不必要的重复的边界。
    SMAA代码详解 - SMAALumaEdgeDetectionPS

  • edgeTex颜色
    edges.x == 1 : 存在左边界, == 0 :不存在左边界
    edges.y == 1 : 存在上边界,== 0 :不存在上边界
    因此:输出的EdgeTex存在红(1,0,0),绿(0,1,0),黄(1,1,0),黑(0,0,0) 四种颜色​
    SMAA代码详解 - SMAALumaEdgeDetectionPS

本文地址:https://blog.csdn.net/weixin_43859510/article/details/107294289