Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 65 additions & 44 deletions SMAA.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,24 @@ SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; Addres
#define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0)
#endif
#endif
#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4)
#define SMAATexture2D(tex) sampler2D tex
#define SMAATexturePass2D(tex) tex
#if defined(SMAA_GLSL_2) || defined(SMAA_GLSL_ES2) || defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4)
#if defined(SMAA_GLSL_2) || defined(SMAA_GLSL_ES2)
#define SMAASampleLevelZero(tex, coord) texture2D(tex, coord)
#define SMAASampleLevelZeroPoint(tex, coord) texture2D(tex, coord)
#define SMAASampleLevelZeroOffset(tex, coord, offset) texture2D(tex, coord + offset * SMAA_RT_METRICS.xy)
#define SMAASample(tex, coord) texture2D(tex, coord)
#define SMAASamplePoint(tex, coord) texture2D(tex, coord)
#define SMAASampleOffset(tex, coord, offset) texture2D(tex, coord + offset * SMAA_RT_METRICS.xy)
#else
#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0)
#define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0)
#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset)
#define SMAASample(tex, coord) texture(tex, coord)
#define SMAASamplePoint(tex, coord) texture(tex, coord)
#define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset)
#define SMAASampleOffset(tex, coord, offset) textureOffset(tex, coord, offset)
#endif
#define SMAATexture2D(tex) sampler2D tex
#define SMAATexturePass2D(tex) tex
#define SMAA_FLATTEN
#define SMAA_BRANCH
#define lerp(a, b, t) mix(a, b, t)
Expand All @@ -585,8 +594,20 @@ SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; Addres
#define bool3 bvec3
#define bool4 bvec4
#endif
#if defined(SMAA_GLSL_2) || defined(SMAA_GLSL_ES2)
#define SMAARound(v) floor((v) + .5)
#define SMAAOffset(x,y) vec2(x,y)
#else
#define SMAARound(v) round(v)
#define SMAAOffset(x,y) int2(x,y)
#endif
#if defined(SMAA_GLSL_ES2)
#define SMAAWhile(condition) for (int i = 0; i < SMAA_MAX_SEARCH_STEPS; i++) { if (!(condition)) break;
#else
#define SMAAWhile(condition) while (condition) {
#endif

#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL)
#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_2) && !defined(SMAA_GLSL_ES2) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL)
#error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL
#endif

Expand Down Expand Up @@ -848,12 +869,12 @@ float2 SMAADecodeDiagBilinearAccess(float2 e) {
// This function will unpack the values (mad + mul + round):
// wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1
e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75);
return round(e);
return SMAARound(e);
}

float4 SMAADecodeDiagBilinearAccess(float4 e) {
e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75);
return round(e);
return SMAARound(e);
}

/**
Expand All @@ -862,8 +883,8 @@ float4 SMAADecodeDiagBilinearAccess(float4 e) {
float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) {
float4 coord = float4(texcoord, -1.0, 1.0);
float3 t = float3(SMAA_RT_METRICS.xy, 1.0);
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9) {
SMAAWhile (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9)
coord.xyz = mad(t, float3(dir, 1.0), coord.xyz);
e = SMAASampleLevelZero(edgesTex, coord.xy).rg;
coord.w = dot(e, float2(0.5, 0.5));
Expand All @@ -875,8 +896,8 @@ float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out
float4 coord = float4(texcoord, -1.0, 1.0);
coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization
float3 t = float3(SMAA_RT_METRICS.xy, 1.0);
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9) {
SMAAWhile (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9)
coord.xyz = mad(t, float3(dir, 1.0), coord.xyz);

// @SearchDiag2Optimization
Expand All @@ -886,7 +907,7 @@ float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out

// Non-optimized version:
// e.g = SMAASampleLevelZero(edgesTex, coord.xy).g;
// e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r;
// e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, SMAAOffset(1, 0)).r;

coord.w = dot(e, float2(0.5, 0.5));
}
Expand Down Expand Up @@ -934,17 +955,17 @@ float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex),
// Fetch the crossing edges:
float4 coords = mad(float4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
float4 c;
c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg;
c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, SMAAOffset(-1, 0)).rg;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, SMAAOffset( 1, 0)).rg;
c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw);

// Non-optimized version:
// float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
// float4 c;
// c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g;
// c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r;
// c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g;
// c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r;
// c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, SMAAOffset(-1, 0)).g;
// c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, SMAAOffset( 0, 0)).r;
// c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, SMAAOffset( 1, 0)).g;
// c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, SMAAOffset( 1, -1)).r;

// Merge crossing edges at each side into a single value:
float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw);
Expand All @@ -958,7 +979,7 @@ float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex),

// Search for the line ends:
d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end);
if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) {
if (SMAASampleLevelZeroOffset(edgesTex, texcoord, SMAAOffset(1, 0)).r > 0.0) {
d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end);
d.y += float(end.y > 0.9);
} else
Expand All @@ -969,9 +990,9 @@ float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex),
// Fetch the crossing edges:
float4 coords = mad(float4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
float4 c;
c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g;
c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, -1)).r;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr;
c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, SMAAOffset(-1, 0)).g;
c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, SMAAOffset( 0, -1)).r;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, SMAAOffset( 1, 0)).gr;
float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw);

// Remove the crossing edge if we didn't found the end of the line:
Expand Down Expand Up @@ -1025,9 +1046,9 @@ float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2
* which edges are active from the four fetched ones.
*/
float2 e = float2(0.0, 1.0);
while (texcoord.x > end &&
SMAAWhile (texcoord.x > end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e.r == 0.0) // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord);
}
Expand All @@ -1050,9 +1071,9 @@ float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2

