目录 - SMAA代码详解
SMAALumaEdgeDetectionPS
float2 SMAALumaEdgeDetectionPS ( float2 texcoord,
float4 offset[ 3 ] ,
SMAATexture2D ( colorTex)
# if SMAA_PREDICATION
, SMAATexture2D ( predicationTex)
# endif
) {
计算边界阈值 预测纹理(通过预计算,得到更精确的阈值,可以通过深度寻边或颜色寻边获取)。
# if SMAA_PREDICATION
float2 threshold = SMAACalculatePredicatedThreshold ( texcoord, offset, SMAATexturePass2D ( predicationTex) ) ;
# else
float2 threshold = float2 ( SMAA_THRESHOLD, SMAA_THRESHOLD) ;
# endif
计算亮度值(RGB转Luma) 计算当前像素,左一像素,上一像素的亮度值
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代表上边界)
float4 delta;
delta. xy = abs ( L - float2 ( Lleft, Ltop) ) ;
float2 edges = step ( threshold, delta. xy) ;
if ( dot ( edges, float2 ( 1.0 , 1.0 ) ) == 0.0 )
discard;
存在左边界或者上边界,计算右边界,下边界,左边的左边界,上边的上边界。 获取最大的finalDelta值。
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) ) ;
float2 maxDelta = max ( delta. xy, delta. zw) ;
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) ) ;
maxDelta = max ( maxDelta. xy, delta. zw) ;
float finalDelta = max ( maxDelta. x, maxDelta. y) ;
通过计算得到的finalDelta,重新对比左边界/上边界。
# 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) 四种颜色