diff --git a/SMAA.hlsl b/SMAA.hlsl index 2c8d497..fe56527 100644 --- a/SMAA.hlsl +++ b/SMAA.hlsl @@ -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) @@ -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 @@ -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); } /** @@ -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)); @@ -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 @@ -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)); } @@ -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); @@ -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 @@ -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: @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); @@ -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 @@ -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 @@ -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: @@ -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); @@ -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