float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(0.0, 1.0);
while (texcoord.x < end &&
SMAAWhile (texcoord.x < end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e.r == 0.0) // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord);
}
Expand All @@ -1062,9 +1083,9 @@ float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2

float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(1.0, 0.0);
while (texcoord.y > end &&
SMAAWhile (texcoord.y > end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e.g == 0.0) // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(-float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord);
}
Expand All @@ -1074,9 +1095,9 @@ float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 te

float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(1.0, 0.0);
while (texcoord.y < end &&
SMAAWhile (texcoord.y < end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e.g == 0.0) // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord);
}
Expand All @@ -1090,7 +1111,7 @@ float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2
*/
float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) {
// Rounding prevents precision errors of bilinear filtering:
float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist);
float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), SMAARound(4.0 * float2(e1, e2)), dist);

// We do a scale and bias for mapping to texel space:
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
Expand All @@ -1113,10 +1134,10 @@ void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 wei
rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line.

float2 factor = float2(1.0, 1.0);
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, 1)).r;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, 1)).r;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, -2)).r;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, -2)).r;
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, SMAAOffset(0, 1)).r;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, SMAAOffset(1, 1)).r;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, SMAAOffset(0, -2)).r;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, SMAAOffset(1, -2)).r;

weights *= saturate(factor);
#endif
Expand All @@ -1130,10 +1151,10 @@ void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weigh
rounding /= leftRight.x + leftRight.y;

float2 factor = float2(1.0, 1.0);
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, 1)).g;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, 1)).g;
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, SMAAOffset( 1, 0)).g;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, SMAAOffset( 1, 1)).g;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, SMAAOffset(-2, 0)).g;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, SMAAOffset(-2, 1)).g;

weights *= saturate(factor);
#endif
Expand Down Expand Up @@ -1185,14 +1206,14 @@ float4 SMAABlendingWeightCalculationPS(float2 texcoord,

// We want the distances to be in pixel units (doing this here allow to
// better interleave arithmetic and memory accesses):
d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx)));
d = abs(SMAARound(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx)));

// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically:
float2 sqrt_d = sqrt(d);

// Fetch the right crossing edges:
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r;
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, SMAAOffset(1, 0)).r;

// Ok, we know how this pattern looks like, now it is time for getting
// the actual area:
Expand Down Expand Up @@ -1226,14 +1247,14 @@ float4 SMAABlendingWeightCalculationPS(float2 texcoord,
d.y = coords.z;

// We want the distances to be in pixel units:
d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy)));
d = abs(SMAARound(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy)));

// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically:
float2 sqrt_d = sqrt(d);

// Fetch the bottom crossing edges:
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, 1)).g;
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, SMAAOffset(0, 1)).g;

// Get the area for this direction:
weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x);
Expand Down Expand Up @@ -1265,7 +1286,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord,

// Is there any blending weight with a value greater than 0.0?
SMAA_BRANCH
if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {
if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) <= 1e-5) {
float4 color = SMAASampleLevelZero(colorTex, texcoord);

#if SMAA_REPROJECTION
Expand Down