diff --git a/Compositor/HDR/hdr.xml b/Compositor/HDR/hdr.xml index df2eb8bbe..69ef3e307 100644 --- a/Compositor/HDR/hdr.xml +++ b/Compositor/HDR/hdr.xml @@ -234,6 +234,30 @@ 0.0625 + + + smaa-edges + 2d + screen + screen + rgba8 + clamp + clamp + linear-mipmap-linear + linear + + + smaa-blend + 2d + screen + screen + rgba8 + clamp + clamp + linear-mipmap-linear + linear + + + - display + no-aa-display quad - Effects/HDR/display + Effects/HDR/trivial + + + /sim/rendering/hdr/antialiasing-technique + 0 + + 0 final + + + fxaa + quad + Effects/HDR/fxaa + + + /sim/rendering/hdr/antialiasing-technique + 1 + + + + 0 + final + + + + + + smaa-edge-detection + Effects/HDR/smaa-edge-detection + color + 0.0 0.0 0.0 0.0 + + 0 + final + + + color0 + smaa-edges + + + + smaa-blending-weight-calculation + Effects/HDR/smaa-blending-weight-calculation + color + 0.0 0.0 0.0 0.0 + + 0 + smaa-edges + + + color0 + smaa-blend + + + + smaa-neighborhood-blending + Effects/HDR/smaa-neighborhood-blending + + 0 + final + + + 1 + smaa-blend + + + debug-albedo diff --git a/Compositor/HDR/smaa-pass.xml b/Compositor/HDR/smaa-pass.xml new file mode 100644 index 000000000..1193d8d17 --- /dev/null +++ b/Compositor/HDR/smaa-pass.xml @@ -0,0 +1,11 @@ + + + + quad + + + /sim/rendering/hdr/antialiasing-technique + 2 + + + diff --git a/Effects/HDR/display.eff b/Effects/HDR/fxaa.eff similarity index 57% rename from Effects/HDR/display.eff rename to Effects/HDR/fxaa.eff index 551650ec6..60f5711c0 100644 --- a/Effects/HDR/display.eff +++ b/Effects/HDR/fxaa.eff @@ -1,14 +1,14 @@ - Effects/HDR/display + Effects/HDR/fxaa - Shaders/HDR/display.vert - Shaders/HDR/display.frag + Shaders/HDR/fxaa.vert + Shaders/HDR/fxaa.frag - tex + color_tex sampler-2d 0 diff --git a/Effects/HDR/smaa-blending-weight-calculation.eff b/Effects/HDR/smaa-blending-weight-calculation.eff new file mode 100644 index 000000000..60d66c702 --- /dev/null +++ b/Effects/HDR/smaa-blending-weight-calculation.eff @@ -0,0 +1,67 @@ + + + Effects/HDR/smaa-blending-weight-calculation + + + Textures/SMAA/area_tex.dds + 2d + linear-mipmap-linear + linear + clamp + clamp + normalized + + + Textures/SMAA/search_tex.dds + 2d + linear-mipmap-linear + linear + clamp + clamp + normalized + + + + + + 1 + texture[1]/image + texture[1]/type + texture[1]/filter + texture[1]/mag-filter + texture[1]/wrap-s + texture[1]/wrap-t + texture[1]/internal-format + + + 2 + texture[2]/image + texture[2]/type + texture[2]/filter + texture[2]/mag-filter + texture[2]/wrap-s + texture[2]/wrap-t + texture[2]/internal-format + + + Shaders/HDR/smaa-blending-weight-calculation.vert + Shaders/HDR/smaa-blending-weight-calculation.frag + + + edges_tex + sampler-2d + 0 + + + area_tex + sampler-2d + 1 + + + search_tex + sampler-2d + 2 + + + + diff --git a/Effects/HDR/smaa-edge-detection.eff b/Effects/HDR/smaa-edge-detection.eff new file mode 100644 index 000000000..4397b1b9f --- /dev/null +++ b/Effects/HDR/smaa-edge-detection.eff @@ -0,0 +1,17 @@ + + + Effects/HDR/smaa-edge-detection + + + + Shaders/HDR/smaa-edge-detection.vert + Shaders/HDR/smaa-edge-detection.frag + + + color_tex + sampler-2d + 0 + + + + diff --git a/Effects/HDR/smaa-neighborhood-blending.eff b/Effects/HDR/smaa-neighborhood-blending.eff new file mode 100644 index 000000000..5e48b5dd8 --- /dev/null +++ b/Effects/HDR/smaa-neighborhood-blending.eff @@ -0,0 +1,22 @@ + + + Effects/HDR/smaa-neighborhood-blending + + + + Shaders/HDR/smaa-neighborhood-blending.vert + Shaders/HDR/smaa-neighborhood-blending.frag + + + color_tex + sampler-2d + 0 + + + blend_tex + sampler-2d + 1 + + + + diff --git a/Shaders/HDR/display.frag b/Shaders/HDR/fxaa.frag similarity index 59% rename from Shaders/HDR/display.frag rename to Shaders/HDR/fxaa.frag index 189b034c1..cb169765a 100644 --- a/Shaders/HDR/display.frag +++ b/Shaders/HDR/fxaa.frag @@ -5,23 +5,21 @@ out vec4 fragColor; in vec2 texCoord; in vec4 posPos; -uniform vec2 fg_BufferSize; - -uniform sampler2D tex; +uniform sampler2D color_tex; const float FXAA_SPAN_MAX = 8.0; const float FXAA_REDUCE_MUL = 1.0/8.0; const float FXAA_REDUCE_MIN = 1.0/128.0; -vec3 fxaa() +void main() { - vec2 rcpFrame = 1.0 / textureSize(tex, 0); + vec2 rcpFrame = 1.0 / textureSize(color_tex, 0); - vec3 rgbNW = textureLod(tex, posPos.zw, 0.0).xyz; - vec3 rgbNE = textureLodOffset(tex, posPos.zw, 0.0, ivec2(1,0)).xyz; - vec3 rgbSW = textureLodOffset(tex, posPos.zw, 0.0, ivec2(0,1)).xyz; - vec3 rgbSE = textureLodOffset(tex, posPos.zw, 0.0, ivec2(1,1)).xyz; - vec3 rgbM = textureLod(tex, posPos.xy, 0.0).xyz; + vec3 rgbNW = textureLod(color_tex, posPos.zw, 0.0).xyz; + vec3 rgbNE = textureLodOffset(color_tex, posPos.zw, 0.0, ivec2(1,0)).xyz; + vec3 rgbSW = textureLodOffset(color_tex, posPos.zw, 0.0, ivec2(0,1)).xyz; + vec3 rgbSE = textureLodOffset(color_tex, posPos.zw, 0.0, ivec2(1,1)).xyz; + vec3 rgbM = textureLod(color_tex, posPos.xy, 0.0).xyz; const vec3 luma = vec3(0.299, 0.587, 0.114); float lumaNW = dot(rgbNW, luma); @@ -45,19 +43,15 @@ vec3 fxaa() dir * rcpDirMin)) * rcpFrame.xy; vec3 rgbA = 0.5 * ( - textureLod(tex, posPos.xy + dir * (1.0/3.0 - 0.5), 0.0).xyz + - textureLod(tex, posPos.xy + dir * (2.0/3.0 - 0.5), 0.0).xyz); + textureLod(color_tex, posPos.xy + dir * (1.0/3.0 - 0.5), 0.0).xyz + + textureLod(color_tex, posPos.xy + dir * (2.0/3.0 - 0.5), 0.0).xyz); vec3 rgbB = rgbA * 0.5 + 0.25 * ( - textureLod(tex, posPos.xy + dir * (0.0/3.0 - 0.5), 0.0).xyz + - textureLod(tex, posPos.xy + dir * (3.0/3.0 - 0.5), 0.0).xyz); + textureLod(color_tex, posPos.xy + dir * (0.0/3.0 - 0.5), 0.0).xyz + + textureLod(color_tex, posPos.xy + dir * (3.0/3.0 - 0.5), 0.0).xyz); float lumaB = dot(rgbB, luma); if((lumaB < lumaMin) || (lumaB > lumaMax)) - return rgbA; - return rgbB; -} - -void main() -{ - fragColor = vec4(fxaa(), 1.0); + fragColor = vec4(rgbA, 1.0); + else + fragColor = vec4(rgbB, 1.0); } diff --git a/Shaders/HDR/display.vert b/Shaders/HDR/fxaa.vert similarity index 84% rename from Shaders/HDR/display.vert rename to Shaders/HDR/fxaa.vert index 53aab4f63..8fa6357b8 100644 --- a/Shaders/HDR/display.vert +++ b/Shaders/HDR/fxaa.vert @@ -8,7 +8,7 @@ out vec4 posPos; uniform mat4 osg_ModelViewProjectionMatrix; -uniform sampler2D tex; +uniform sampler2D color_tex; const float FXAA_SUBPIX_SHIFT = 1.0/4.0; @@ -16,7 +16,7 @@ void main() { gl_Position = osg_ModelViewProjectionMatrix * pos; texCoord = multiTexCoord0.st; - vec2 rcpFrame = 1.0 / textureSize(tex, 0); + vec2 rcpFrame = 1.0 / textureSize(color_tex, 0); posPos.xy = multiTexCoord0.xy; posPos.zw = multiTexCoord0.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT)); } diff --git a/Shaders/HDR/smaa-blending-weight-calculation.frag b/Shaders/HDR/smaa-blending-weight-calculation.frag new file mode 100644 index 000000000..4a9ab020d --- /dev/null +++ b/Shaders/HDR/smaa-blending-weight-calculation.frag @@ -0,0 +1,491 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define SMAA_THRESHOLD 0.1 +#define SMAA_MAX_SEARCH_STEPS_DIAG 8 +#define SMAA_CORNER_ROUNDING 25 + +#define SMAA_AREATEX_MAX_DISTANCE 16 +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) +#define SMAA_SEARCHTEX_SIZE vec2(66.0, 33.0) +#define SMAA_SEARCHTEX_PACKED_SIZE vec2(64.0, 16.0) +#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0) + +#define SMAA_AREATEX_SELECT(sample) sample.rg +#define SMAA_SEARCHTEX_SELECT(sample) sample.r + +out vec4 fragColor; + +in vec2 texCoord; +in vec2 pixCoord; +in vec4 vOffset[3]; + +uniform sampler2D edges_tex; +uniform sampler2D area_tex; +uniform sampler2D search_tex; + +uniform vec4 fg_Viewport; + +#define SMAA_RT_METRICS vec4(1.0 / fg_Viewport.z, 1.0 / fg_Viewport.w, fg_Viewport.z, fg_Viewport.w) +#define mad(a, b, c) (a * b + c) +#define saturate(a) clamp(a, 0.0, 1.0) +#define round(v) floor(v + 0.5) +#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) + +/** + * Conditional move: + */ +void SMAAMovc(bvec2 cond, inout vec2 variable, vec2 value) { + if (cond.x) variable.x = value.x; + if (cond.y) variable.y = value.y; +} + +void SMAAMovc(bvec4 cond, inout vec4 variable, vec4 value) { + SMAAMovc(cond.xy, variable.xy, value.xy); + SMAAMovc(cond.zw, variable.zw, value.zw); +} + +//----------------------------------------------------------------------------- +// Diagonal Search Functions + +/** + * Allows to decode two binary values from a bilinear-filtered access. + */ +vec2 SMAADecodeDiagBilinearAccess(vec2 e) { + // Bilinear access for fetching 'e' have a 0.25 offset, and we are + // interested in the R and G edges: + // + // +---G---+-------+ + // | x o R x | + // +-------+-------+ + // + // Then, if one of these edge is enabled: + // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 + // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 + // + // 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); +} + +vec4 SMAADecodeDiagBilinearAccess(vec4 e) { + e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75); + return round(e); +} + +/** + * These functions allows to perform diagonal pattern searches. + */ +vec2 SMAASearchDiag1(sampler2D edgesTex, vec2 texcoord, vec2 dir, out vec2 e) { + vec4 coord = vec4(texcoord, -1.0, 1.0); + vec3 t = vec3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz); + e = textureLod(edgesTex, coord.xy, 0.0).rg; + coord.w = dot(e, vec2(0.5, 0.5)); + } + return coord.zw; +} + +vec2 SMAASearchDiag2(sampler2D edgesTex, vec2 texcoord, vec2 dir, out vec2 e) { + vec4 coord = vec4(texcoord, -1.0, 1.0); + coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization + vec3 t = vec3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz); + + // @SearchDiag2Optimization + // Fetch both edges at once using bilinear filtering: + e = textureLod(edgesTex, coord.xy, 0.0).rg; + e = SMAADecodeDiagBilinearAccess(e); + + // Non-optimized version: + // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; + // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r; + + coord.w = dot(e, vec2(0.5, 0.5)); + } + return coord.zw; +} + +/** + * Similar to SMAAArea, this calculates the area corresponding to a certain + * diagonal distance and crossing edges 'e'. + */ +vec2 SMAAAreaDiag(sampler2D areaTex, vec2 dist, vec2 e, float offset) { + vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, 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); + + // Diagonal areas are on the second half of the texture: + texcoord.x += 0.5; + + // Move to proper place, according to the subpixel offset: + texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; + + // Do it! + return SMAA_AREATEX_SELECT(textureLod(areaTex, texcoord, 0.0)); +} + +/** + * This searches for diagonal patterns and returns the corresponding weights. + */ +vec2 SMAACalculateDiagWeights(sampler2D edgesTex, sampler2D areaTex, vec2 texcoord, vec2 e, vec4 subsampleIndices) { + vec2 weights = vec2(0.0, 0.0); + + // Search for the line ends: + vec4 d; + vec2 end; + if (e.r > 0.0) { + d.xz = SMAASearchDiag1(edgesTex, texcoord, vec2(-1.0, 1.0), end); + d.x += float(end.y > 0.9); + } else + d.xz = vec2(0.0, 0.0); + d.yw = SMAASearchDiag1(edgesTex, texcoord, vec2(1.0, -1.0), end); + + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + vec4 coords = mad(vec4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + vec4 c; + c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).rg; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).rg; + c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw); + + // Non-optimized version: + // vec4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + // vec4 c; + // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).g; + // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2( 0, 0)).r; + // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).g; + // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, -1)).r; + + // Merge crossing edges at each side into a single value: + vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(areaTex, d.xy, cc, subsampleIndices.z); + } + + // Search for the line ends: + d.xz = SMAASearchDiag2(edgesTex, texcoord, vec2(-1.0, -1.0), end); + if (SMAASampleLevelZeroOffset(edgesTex, texcoord, ivec2(1, 0)).r > 0.0) { + d.yw = SMAASearchDiag2(edgesTex, texcoord, vec2(1.0, 1.0), end); + d.y += float(end.y > 0.9); + } else + d.yw = vec2(0.0, 0.0); + + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + vec4 coords = mad(vec4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + vec4 c; + c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).g; + c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2( 0, -1)).r; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).gr; + vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(areaTex, d.xy, cc, subsampleIndices.w).gr; + } + + return weights; +} + +//----------------------------------------------------------------------------- +// Horizontal/Vertical Search Functions + +/** + * This allows to determine how much length should we add in the last step + * of the searches. It takes the bilinearly interpolated edge (see + * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and + * crossing edges are active. + */ +float SMAASearchLength(sampler2D searchTex, vec2 e, float offset) { + // The texture is flipped vertically, with left and right cases taking half + // of the space horizontally: + vec2 scale = SMAA_SEARCHTEX_SIZE * vec2(0.5, -1.0); + vec2 bias = SMAA_SEARCHTEX_SIZE * vec2(offset, 1.0); + + // Scale and bias to access texel centers: + scale += vec2(-1.0, 1.0); + bias += vec2( 0.5, -0.5); + + // Convert from pixel coordinates to texcoords: + // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) + scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + + // Lookup the search texture: + return SMAA_SEARCHTEX_SELECT(textureLod(searchTex, mad(scale, e, bias), 0.0)); +} + +/** + * Horizontal/vertical search functions for the 2nd pass. + */ +float SMAASearchXLeft(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + /** + * @PSEUDO_GATHER4 + * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to + * sample between edge, thus fetching four edges in a row. + * Sampling with different offsets in each direction allows to disambiguate + * which edges are active from the four fetched ones. + */ + vec2 e = vec2(0.0, 1.0); + while (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 = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord = mad(-vec2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + + float offset = mad(-(255.0 / 127.0), SMAASearchLength(searchTex, e, 0.0), 3.25); + return mad(SMAA_RT_METRICS.x, offset, texcoord.x); + + // Non-optimized version: + // We correct the previous (-0.25, -0.125) offset we applied: + // texcoord.x += 0.25 * SMAA_RT_METRICS.x; + + // The searches are bias by 1, so adjust the coords accordingly: + // texcoord.x += SMAA_RT_METRICS.x; + + // Disambiguate the length added by the last step: + // texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step + // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); + // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchXRight(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(0.0, 1.0); + while (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 = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord = mad(vec2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(searchTex, e, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchYUp(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(1.0, 0.0); + while (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 = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord = mad(-vec2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(searchTex, e.gr, 0.0), 3.25); + return mad(SMAA_RT_METRICS.y, offset, texcoord.y); +} + +float SMAASearchYDown(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(1.0, 0.0); + while (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 = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord = mad(vec2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(searchTex, e.gr, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.y, offset, texcoord.y); +} + +/** + * Ok, we have the distance and both crossing edges. So, what are the areas + * at each side of current edge? + */ +vec2 SMAAArea(sampler2D area_tex, vec2 dist, float e1, float e2, float offset) { + // Rounding prevents precision errors of bilinear filtering: + vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * vec2(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); + + // Move to proper place, according to the subpixel offset: + texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); + + // Do it! + return SMAA_AREATEX_SELECT(textureLod(area_tex, texcoord, 0.0)); +} + +//----------------------------------------------------------------------------- +// Corner Detection Functions + +void SMAADetectHorizontalCornerPattern(sampler2D edgesTex, inout vec2 weights, vec4 texcoord, vec2 d) { +#if !defined(SMAA_DISABLE_CORNER_DETECTION) + vec2 leftRight = step(d.xy, d.yx); + vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line. + + vec2 factor = vec2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(0, 1)).r; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(1, 1)).r; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(0, -2)).r; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(1, -2)).r; + + weights *= saturate(factor); +#endif +} + +void SMAADetectVerticalCornerPattern(sampler2D edgesTex, inout vec2 weights, vec4 texcoord, vec2 d) { +#if !defined(SMAA_DISABLE_CORNER_DETECTION) + vec2 leftRight = step(d.xy, d.yx); + vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; + + vec2 factor = vec2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2( 1, 0)).g; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2( 1, 1)).g; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(-2, 0)).g; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(-2, 1)).g; + + weights *= saturate(factor); +#endif +} + +//----------------------------------------------------------------------------- +// Blending Weight Calculation Pixel Shader (Second Pass) + +void main() +{ + vec4 subsampleIndices = vec4(0.0); // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. + + vec4 weights = vec4(0.0, 0.0, 0.0, 0.0); + + vec2 e = texture(edges_tex, texCoord).rg; + + if (e.g > 0.0) { // Edge at north +#if !defined(SMAA_DISABLE_DIAG_DETECTION) + // Diagonals have both north and west edges, so searching for them in + // one of the boundaries is enough. + weights.rg = SMAACalculateDiagWeights(edges_tex, area_tex, texCoord, e, subsampleIndices); + + // We give priority to diagonals, so if we find a diagonal we skip + // horizontal/vertical processing. + if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 +#endif + vec2 d; + + // Find the distance to the left: + vec3 coords; + coords.x = SMAASearchXLeft(edges_tex, search_tex, vOffset[0].xy, vOffset[2].x); + coords.y = vOffset[1].y; // vOffset[1].y = texCoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) + d.x = coords.x; + + // Now fetch the left crossing edges, two at a time using bilinear + // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to + // discern what value each edge has: + float e1 = textureLod(edges_tex, coords.xy, 0.0).r; + + // Find the distance to the right: + coords.z = SMAASearchXRight(edges_tex, search_tex, vOffset[0].zw, vOffset[2].y); + d.y = coords.z; + + // 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))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + vec2 sqrt_d = sqrt(d); + + // Fetch the right crossing edges: + float e2 = SMAASampleLevelZeroOffset(edges_tex, coords.zy, ivec2(1, 0)).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + weights.rg = SMAAArea(area_tex, sqrt_d, e1, e2, subsampleIndices.y); + + // Fix corners: + coords.y = texCoord.y; + SMAADetectHorizontalCornerPattern(edges_tex, weights.rg, coords.xyzy, d); + +#if !defined(SMAA_DISABLE_DIAG_DETECTION) + } else + e.r = 0.0; // Skip vertical processing. +#endif + } + + if (e.r > 0.0) { // Edge at west + vec2 d; + + // Find the distance to the top: + vec3 coords; + coords.y = SMAASearchYUp(edges_tex, search_tex, vOffset[1].xy, vOffset[2].z); + coords.x = vOffset[0].x; // vOffset[1].x = texCoord.x - 0.25 * SMAA_RT_METRICS.x; + d.x = coords.y; + + // Fetch the top crossing edges: + float e1 = textureLod(edges_tex, coords.xy, 0.0).g; + + // Find the distance to the bottom: + coords.z = SMAASearchYDown(edges_tex, search_tex, vOffset[1].zw, vOffset[2].w); + d.y = coords.z; + + // We want the distances to be in pixel units: + d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixCoord.yy))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + vec2 sqrt_d = sqrt(d); + + // Fetch the bottom crossing edges: + float e2 = SMAASampleLevelZeroOffset(edges_tex, coords.xz, ivec2(0, 1)).g; + + // Get the area for this direction: + weights.ba = SMAAArea(area_tex, sqrt_d, e1, e2, subsampleIndices.x); + + // Fix corners: + coords.x = texCoord.x; + SMAADetectVerticalCornerPattern(edges_tex, weights.ba, coords.xyxz, d); + } + + fragColor = weights; +} diff --git a/Shaders/HDR/smaa-blending-weight-calculation.vert b/Shaders/HDR/smaa-blending-weight-calculation.vert new file mode 100644 index 000000000..5c098859a --- /dev/null +++ b/Shaders/HDR/smaa-blending-weight-calculation.vert @@ -0,0 +1,70 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define SMAA_MAX_SEARCH_STEPS 16 + +#define mad(a, b, c) (a * b + c) + +layout(location = 0) in vec4 pos; +layout(location = 3) in vec4 multiTexCoord0; + +out vec2 texCoord; +out vec2 pixCoord; +out vec4 vOffset[3]; + +uniform mat4 osg_ModelViewProjectionMatrix; + +uniform vec4 fg_Viewport; + +#define SMAA_RT_METRICS vec4(1.0 / fg_Viewport.z, 1.0 / fg_Viewport.w, fg_Viewport.z, fg_Viewport.w) + +void main() +{ + gl_Position = osg_ModelViewProjectionMatrix * pos; + texCoord = multiTexCoord0.st; + + pixCoord = texCoord * SMAA_RT_METRICS.zw; + + // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): + vOffset[0] = mad(SMAA_RT_METRICS.xyxy, vec4(-0.25, -0.125, 1.25, -0.125), texCoord.xyxy); + vOffset[1] = mad(SMAA_RT_METRICS.xyxy, vec4(-0.125,-0.25, -0.125, 1.25 ), texCoord.xyxy); + + // And these for the searches, they indicate the ends of the loops: + vOffset[2] = mad(SMAA_RT_METRICS.xxyy, + vec4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS), + vec4(vOffset[0].xz, vOffset[1].yw)); +} diff --git a/Shaders/HDR/smaa-edge-detection.frag b/Shaders/HDR/smaa-edge-detection.frag new file mode 100644 index 000000000..ddbfa2465 --- /dev/null +++ b/Shaders/HDR/smaa-edge-detection.frag @@ -0,0 +1,98 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define SMAA_THRESHOLD 0.1 +#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 + +out vec4 fragColor; + +in vec2 texCoord; +in vec4 vOffset[3]; + +uniform sampler2D color_tex; + +//----------------------------------------------------------------------------- +// Edge Detection Pixel Shaders (First Pass) + +/** + * Luma Edge Detection + * + * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +void main() +{ + vec2 threshold = vec2(SMAA_THRESHOLD); + + // Calculate lumas: + vec3 weights = vec3(0.2126, 0.7152, 0.0722); + float L = dot(texture(color_tex, texCoord).rgb, weights); + + float Lleft = dot(texture(color_tex, vOffset[0].xy).rgb, weights); + float Ltop = dot(texture(color_tex, vOffset[0].zw).rgb, weights); + + // We do the usual threshold: + vec4 delta; + delta.xy = abs(L - vec2(Lleft, Ltop)); + vec2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, vec2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float Lright = dot(texture(color_tex, vOffset[1].xy).rgb, weights); + float Lbottom = dot(texture(color_tex, vOffset[1].zw).rgb, weights); + delta.zw = abs(L - vec2(Lright, Lbottom)); + + // Calculate the maximum delta in the direct neighborhood: + vec2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float Lleftleft = dot(texture(color_tex, vOffset[2].xy).rgb, weights); + float Ltoptop = dot(texture(color_tex, vOffset[2].zw).rgb, weights); + delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop)); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + fragColor = vec4(edges, 0.0, 1.0); +} diff --git a/Shaders/HDR/smaa-edge-detection.vert b/Shaders/HDR/smaa-edge-detection.vert new file mode 100644 index 000000000..745511c95 --- /dev/null +++ b/Shaders/HDR/smaa-edge-detection.vert @@ -0,0 +1,59 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define mad(a, b, c) (a * b + c) + +layout(location = 0) in vec4 pos; +layout(location = 3) in vec4 multiTexCoord0; + +out vec2 texCoord; +out vec4 vOffset[3]; + +uniform mat4 osg_ModelViewProjectionMatrix; +uniform vec4 fg_Viewport; + +#define SMAA_RT_METRICS vec4(1.0 / fg_Viewport.z, 1.0 / fg_Viewport.w, fg_Viewport.z, fg_Viewport.w) + +void main() +{ + gl_Position = osg_ModelViewProjectionMatrix * pos; + texCoord = multiTexCoord0.st; + + vOffset[0] = mad(SMAA_RT_METRICS.xyxy, vec4(-1.0, 0.0, 0.0, -1.0), texCoord.xyxy); + vOffset[1] = mad(SMAA_RT_METRICS.xyxy, vec4( 1.0, 0.0, 0.0, 1.0), texCoord.xyxy); + vOffset[2] = mad(SMAA_RT_METRICS.xyxy, vec4(-2.0, 0.0, 0.0, -2.0), texCoord.xyxy); +} diff --git a/Shaders/HDR/smaa-neighborhood-blending.frag b/Shaders/HDR/smaa-neighborhood-blending.frag new file mode 100644 index 000000000..2ffc0eccc --- /dev/null +++ b/Shaders/HDR/smaa-neighborhood-blending.frag @@ -0,0 +1,101 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define mad(a, b, c) (a * b + c) + +out vec4 fragColor; + +in vec2 texCoord; +in vec4 vOffset; + +uniform sampler2D color_tex; +uniform sampler2D blend_tex; + +uniform vec4 fg_Viewport; + +#define SMAA_RT_METRICS vec4(1.0 / fg_Viewport.z, 1.0 / fg_Viewport.w, fg_Viewport.z, fg_Viewport.w) + +/** + * Conditional move: + */ +void SMAAMovc(bvec2 cond, inout vec2 variable, vec2 value) { + if (cond.x) variable.x = value.x; + if (cond.y) variable.y = value.y; +} + +void SMAAMovc(bvec4 cond, inout vec4 variable, vec4 value) { + SMAAMovc(cond.xy, variable.xy, value.xy); + SMAAMovc(cond.zw, variable.zw, value.zw); +} + +//----------------------------------------------------------------------------- +// Neighborhood Blending Pixel Shader (Third Pass) + +void main() +{ + vec4 color; + + // Fetch the blending weights for current pixel: + vec4 a; + a.x = texture(blend_tex, vOffset.xy).a; // Right + a.y = texture(blend_tex, vOffset.zw).g; // Top + a.wz = texture(blend_tex, texCoord).xz; // Bottom / Left + + // Is there any blending weight with a value greater than 0.0? + if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { + color = textureLod(color_tex, texCoord, 0.0); + } else { + bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) + + // Calculate the blending offsets: + vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w); + vec2 blendingWeight = a.yw; + SMAAMovc(bvec4(h, h, h, h), blendingOffset, vec4(a.x, 0.0, a.z, 0.0)); + SMAAMovc(bvec2(h, h), blendingWeight, a.xz); + blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0)); + + // Calculate the texture coordinates: + vec4 blendingCoord = mad(blendingOffset, vec4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texCoord.xyxy); + + // We exploit bilinear filtering to mix current pixel with the chosen + // neighbor: + color = blendingWeight.x * textureLod(color_tex, blendingCoord.xy, 0.0); + color += blendingWeight.y * textureLod(color_tex, blendingCoord.zw, 0.0); + } + + fragColor = color; +} diff --git a/Shaders/HDR/smaa-neighborhood-blending.vert b/Shaders/HDR/smaa-neighborhood-blending.vert new file mode 100644 index 000000000..75b334023 --- /dev/null +++ b/Shaders/HDR/smaa-neighborhood-blending.vert @@ -0,0 +1,57 @@ +/** + * Adaptation of SMAA (Enhanced Subpixel Morphological Antialiasing) + * for FlightGear. + * See http://www.iryoku.com/smaa/ for details. + * Licensed under the MIT license, see below. + */ + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#version 330 core + +#define mad(a, b, c) (a * b + c) + +layout(location = 0) in vec4 pos; +layout(location = 3) in vec4 multiTexCoord0; + +out vec2 texCoord; +out vec4 vOffset; + +uniform mat4 osg_ModelViewProjectionMatrix; +uniform vec4 fg_Viewport; + +#define SMAA_RT_METRICS vec4(1.0 / fg_Viewport.z, 1.0 / fg_Viewport.w, fg_Viewport.z, fg_Viewport.w) + +void main() +{ + gl_Position = osg_ModelViewProjectionMatrix * pos; + texCoord = multiTexCoord0.st; + + vOffset = mad(SMAA_RT_METRICS.xyxy, vec4(1.0, 0.0, 0.0, 1.0), texCoord.xyxy); +} diff --git a/Textures/SMAA/area_tex.dds b/Textures/SMAA/area_tex.dds new file mode 100644 index 000000000..7a3b1f8d1 Binary files /dev/null and b/Textures/SMAA/area_tex.dds differ diff --git a/Textures/SMAA/search_tex.dds b/Textures/SMAA/search_tex.dds new file mode 100644 index 000000000..f48ec89dd Binary files /dev/null and b/Textures/SMAA/search_tex.dds differ diff --git a/defaults.xml b/defaults.xml index dbc12c2f1..150d78aa7 100644 --- a/defaults.xml +++ b/defaults.xml @@ -390,6 +390,7 @@ Started September 2000 by David Megginson, david@megginson.com 0.0 1.0 6.0 + 2 true