首页 > 编程知识 正文

SMAA算法详解 SMAANeighborhoodBlendingPS,离散数学warshall算法详解

时间:2023-05-05 20:17:17 阅读:226246 作者:1841

目录 - SMAA代码详解

SMAANeighborhoodBlendingPS //-----------------------------------------------------------------------------// Neighborhood Blending Pixel Shader (Third Pass)float4 SMAANeighborhoodBlendingPS(float2 texcoord, float4 offset, SMAATexture2D(colorTex), SMAATexture2D(blendTex) #if SMAA_REPROJECTION , SMAATexture2D(velocityTex) #endif ) {

混合

获取权重值 a.x = SMAASample(blendTex, offset.xy).a; // Right a.y = SMAASample(blendTex, offset.zw).g; // Top a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left


2. 没有权重

if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {float4 color = SMAASampleLevelZero(colorTex, texcoord);#if SMAA_REPROJECTIONfloat2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord));// Pack velocity into the alpha channel:color.a = sqrt(5.0 * length(velocity));#endifreturn color;} 存在权重 bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical)

判断横向混合还是纵向混合水平锯齿纵向混合,垂直锯齿横向混合。

3.1 计算混合偏移

// Calculate the blending offsets:float4 blendingOffset = float4(0.0, a.y, 0.0, a.w);float2 blendingWeight = a.yw;SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0));SMAAMovc(bool2(h, h), blendingWeight, a.xz);

以上算法等同于:

bool h = max(a.x, a.z) > max(a.y, a.w)if(h){ blendingOffset = float4(a.x, 0.0, a.z, 0.0); blendingWeight = a.xz;}else{ bleningOffset = float4(0.0, a.y, 0.0, a.w); blendingWeight = a.yw;}

3.2 权重归一化

blendingWeight /= dot(blendingWeight, float2(1.0, 1.0));

混合比例总和应为1

3.3 计算采样纹理坐标

// Calculate the texture coordinates:float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy);

以水平锯齿为例:



观察上面的各阶段纹理,

WeightTex中上边界,红色部分与上混合,绿色部分的上一行与下混合。

双线性采样,
红色部分采样坐标等于 Texcoord.y - WeightTex.r,
绿色部分上一行坐标等于 Texcoord.y + WeightTex.g。

如果当前像素有上边界的 r 值,当前纹理坐标 texcoord.y -= WeightTex.r,
如果当前像素的下一行的像素有上边界的 g 值,当前纹理坐标 texcoord.y += WeightTex.g。

当前像素的 r 值:a.w = SMAASample(blendTex, texcoord).x,
当前像素下一行的g值:a.y = SMAASample(blendTex, offset.zw).g。

if(h == false){ blendingWeight = a.yw; blendingOffset.yw = (a.y, a.w); blendingCoord.yw = (texcoord.y + blendingOffset.y, texcoord.w - blendingOffset.w); }

同理可计算垂直锯齿。

3.4 混合颜色

// We exploit bilinear filtering to mix current pixel with the chosen // neighbor: float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy); color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw);

每个像素的权重都分为两个部分a1, a2,把这两个部分相加。就得到最终的颜色。

3.5 reprojection

#if SMAA_REPROJECTION // Antialias velocity for proper reprojection in a later stage: float2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy)); velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw)); // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif

for cryEngine(略)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。