Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: The E on May 17, 2011, 09:01:29 am

Title: FXAA in FSO
Post by: The E on May 17, 2011, 09:01:29 am
Okay, as some of you may be aware, it is not possible to have both antialiasing and post-processing active at the same time.
However, in recent months, techniques have surfaced that turn Antialiasing into a post-processing stage. While ATI has chosen to implement one such technique (called MLAA, Morphological AntiAliasing), NVidia has countered with something they call FXAA (Fast Approximate Antialiasing). NV's solution has the advantage of being a) a bit faster and b) being a hell of a lot easier to implement. So that is what I did. Thus, I proudly present FXAA for FSO. Test builds will be available soon, for now, here's the code patch to enable it as well as the necessary shaders.

One note: Even though this technique was developed by NVidia, it is usable on ATI/AMD cards as well.

EDIT: Code patch removed. Code has been committed to trunk.

These are the shaders you will need to use:

fxaa-v.sdr:
Code: [Select]
#extension GL_EXT_gpu_shader4 : enable

noperspective varying vec2 pos;
uniform float rt_w;
uniform float rt_h;
varying vec2 rcpFrame;

void main() {
gl_Position = gl_Vertex;

rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);

pos = gl_Vertex.xy*0.5 + 0.5;
}

fxaa-f.sdr:
Code: [Select]
#extension GL_EXT_gpu_shader4 : enable

// Copyright for FXAA Source
//
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
//
// TO  THE MAXIMUM  EXTENT PERMITTED  BY APPLICABLE  LAW, THIS SOFTWARE  IS PROVIDED
// *AS IS*  AND NVIDIA AND  ITS SUPPLIERS DISCLAIM  ALL WARRANTIES,  EITHER  EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED  TO, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL  NVIDIA OR ITS SUPPLIERS
// BE  LIABLE  FOR  ANY  SPECIAL,  INCIDENTAL,  INDIRECT,  OR  CONSEQUENTIAL DAMAGES
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION,  DAMAGES FOR LOSS OF BUSINESS PROFITS,
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
// ARISING OUT OF THE  USE OF OR INABILITY  TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

#define FXAA_GLSL_120 1

/*============================================================================
                                    FXAA                                 
============================================================================*/
 
/*============================================================================
                                 API PORTING
============================================================================*/
#ifndef     FXAA_GLSL_120
    #define FXAA_GLSL_120 0
#endif
#ifndef     FXAA_GLSL_130
    #define FXAA_GLSL_130 0
#endif

#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_120
    // Requires "#version 120" or better
    #define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
    #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
    // Requires "#version 130" or better
    #define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/

#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
    #if FXAA_GLSL_120
        return texture2DGrad(tex, pos.xy, grad, grad);
    #endif
    #if FXAA_GLSL_130
        return textureGrad(tex, pos.xy, grad, grad);
    #endif
}

/*============================================================================
                                 SRGB KNOBS
------------------------------------------------------------------------------
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
                This will do the sRGB to linear transform,
                as ROP will expect linear color from this shader,
                and this shader works in non-linear color.
============================================================================*/
#define FXAA_SRGB_ROP 0

/*============================================================================
                                DEBUG KNOBS
------------------------------------------------------------------------------
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
 
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
                         yellow tint on sub-pixel aliasing filtered by FXAA.
FXAA_DEBUG_HORZVERT    - Blue for horizontal edges, gold for vertical edges.
FXAA_DEBUG_PAIR        - Blue/green for the 2 pixel pair choice.
FXAA_DEBUG_NEGPOS      - Red/blue for which side of center of span.
FXAA_DEBUG_OFFSET      - Red/blue for -/+ x, gold/skyblue for -/+ y.
============================================================================*/
#ifndef     FXAA_DEBUG_PASSTHROUGH
    #define FXAA_DEBUG_PASSTHROUGH 0
#endif   
#ifndef     FXAA_DEBUG_HORZVERT
    #define FXAA_DEBUG_HORZVERT    0
#endif   
#ifndef     FXAA_DEBUG_PAIR   
    #define FXAA_DEBUG_PAIR        0
#endif   
#ifndef     FXAA_DEBUG_NEGPOS
    #define FXAA_DEBUG_NEGPOS      0
#endif
#ifndef     FXAA_DEBUG_OFFSET
    #define FXAA_DEBUG_OFFSET      0
#endif   
/*--------------------------------------------------------------------------*/
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
    #define FXAA_DEBUG 1
#endif   
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
    #define FXAA_DEBUG 1
#endif
#ifndef FXAA_DEBUG
    #define FXAA_DEBUG 0
#endif
 
/*============================================================================
                              COMPILE-IN KNOBS
------------------------------------------------------------------------------
FXAA_PRESET - Choose compile-in knob preset 0-5.
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
                      to apply algorithm.
                      1.0/3.0  - too little
                      1.0/4.0  - good start
                      1.0/8.0  - applies to more edges
                      1.0/16.0 - overkill
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
                          Perf optimization.
                          1.0/32.0 - visible limit (smaller isn't visible)
                          1.0/16.0 - good compromise
                          1.0/12.0 - upper limit (seeing artifacts)
------------------------------------------------------------------------------
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
------------------------------------------------------------------------------
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
                           1 - no acceleration
                           2 - skip by 2 pixels
                           3 - skip by 3 pixels
                           4 - skip by 4 pixels
------------------------------------------------------------------------------
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
                        1.0/4.0 - seems to be the best quality wise
------------------------------------------------------------------------------
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
                     Not recomended, but used in preset 0.
------------------------------------------------------------------------------
FXAA_SUBPIX - Toggle subpix filtering.
              0 - turn off
              1 - turn on
              2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
------------------------------------------------------------------------------
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
                   1.0/2.0 - low removal
                   1.0/3.0 - medium removal
                   1.0/4.0 - default removal
                   1.0/8.0 - high removal
                   0.0 - complete removal
------------------------------------------------------------------------------
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
                  This is important for the transition of sub-pixel detail,
                  like fences and wires.
                  3.0/4.0 - default (medium amount of filtering)
                  7.0/8.0 - high amount of filtering
                  1.0 - no capping of sub-pixel aliasing removal
============================================================================*/

float FXAA_EDGE_THRESHOLD = (1.0/8.0);
float FXAA_EDGE_THRESHOLD_MIN = (1.0/24.0);
int   FXAA_SEARCH_STEPS = 16; 
int   FXAA_SEARCH_ACCELERATION = 1;
float FXAA_SEARCH_THRESHOLD = (1.0/4.0);
int   FXAA_SUBPIX = 1;
int   FXAA_SUBPIX_FASTER = 0;
float FXAA_SUBPIX_CAP = (3.0/4.0);
float FXAA_SUBPIX_TRIM = (1.0/4.0);
float FXAA_SUBPIX_TRIM_SCALE = (1.0/0.75);   

void FXAA_set_preset(int preset) {

if (preset > 6)
preset = 6;
/*--------------------------------------------------------------------------*/
if  (preset == 0) {
FXAA_EDGE_THRESHOLD      = (1.0/4.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/12.0);
FXAA_SEARCH_STEPS        = 2;
FXAA_SEARCH_ACCELERATION = 4;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 1;
FXAA_SUBPIX_CAP          = (2.0/3.0);
FXAA_SUBPIX_TRIM         = (1.0/4.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 1) {
FXAA_EDGE_THRESHOLD      = (1.0/8.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/16.0);
FXAA_SEARCH_STEPS        = 4;
FXAA_SEARCH_ACCELERATION = 3;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (3.0/4.0);
FXAA_SUBPIX_TRIM         = (1.0/4.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 2) {
FXAA_EDGE_THRESHOLD      = (1.0/8.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/24.0);
FXAA_SEARCH_STEPS        = 8;
FXAA_SEARCH_ACCELERATION = 2;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (3.0/4.0);
FXAA_SUBPIX_TRIM         = (1.0/4.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 3) {
FXAA_EDGE_THRESHOLD      = (1.0/8.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/24.0);
FXAA_SEARCH_STEPS        = 16;
FXAA_SEARCH_ACCELERATION = 1;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (3.0/4.0);
FXAA_SUBPIX_TRIM         = (1.0/4.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 4) {
FXAA_EDGE_THRESHOLD      = (1.0/8.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/24.0);
FXAA_SEARCH_STEPS        = 24;
FXAA_SEARCH_ACCELERATION = 1;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (3.0/4.0);
FXAA_SUBPIX_TRIM         = (1.0/4.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 5) {
FXAA_EDGE_THRESHOLD      = (1.0/8.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/24.0);
FXAA_SEARCH_STEPS        = 32;
FXAA_SEARCH_ACCELERATION = 1;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (7.0/8.0);
FXAA_SUBPIX_TRIM         = (1.0/8.0);
}
/*--------------------------------------------------------------------------*/
else if  (preset == 6) {
FXAA_EDGE_THRESHOLD      = (1.0/12.0);
FXAA_EDGE_THRESHOLD_MIN  = (1.0/24.0);
FXAA_SEARCH_STEPS        = 32;
FXAA_SEARCH_ACCELERATION = 1;
FXAA_SEARCH_THRESHOLD    = (1.0/4.0);
FXAA_SUBPIX              = 1;
FXAA_SUBPIX_FASTER       = 0;
FXAA_SUBPIX_CAP          = (1.0);
FXAA_SUBPIX_TRIM         = (0.0);
}
/*--------------------------------------------------------------------------*/
FXAA_SUBPIX_TRIM_SCALE = (1.0/(1.0 - FXAA_SUBPIX_TRIM));

}

/*============================================================================
                                   HELPERS
============================================================================*/
// Return the luma, the estimation of luminance from rgb inputs.
// This approximates luma using one FMA instruction,
// skipping normalization and tossing out blue.
// FxaaLuma() will range 0.0 to 2.963210702.
float FxaaLuma(float3 rgb) {
    return rgb.y * (0.587/0.299) + rgb.x; }
/*--------------------------------------------------------------------------*/
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
    return (FxaaToFloat3(-amountOfA) * b) +
        ((a * FxaaToFloat3(amountOfA)) + b); }
/*--------------------------------------------------------------------------*/
// Support any extra filtering before returning color.
float3 FxaaFilterReturn(float3 rgb) {
    #if FXAA_SRGB_ROP
        // Do sRGB encoded value to linear conversion.
        return FxaaSel3(
            rgb * FxaaToFloat3(1.0/12.92),
            FxaaPow3(
                rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
                FxaaToFloat3(2.4)),
            rgb > FxaaToFloat3(0.04045));
    #else
        return rgb;
    #endif
}
 
/*============================================================================
                                PIXEL SHADER
============================================================================*/
float3 FxaaPixelShader(
// Output of FxaaVertexShader interpolated across screen.
//  xy -> actual texture position {0.0 to 1.0}
float2 pos,
// Input texture.
FxaaTex tex,
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// {1.0/frameWidth, 1.0/frameHeight}
float2 rcpFrame) {
   
/*----------------------------------------------------------------------------
            EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
------------------------------------------------------------------------------
Majority of pixels of a typical image do not require filtering,
often pixels are grouped into blocks which could benefit from early exit
right at the beginning of the algorithm.
Given the following neighborhood,
 
      N   
    W M E
      S   
   
If the difference in local maximum and minimum luma (contrast "range")
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
then the shader early exits (no visible aliasing).
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
to avoid processing in really dark areas.   
----------------------------------------------------------------------------*/
    float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
    float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
    float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
    float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
    float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
    float lumaN = FxaaLuma(rgbN);
    float lumaW = FxaaLuma(rgbW);
    float lumaM = FxaaLuma(rgbM);
    float lumaE = FxaaLuma(rgbE);
    float lumaS = FxaaLuma(rgbS);
    float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
    float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
    float range = rangeMax - rangeMin;
    #if FXAA_DEBUG
        float lumaO = lumaM / (1.0 + (0.587/0.299));
    #endif       
    if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
        #if FXAA_DEBUG
            return FxaaFilterReturn(FxaaToFloat3(lumaO));
        #endif
        return FxaaFilterReturn(rgbM);

}

float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;

    if (FXAA_SUBPIX > 0) {
        if (FXAA_SUBPIX_FASTER != 0) {
            rgbL *= FxaaToFloat3(1.0/5.0);
}
    }     
   
/*----------------------------------------------------------------------------
                               COMPUTE LOWPASS
------------------------------------------------------------------------------
FXAA computes a local neighborhood lowpass value as follows,
 
  (N + W + E + S)/4
 
Then uses the ratio of the contrast range of the lowpass
and the range found in the early exit check,
as a sub-pixel aliasing detection filter.
When FXAA detects sub-pixel aliasing (such as single pixel dots),
it later blends in "blendL" amount
of a lowpass value (computed in the next section) to the final result.
----------------------------------------------------------------------------*/
   
float blendL = 0.0;

if (FXAA_SUBPIX > 0) {
        float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
        float rangeL = abs(lumaL - lumaM);
       
if (FXAA_SUBPIX == 1) {
blendL = max(0.0,
(rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
blendL = min(FXAA_SUBPIX_CAP, blendL);
}
if (FXAA_SUBPIX == 2) {
blendL = rangeL / range;
}
#if FXAA_DEBUG_PASSTHROUGH
if (FXAA_SUBPIX == 0) {
blendL = 0.0;
}
return FxaaFilterReturn(
FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
#endif   
}
   
/*----------------------------------------------------------------------------
                    CHOOSE VERTICAL OR HORIZONTAL SEARCH
------------------------------------------------------------------------------
FXAA uses the following local neighborhood,
 
    NW N NE
    W  M  E
    SW S SE
   
To compute an edge amount for both vertical and horizontal directions.
Note edge detect filters like Sobel fail on single pixel lines through M.
FXAA takes the weighted average magnitude of the high-pass values
for rows and columns as an indication of local edge amount.
 
A lowpass value for anti-sub-pixel-aliasing is computed as
    (N+W+E+S+M+NW+NE+SW+SE)/9.
This full box pattern has higher quality than other options.
 
Note following this block, both vertical and horizontal cases
flow in parallel (reusing the horizontal variables).
----------------------------------------------------------------------------*/
    float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
    float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
    float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
    float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
    if ((FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)) {
        rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
        rgbL *= FxaaToFloat3(1.0/9.0);
    }
    float lumaNW = FxaaLuma(rgbNW);
    float lumaNE = FxaaLuma(rgbNE);
    float lumaSW = FxaaLuma(rgbSW);
    float lumaSE = FxaaLuma(rgbSE);
    float edgeVert =
        abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
        abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
        abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
    float edgeHorz =
        abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
        abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
        abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
    bool horzSpan = edgeHorz >= edgeVert;
    #if FXAA_DEBUG_HORZVERT
        if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
        else         return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
    #endif
    float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
    if(!horzSpan) lumaN = lumaW;
    if(!horzSpan) lumaS = lumaE;
    float gradientN = abs(lumaN - lumaM);
    float gradientS = abs(lumaS - lumaM);
    lumaN = (lumaN + lumaM) * 0.5;
    lumaS = (lumaS + lumaM) * 0.5;
   
/*----------------------------------------------------------------------------
                CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
------------------------------------------------------------------------------
This chooses a pixel pair.
For "horzSpan == true" this will be a vertical pair,
 
    [N]     N
    [M] or [M]
     S     [S]
 
Note following this block, both {N,M} and {S,M} cases
flow in parallel (reusing the {N,M} variables).
 
This pair of image rows or columns is searched below
in the positive and negative direction
until edge status changes
(or the maximum number of search steps is reached).
----------------------------------------------------------------------------*/   
    bool pairN = gradientN >= gradientS;
    #if FXAA_DEBUG_PAIR
        if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
        else      return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
    #endif
    if(!pairN) lumaN = lumaS;
    if(!pairN) gradientN = gradientS;
    if(!pairN) lengthSign *= -1.0;
    float2 posN;
    posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
    posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
   
/*----------------------------------------------------------------------------
                         CHOOSE SEARCH LIMITING VALUES
------------------------------------------------------------------------------
Search limit (+/- gradientN) is a function of local gradient.
----------------------------------------------------------------------------*/
    gradientN *= FXAA_SEARCH_THRESHOLD;
   
/*----------------------------------------------------------------------------
    SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
------------------------------------------------------------------------------
This loop searches either in vertical or horizontal directions,
and in both the negative and positive direction in parallel.
This loop fusion is faster than searching separately.
 
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
via anisotropic filtering with specified texture gradients.
----------------------------------------------------------------------------*/
    float2 posP = posN;
    float2 offNP = horzSpan ?
        FxaaFloat2(rcpFrame.x, 0.0) :
        FxaaFloat2(0.0f, rcpFrame.y);
    float lumaEndN = lumaN;
    float lumaEndP = lumaN;
    bool doneN = false;
    bool doneP = false;
    if (FXAA_SEARCH_ACCELERATION == 1) {
        posN += offNP * FxaaFloat2(-1.0, -1.0);
        posP += offNP * FxaaFloat2( 1.0,  1.0);
    }
    if (FXAA_SEARCH_ACCELERATION == 2 ) {
        posN += offNP * FxaaFloat2(-1.5, -1.5);
        posP += offNP * FxaaFloat2( 1.5,  1.5);
        offNP *= FxaaFloat2(2.0, 2.0);
    }
    if (FXAA_SEARCH_ACCELERATION == 3) {
        posN += offNP * FxaaFloat2(-2.0, -2.0);
        posP += offNP * FxaaFloat2( 2.0,  2.0);
        offNP *= FxaaFloat2(3.0, 3.0);
    }
    if (FXAA_SEARCH_ACCELERATION == 4) {
        posN += offNP * FxaaFloat2(-2.5, -2.5);
        posP += offNP * FxaaFloat2( 2.5,  2.5);
        offNP *= FxaaFloat2(4.0, 4.0);
    }
    for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
        if (FXAA_SEARCH_ACCELERATION == 1) {
            if(!doneN) lumaEndN =
                FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
            if(!doneP) lumaEndP =
                FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
        } else {
            if(!doneN) lumaEndN =
                FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
            if(!doneP) lumaEndP =
                FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
        }
        doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
        doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
        if(doneN && doneP) break;
        if(!doneN) posN -= offNP;
        if(!doneP) posP += offNP; }
   
/*----------------------------------------------------------------------------
               HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
------------------------------------------------------------------------------
FXAA uses the pixel's position in the span
in combination with the values (lumaEnd*) at the ends of the span,
to determine filtering.
 
This step computes which side of the span the pixel is on.
On negative side if dstN < dstP,
 
     posN        pos                      posP
      |-----------|------|------------------|
      |           |      |                  |
      |<--dstN--->|<---------dstP---------->|
                         |
                    span center
                   
----------------------------------------------------------------------------*/
    float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
    float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
    bool directionN = dstN < dstP;
    #if FXAA_DEBUG_NEGPOS
        if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
        else           return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
    #endif
    lumaEndN = directionN ? lumaEndN : lumaEndP;
   
/*----------------------------------------------------------------------------
         CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
------------------------------------------------------------------------------
If both the pair luma at the end of the span (lumaEndN)
and middle pixel luma (lumaM)
are on the same side of the middle pair average luma (lumaN),
then don't filter.
 
Cases,
 
(1.) "L",
 
               lumaM
                 |
                 V    XXXXXXXX <- other line averaged
         XXXXXXX[X]XXXXXXXXXXX <- source pixel line
        |      .      |
    --------------------------                   
       [ ]xxxxxx[x]xx[X]XXXXXX <- pair average
    --------------------------           
        ^      ^ ^    ^
        |      | |    |
        .      |<---->|<---------- no filter region
        .      | |    |
        . center |    |
        .        |  lumaEndN
        .        |    .
        .      lumaN  .
        .             .
        |<--- span -->|
       
                       
(2.) "^" and "-",
 
                               <- other line averaged
          XXXXX[X]XXX          <- source pixel line
         |     |     |
    --------------------------                   
        [ ]xxxx[x]xx[ ]        <- pair average
    --------------------------           
         |     |     |
         |<--->|<--->|<---------- filter both sides
 
 
(3.) "v" and inverse of "-",
 
    XXXXXX           XXXXXXXXX <- other line averaged
    XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
         |     |     |
    --------------------------                   
    XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
    --------------------------           
         |     |     |
         |<--->|<--->|<---------- don't filter both!
 
         
Note the "v" case for FXAA requires no filtering.
This is because the inverse of the "-" case is the "v".
Filtering "v" case turns open spans like this,
 
    XXXXXXXXX
   
Into this (which is not desired),
 
    x+.   .+x
    XXXXXXXXX
 
----------------------------------------------------------------------------*/
    if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
        lengthSign = 0.0;
 
/*----------------------------------------------------------------------------
                COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
------------------------------------------------------------------------------
FXAA filters using a bilinear texture fetch offset
from the middle pixel M towards the center of the pair (NM below).
Maximum filtering will be half way between pair.
Reminder, at this point in the code,
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
 
    +-------+
    |       |    0.5 offset
    |   N   |     |
    |       |     V
    +-------+....---
    |       |
    |   M...|....---
    |       |     ^
    +-------+     |
    .       .    0.0 offset
    .   S   .
    .       .
    .........
 
Position on span is used to compute sub-pixel filter offset using simple ramp,
 
             posN           posP
              |\             |<------- 0.5 pixel offset into pair pixel
              | \            |
              |  \           |
    ---.......|...\..........|<------- 0.25 pixel offset into pair pixel
     ^        |   ^\         |
     |        |   | \        |
     V        |   |  \       |
    ---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
     ^        .   |   ^      .
     |        .  pos  |      .
     |        .   .   |      .
     |        .   . center   .
     |        .   .          .
     |        |<->|<---------.-------- dstN
     |        .   .          .   
     |        .   |<-------->|<------- dstP   
     |        .             .
     |        |<------------>|<------- spanLength   
     |
    subPixelOffset
   
----------------------------------------------------------------------------*/
    float spanLength = (dstP + dstN);
    dstN = directionN ? dstN : dstP;
    float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
    #if FXAA_DEBUG_OFFSET
        float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
        float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
        if(ox < 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(1.0, 0.0, 0.0), -ox));
        if(ox > 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(0.0, 0.0, 1.0),  ox));
        if(oy < 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(1.0, 0.6, 0.2), -oy));
        if(oy > 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(0.2, 0.6, 1.0),  oy));
        return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
    #endif
    float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
        pos.x + (horzSpan ? 0.0 : subPixelOffset),
        pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
    if (FXAA_SUBPIX == 0) {
        return FxaaFilterReturn(rgbF);
    } else {   
        return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
    }
}

uniform sampler2D tex0;
uniform int fxaa_preset;
varying vec2 rcpFrame;
noperspective varying vec2 pos;

void main() {
FXAA_set_preset(fxaa_preset);
gl_FragColor.xyz = FxaaPixelShader(pos, tex0, rcpFrame);
}



As evidence of this working, I present the following screenies:

FXAA off:
(http://blueplanet.fsmods.net/E/pics/FXAAoff.png)

FXAA on:
(http://blueplanet.fsmods.net/E/pics/FXAAon.png)


EDIT: To enable FXAA, you need to: 1. Activate post-processing, 2. Enable the "-fxaa" commandline setting (Can be found in the Launchers "Graphics" feature tab).

EDIT AGAIN:
Further refinements have been made. You can now use the "-fxaa_preset" commandline argument to specify how strong FXAA will be. Currently, valid arguments go from 0 (fastest, but least amount of smoothing) to 6 (slowest, but a lot of smoothing), with 3 being the default value.
In addition, you can now go to the F3 lab and go through presets by pressing the number keys.

EDIT0RED:
Since the code (and default shaders) have been added to FSO trunk, it is recommended to use recent (read: post revision 7201) nightly builds to test this. The custom test builds have been removed.
Title: Re: FXAA in FSO
Post by: CommanderDJ on May 17, 2011, 09:03:58 am
All hail the glorious code masters. Will definitely be keeping a close eye on this.
Title: Re: FXAA in FSO
Post by: General Battuta on May 17, 2011, 09:04:58 am
It's subtle but it's definitely working.
Title: Re: FXAA in FSO
Post by: The E on May 17, 2011, 09:14:02 am
Builds added to post.
Title: Re: FXAA in FSO
Post by: Zacam on May 17, 2011, 09:30:00 am

Plays well with Driver Side AA. When I un-limit the FPS in FSO and set driver side vsync, I get solid 60fps either on or off.

I set Driver side AA. Then played with the "Hide Post Processing" check-box in the lab.
With FXAA on, the results are just a little behind what one get's when the post processing is turned off, but it has definitely overall improved the existing driver side AA and is noticeable in the same fashion that 4x is noticeable from 8x. And with objects in motion, that there is -any- AA at all in conjunction with the post-processing makes this an invaluable WIN any way you slice it.
Title: Re: FXAA in FSO
Post by: Sushi on May 17, 2011, 10:36:54 am
Confirmed awesome.  :yes:
Title: Re: FXAA in FSO
Post by: Kolgena on May 17, 2011, 12:05:33 pm
Screenshots show that the performance hit is at least 50%. That's kind of intimidating XD

Still, it's excellent that AA is finally working. I'm very happy about this development.
Title: Re: FXAA in FSO
Post by: The E on May 17, 2011, 12:10:40 pm
The performance hit you see there is not at all representative. Yes, there is one. But ingame, it is almost unnoticeable. Reason being that the FXAA algorithm has a constant run-time, much like any of the other post effects.
Title: Re: FXAA in FSO
Post by: Herra Tohtori on May 17, 2011, 12:13:18 pm
Screenshots show that the performance hit is at least 50%. That's kind of intimidating XD


VSync always drops the frame rate to a factor of display's native frame rate. If display can do 120 Hz, then when VSync is enabled but the computer is only capable of, let's say 100 FPS, the VSync throttles it down to 60 FPS - each frame is then shown for the duration of two frames in the display's native frequency.

This prevents switching of frames between the times when they can be changed - which can cause screen tearing, as the image is being drawn on the screen and suddenly changes into another image.

This doesn't mean the performance drop is 50%...
Title: Re: FXAA in FSO
Post by: Kolgena on May 17, 2011, 12:41:37 pm
The_E never mentioned that his game was vsynced, so I assumed it wasn't. Also, 64 fps would be weird to cap at, instead of 60. I just know that the in-game FPS cap in ship lab is 120 fps. I have vysnc off and it never lets me get higher than 120, which is fine because my screen is 60hz.

By constant runtime, do you mean that the performance load stays relatively constant, therefore fps jitter is minimized?
Title: Re: FXAA in FSO
Post by: The E on May 17, 2011, 12:45:53 pm
Yes. The algorithm's runtime depends entirely on your resolution and GPU speed, no other factors play into it.
Title: Re: FXAA in FSO
Post by: Rodo on May 17, 2011, 12:51:44 pm
Cool stuff, it looks quite better in that pic... will be testing it :yes:


When I un-limit the FPS in FSO


say wat?
Title: Re: FXAA in FSO
Post by: The E on May 17, 2011, 04:30:13 pm
Ooookaaaay.

So.

The shaders posted above? Forget them. They were based on FXAA v2, aka the fast-and-dirty console version. For the really powerful v1 shaders, which are made for members of the PC GAMING MASTER RACE, look here:

EDIT: FILES REMOVED. Look at the first post in the thread for the current version.
Title: Re: FXAA in FSO
Post by: DaBrain on May 17, 2011, 05:07:11 pm
This rocks!

Now Post Processing has now downsides anymore. I love it!  :yes:


I'll try to run a complete test on this tomorrow.
Title: Re: FXAA in FSO
Post by: Sushi on May 17, 2011, 06:01:29 pm
Ooookaaaay.

So.

The shaders posted above? Forget them. They were based on FXAA v2, aka the fast-and-dirty console version. For the really powerful v1 shaders, which are made for members of the PC GAMING MASTER RACE, look here:


So are these slower, but higher quality? Or faster AND higher quality?

Or just more pretentious? I'm cool with that too.  :D
Title: Re: FXAA in FSO
Post by: The E on May 17, 2011, 06:06:13 pm
They might be slower, but if I can't tell the difference on my machine, I'm not counting it. The main advantage these thingies have is that they are more configurable, which means that in the future, you'll be able to adjust the FXAA strength and other parameters on-the-fly.
Title: Re: FXAA in FSO
Post by: Kolgena on May 17, 2011, 08:37:11 pm
Just curious: the result looks a heck of a lot like Crysis 2's AA filter. Is it the same thing?

(Also, I'd appreciate anything that could be done for performance. The current AA already drops my framerates by 10-20%, which is quite a bit when I can get as low as 22 fps without the FXAA)

ED: For curiosity sake, I did a bench to compare the hit of the ver1 FXAA shaders.

With FXAA: 30 fps
Same scene without FXAA: 77 fps

Ver2 FXAA shaders:

With FXAA: 58 fps
Same scene without FXAA: 76 fps

Core2Duo 2.4 GHz, Mobility 3650 HD @ 593/791. The hardware is ****tier than that found in a console, so I think I'll stick with my ver2 shaders, if at all :P
Title: Re: FXAA in FSO
Post by: rscaper1070 on May 17, 2011, 11:27:36 pm
I thought these were just for NVidia cards. Does this work with ATI as well?
Title: Re: FXAA in FSO
Post by: General Battuta on May 17, 2011, 11:29:36 pm
I thought these were just for NVidia cards. Does this work with ATI as well?

Yes, it does.

On an HD 5850, works beautifully for me. Slight degradation in texture definition but a definite antialiasing effect. More than worth it as far as I'm concerned. My FPS is capped at 60 and does not drop from 60 using FXAA.
Title: Re: FXAA in FSO
Post by: Zacam on May 18, 2011, 02:19:01 am
Code: [Select]
0(3) : warning C7022: unrecognized profile specifier "noperspective"
0(3) : error C0502: syntax error at token "noperspective"

ERROR! Unable to create vertex shader!
Error while compiling FXAA shaders. FXAA will be unavailable.
Removing 'noperspective' from both Fragment and Vertex resolves.

Setting "#define FXAA_GLSL_120 1" to being "#define FXAA_GLSL_130 1" and 'noperspective' removed produces the following:
Code: [Select]
Fragment shader compiled with warnings:
0(45) : warning C7532: global function textureGrad requires "#version 130" or later
0(184) : warning C7532: global function textureLodOffset requires "#version 130" or later
0(311) : warning C7532: global function textureLod requires "#version 130" or later
Shaders still compile so long as "#version 120" is not set.

Setting a "#version 130" with "#define FXAA_GLSL_130 1" and 'noperspective' removed produces the following:
Code: [Select]
Fragment shader compiled with warnings:
0(369) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(370) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(375) : warning C7533: global variable gl_FragColor is deprecated after version 120

Shader linked with warnings:
Fragment info
-------------
0(369) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(370) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(375) : warning C7533: global variable gl_FragColor is deprecated after version 120


Setting "#version 130" with "#define FXAA_GLSL_120 1" and 'noperspective' removed produces the following:
Code: [Select]
Fragment shader compiled with warnings:
0(311) : warning C7533: global function texture2DLod is deprecated after version 120
0(369) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(370) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(375) : warning C7533: global variable gl_FragColor is deprecated after version 120

Shader linked with warnings:
Fragment info
-------------
0(311) : warning C7533: global function texture2DLod is deprecated after version 120
0(369) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(370) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(375) : warning C7533: global variable gl_FragColor is deprecated after version 120


Setting "#version 130" with "#define FXAA_GLSL_120 1" and leaving 'noperspective' produces the following:
Code: [Select]
Vertex shader failed to compile:
0(4) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(4) : error C7560: OpenGL does not allow 'noperspective' with 'varying'
0(4) : error C7561: OpenGL requires 'in/out' with 'noperspective'
0(7) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(10) : warning C7533: global variable gl_Vertex is deprecated after version 120

ERROR! Unable to create vertex shader!
Error while compiling FXAA shaders. FXAA will be unavailable.

This concludes today's exercise
Title: Re: FXAA in FSO
Post by: The E on May 18, 2011, 02:50:12 am
Just curious: the result looks a heck of a lot like Crysis 2's AA filter. Is it the same thing?

(Also, I'd appreciate anything that could be done for performance. The current AA already drops my framerates by 10-20%, which is quite a bit when I can get as low as 22 fps without the FXAA)

ED: For curiosity sake, I did a bench to compare the hit of the ver1 FXAA shaders.

With FXAA: 30 fps
Same scene without FXAA: 77 fps

Ver2 FXAA shaders:

With FXAA: 58 fps
Same scene without FXAA: 76 fps

Core2Duo 2.4 GHz, Mobility 3650 HD @ 593/791. The hardware is ****tier than that found in a console, so I think I'll stick with my ver2 shaders, if at all :P

Have you done these tests in the ship lab? The problem with the lab is that framerate achieved there are not at all representative for ingame performance, and very sensitive to changes in the rendering infrastructure (like FXAA). I will still maintain that the performance loss under real-life situations is negligible.

Anyway, a few tests of my own show that FXAA adds somewhere ~2 Milliseconds to the render time per frame (On a Radeon Mobile 5470). This will have some effect on the global framerate, but an effect that actually decreases as FPS get lower.
Title: Re: FXAA in FSO
Post by: Zacam on May 18, 2011, 04:19:46 am

While these (and the attendant code) are still being moderately tweaked with, seems nVidia cards (despite this being nV generated) has a few issues, so here's a micro-update:

Code: (fxaa-v.sdr) [Select]
#extension GL_EXT_gpu_shader4 : enable
noperspective varying vec2 pos;
uniform float rt_w;
uniform float rt_h;
varying vec2 rcpFrame;

void main() {
gl_Position = gl_Vertex;

rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);

pos = gl_Vertex.xy*0.5 + 0.5;
}

Not much changed there, but note the "#extension" bit.
This was on in the Fragment Shader, but was not in the original Vertex shader, leading to errors and un-linking shaders re 'noperspective'.
This change resolves that.

Code: (fxaa-f.sdr) [Select]
#extension GL_EXT_gpu_shader4 : enable

// Copyright for FXAA Source
//
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
//
// TO  THE MAXIMUM  EXTENT PERMITTED  BY APPLICABLE  LAW, THIS SOFTWARE  IS PROVIDED
// *AS IS*  AND NVIDIA AND  ITS SUPPLIERS DISCLAIM  ALL WARRANTIES,  EITHER  EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED  TO, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL  NVIDIA OR ITS SUPPLIERS
// BE  LIABLE  FOR  ANY  SPECIAL,  INCIDENTAL,  INDIRECT,  OR  CONSEQUENTIAL DAMAGES
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION,  DAMAGES FOR LOSS OF BUSINESS PROFITS,
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
// ARISING OUT OF THE  USE OF OR INABILITY  TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

#define FXAA_GLSL_120 1

/*============================================================================
                                    FXAA                                 
============================================================================*/
 
/*============================================================================
                                 API PORTING
============================================================================*/
#ifndef     FXAA_GLSL_120
    #define FXAA_GLSL_120 0
#endif
#ifndef     FXAA_GLSL_130
    #define FXAA_GLSL_130 0
#endif

#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaBool3 bvec3
#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
#define FxaaPow3(x, y) pow(x, y)
#define FxaaSel3(f, t, b) mix((f), (t), (b))
#define FxaaTex sampler2D
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_120
    // Requires "#version 120" or better
    #define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
    #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
    // Requires "#version 130" or better
    #define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#endif
/*--------------------------------------------------------------------------*/

#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
    #if FXAA_GLSL_120
        return texture2DGrad(tex, pos.xy, grad, grad);
    #endif
    #if FXAA_GLSL_130
        return textureGrad(tex, pos.xy, grad, grad);
    #endif
}

/*============================================================================
                                 SRGB KNOBS
------------------------------------------------------------------------------
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
                This will do the sRGB to linear transform,
                as ROP will expect linear color from this shader,
                and this shader works in non-linear color.
============================================================================*/
#define FXAA_SRGB_ROP 0

/*============================================================================
                                DEBUG KNOBS
------------------------------------------------------------------------------
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
 
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
                         yellow tint on sub-pixel aliasing filtered by FXAA.
FXAA_DEBUG_HORZVERT    - Blue for horizontal edges, gold for vertical edges.
FXAA_DEBUG_PAIR        - Blue/green for the 2 pixel pair choice.
FXAA_DEBUG_NEGPOS      - Red/blue for which side of center of span.
FXAA_DEBUG_OFFSET      - Red/blue for -/+ x, gold/skyblue for -/+ y.
============================================================================*/
#ifndef     FXAA_DEBUG_PASSTHROUGH
    #define FXAA_DEBUG_PASSTHROUGH 0
#endif   
#ifndef     FXAA_DEBUG_HORZVERT
    #define FXAA_DEBUG_HORZVERT    0
#endif   
#ifndef     FXAA_DEBUG_PAIR   
    #define FXAA_DEBUG_PAIR        0
#endif   
#ifndef     FXAA_DEBUG_NEGPOS
    #define FXAA_DEBUG_NEGPOS      0
#endif
#ifndef     FXAA_DEBUG_OFFSET
    #define FXAA_DEBUG_OFFSET      0
#endif   
/*--------------------------------------------------------------------------*/
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
    #define FXAA_DEBUG 1
#endif   
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
    #define FXAA_DEBUG 1
#endif
#ifndef FXAA_DEBUG
    #define FXAA_DEBUG 0
#endif
 
/*============================================================================
                              COMPILE-IN KNOBS
------------------------------------------------------------------------------
FXAA_PRESET - Choose compile-in knob preset 0-5.
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
                      to apply algorithm.
                      1.0/3.0  - too little
                      1.0/4.0  - good start
                      1.0/8.0  - applies to more edges
                      1.0/16.0 - overkill
------------------------------------------------------------------------------
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
                          Perf optimization.
                          1.0/32.0 - visible limit (smaller isn't visible)
                          1.0/16.0 - good compromise
                          1.0/12.0 - upper limit (seeing artifacts)
------------------------------------------------------------------------------
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
------------------------------------------------------------------------------
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
                           1 - no acceleration
                           2 - skip by 2 pixels
                           3 - skip by 3 pixels
                           4 - skip by 4 pixels
------------------------------------------------------------------------------
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
                        1.0/4.0 - seems to be the best quality wise
------------------------------------------------------------------------------
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
                     Not recomended, but used in preset 0.
------------------------------------------------------------------------------
FXAA_SUBPIX - Toggle subpix filtering.
              0 - turn off
              1 - turn on
              2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
------------------------------------------------------------------------------
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
                   1.0/2.0 - low removal
                   1.0/3.0 - medium removal
                   1.0/4.0 - default removal
                   1.0/8.0 - high removal
                   0.0 - complete removal
------------------------------------------------------------------------------
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
                  This is important for the transition of sub-pixel detail,
                  like fences and wires.
                  3.0/4.0 - default (medium amount of filtering)
                  7.0/8.0 - high amount of filtering
                  1.0 - no capping of sub-pixel aliasing removal
============================================================================*/
#ifndef FXAA_PRESET
    #define FXAA_PRESET 3
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 0)
    #define FXAA_EDGE_THRESHOLD      (1.0/4.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/12.0)
    #define FXAA_SEARCH_STEPS        2
    #define FXAA_SEARCH_ACCELERATION 4
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       1
    #define FXAA_SUBPIX_CAP          (2.0/3.0)
    #define FXAA_SUBPIX_TRIM         (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 1)
    #define FXAA_EDGE_THRESHOLD      (1.0/8.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/16.0)
    #define FXAA_SEARCH_STEPS        4
    #define FXAA_SEARCH_ACCELERATION 3
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (3.0/4.0)
    #define FXAA_SUBPIX_TRIM         (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 2)
    #define FXAA_EDGE_THRESHOLD      (1.0/8.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/24.0)
    #define FXAA_SEARCH_STEPS        8
    #define FXAA_SEARCH_ACCELERATION 2
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (3.0/4.0)
    #define FXAA_SUBPIX_TRIM         (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 3)
    #define FXAA_EDGE_THRESHOLD      (1.0/8.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/24.0)
    #define FXAA_SEARCH_STEPS        16
    #define FXAA_SEARCH_ACCELERATION 1
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (3.0/4.0)
    #define FXAA_SUBPIX_TRIM         (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 4)
    #define FXAA_EDGE_THRESHOLD      (1.0/8.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/24.0)
    #define FXAA_SEARCH_STEPS        24
    #define FXAA_SEARCH_ACCELERATION 1
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (3.0/4.0)
    #define FXAA_SUBPIX_TRIM         (1.0/4.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 5)
    #define FXAA_EDGE_THRESHOLD      (1.0/8.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/24.0)
    #define FXAA_SEARCH_STEPS        32
    #define FXAA_SEARCH_ACCELERATION 1
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (7.0/8.0)
    #define FXAA_SUBPIX_TRIM         (1.0/8.0)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_PRESET == 6)
    #define FXAA_EDGE_THRESHOLD      (1.0/12.0)
    #define FXAA_EDGE_THRESHOLD_MIN  (1.0/24.0)
    #define FXAA_SEARCH_STEPS        32
    #define FXAA_SEARCH_ACCELERATION 1
    #define FXAA_SEARCH_THRESHOLD    (1.0/4.0)
    #define FXAA_SUBPIX              1
    #define FXAA_SUBPIX_FASTER       0
    #define FXAA_SUBPIX_CAP          (1.0)
    #define FXAA_SUBPIX_TRIM         (0.0)
#endif
/*--------------------------------------------------------------------------*/
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))

/*============================================================================
                                   HELPERS
============================================================================*/
// Return the luma, the estimation of luminance from rgb inputs.
// This approximates luma using one FMA instruction,
// skipping normalization and tossing out blue.
// FxaaLuma() will range 0.0 to 2.963210702.
float FxaaLuma(float3 rgb) {
    return rgb.y * (0.587/0.299) + rgb.x; }
/*--------------------------------------------------------------------------*/
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
    return (FxaaToFloat3(-amountOfA) * b) +
        ((a * FxaaToFloat3(amountOfA)) + b); }
/*--------------------------------------------------------------------------*/
// Support any extra filtering before returning color.
float3 FxaaFilterReturn(float3 rgb) {
    #if FXAA_SRGB_ROP
        // Do sRGB encoded value to linear conversion.
        return FxaaSel3(
            rgb * FxaaToFloat3(1.0/12.92),
            FxaaPow3(
                rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
                FxaaToFloat3(2.4)),
            rgb > FxaaToFloat3(0.04045));
    #else
        return rgb;
    #endif
}
 
/*============================================================================
                                VERTEX SHADER
============================================================================*/
float2 FxaaVertexShader(
// Both x and y range {-1.0 to 1.0 across screen}.
float2 inPos) {
    float2 pos;
    pos.xy = (inPos.xy * FxaaFloat2(0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
    return pos; } 
 
/*============================================================================
                                PIXEL SHADER
============================================================================*/
float3 FxaaPixelShader(
// Output of FxaaVertexShader interpolated across screen.
//  xy -> actual texture position {0.0 to 1.0}
float2 pos,
// Input texture.
FxaaTex tex,
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// {1.0/frameWidth, 1.0/frameHeight}
float2 rcpFrame) {
   
/*----------------------------------------------------------------------------
            EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
------------------------------------------------------------------------------
Majority of pixels of a typical image do not require filtering,
often pixels are grouped into blocks which could benefit from early exit
right at the beginning of the algorithm.
Given the following neighborhood,
 
      N   
    W M E
      S   
   
If the difference in local maximum and minimum luma (contrast "range")
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
then the shader early exits (no visible aliasing).
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
to avoid processing in really dark areas.   
----------------------------------------------------------------------------*/
    float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
    float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
    float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
    float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
    float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
    float lumaN = FxaaLuma(rgbN);
    float lumaW = FxaaLuma(rgbW);
    float lumaM = FxaaLuma(rgbM);
    float lumaE = FxaaLuma(rgbE);
    float lumaS = FxaaLuma(rgbS);
    float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
    float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
    float range = rangeMax - rangeMin;
    #if FXAA_DEBUG
        float lumaO = lumaM / (1.0 + (0.587/0.299));
    #endif       
    if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
        #if FXAA_DEBUG
            return FxaaFilterReturn(FxaaToFloat3(lumaO));
        #endif
        return FxaaFilterReturn(rgbM); }
    #if FXAA_SUBPIX > 0
        #if FXAA_SUBPIX_FASTER
            float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
                FxaaToFloat3(1.0/5.0);
        #else
            float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
        #endif
    #endif       
   
/*----------------------------------------------------------------------------
                               COMPUTE LOWPASS
------------------------------------------------------------------------------
FXAA computes a local neighborhood lowpass value as follows,
 
  (N + W + E + S)/4
 
Then uses the ratio of the contrast range of the lowpass
and the range found in the early exit check,
as a sub-pixel aliasing detection filter.
When FXAA detects sub-pixel aliasing (such as single pixel dots),
it later blends in "blendL" amount
of a lowpass value (computed in the next section) to the final result.
----------------------------------------------------------------------------*/
    #if FXAA_SUBPIX != 0
        float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
        float rangeL = abs(lumaL - lumaM);
    #endif       
    #if FXAA_SUBPIX == 1
        float blendL = max(0.0,
            (rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
        blendL = min(FXAA_SUBPIX_CAP, blendL);
    #endif
    #if FXAA_SUBPIX == 2
        float blendL = rangeL / range;
    #endif
    #if FXAA_DEBUG_PASSTHROUGH
        #if FXAA_SUBPIX == 0
            float blendL = 0.0;
        #endif
        return FxaaFilterReturn(
            FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
    #endif   
   
/*----------------------------------------------------------------------------
                    CHOOSE VERTICAL OR HORIZONTAL SEARCH
------------------------------------------------------------------------------
FXAA uses the following local neighborhood,
 
    NW N NE
    W  M  E
    SW S SE
   
To compute an edge amount for both vertical and horizontal directions.
Note edge detect filters like Sobel fail on single pixel lines through M.
FXAA takes the weighted average magnitude of the high-pass values
for rows and columns as an indication of local edge amount.
 
A lowpass value for anti-sub-pixel-aliasing is computed as
    (N+W+E+S+M+NW+NE+SW+SE)/9.
This full box pattern has higher quality than other options.
 
Note following this block, both vertical and horizontal cases
flow in parallel (reusing the horizontal variables).
----------------------------------------------------------------------------*/
    float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
    float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
    float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
    float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
    #if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
        rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
        rgbL *= FxaaToFloat3(1.0/9.0);
    #endif
    float lumaNW = FxaaLuma(rgbNW);
    float lumaNE = FxaaLuma(rgbNE);
    float lumaSW = FxaaLuma(rgbSW);
    float lumaSE = FxaaLuma(rgbSE);
    float edgeVert =
        abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
        abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
        abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
    float edgeHorz =
        abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
        abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
        abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
    bool horzSpan = edgeHorz >= edgeVert;
    #if FXAA_DEBUG_HORZVERT
        if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
        else         return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
    #endif
    float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
    if(!horzSpan) lumaN = lumaW;
    if(!horzSpan) lumaS = lumaE;
    float gradientN = abs(lumaN - lumaM);
    float gradientS = abs(lumaS - lumaM);
    lumaN = (lumaN + lumaM) * 0.5;
    lumaS = (lumaS + lumaM) * 0.5;
   
/*----------------------------------------------------------------------------
                CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
------------------------------------------------------------------------------
This chooses a pixel pair.
For "horzSpan == true" this will be a vertical pair,
 
    [N]     N
    [M] or [M]
     S     [S]
 
Note following this block, both {N,M} and {S,M} cases
flow in parallel (reusing the {N,M} variables).
 
This pair of image rows or columns is searched below
in the positive and negative direction
until edge status changes
(or the maximum number of search steps is reached).
----------------------------------------------------------------------------*/   
    bool pairN = gradientN >= gradientS;
    #if FXAA_DEBUG_PAIR
        if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
        else      return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
    #endif
    if(!pairN) lumaN = lumaS;
    if(!pairN) gradientN = gradientS;
    if(!pairN) lengthSign *= -1.0;
    float2 posN;
    posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
    posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
   
/*----------------------------------------------------------------------------
                         CHOOSE SEARCH LIMITING VALUES
------------------------------------------------------------------------------
Search limit (+/- gradientN) is a function of local gradient.
----------------------------------------------------------------------------*/
    gradientN *= FXAA_SEARCH_THRESHOLD;
   
/*----------------------------------------------------------------------------
    SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
------------------------------------------------------------------------------
This loop searches either in vertical or horizontal directions,
and in both the negative and positive direction in parallel.
This loop fusion is faster than searching separately.
 
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
via anisotropic filtering with specified texture gradients.
----------------------------------------------------------------------------*/
    float2 posP = posN;
    float2 offNP = horzSpan ?
        FxaaFloat2(rcpFrame.x, 0.0) :
        FxaaFloat2(0.0, rcpFrame.y);
    float lumaEndN = lumaN;
    float lumaEndP = lumaN;
    bool doneN = false;
    bool doneP = false;
    #if FXAA_SEARCH_ACCELERATION == 1
        posN += offNP * FxaaFloat2(-1.0, -1.0);
        posP += offNP * FxaaFloat2( 1.0,  1.0);
    #endif
    #if FXAA_SEARCH_ACCELERATION == 2
        posN += offNP * FxaaFloat2(-1.5, -1.5);
        posP += offNP * FxaaFloat2( 1.5,  1.5);
        offNP *= FxaaFloat2(2.0, 2.0);
    #endif
    #if FXAA_SEARCH_ACCELERATION == 3
        posN += offNP * FxaaFloat2(-2.0, -2.0);
        posP += offNP * FxaaFloat2( 2.0,  2.0);
        offNP *= FxaaFloat2(3.0, 3.0);
    #endif
    #if FXAA_SEARCH_ACCELERATION == 4
        posN += offNP * FxaaFloat2(-2.5, -2.5);
        posP += offNP * FxaaFloat2( 2.5,  2.5);
        offNP *= FxaaFloat2(4.0, 4.0);
    #endif
    for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
        #if FXAA_SEARCH_ACCELERATION == 1
            if(!doneN) lumaEndN =
                FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
            if(!doneP) lumaEndP =
                FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
        #else
            if(!doneN) lumaEndN =
                FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
            if(!doneP) lumaEndP =
                FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
        #endif
        doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
        doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
        if(doneN && doneP) break;
        if(!doneN) posN -= offNP;
        if(!doneP) posP += offNP; }
   
/*----------------------------------------------------------------------------
               HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
------------------------------------------------------------------------------
FXAA uses the pixel's position in the span
in combination with the values (lumaEnd*) at the ends of the span,
to determine filtering.
 
This step computes which side of the span the pixel is on.
On negative side if dstN < dstP,
 
     posN        pos                      posP
      |-----------|------|------------------|
      |           |      |                  |
      |<--dstN--->|<---------dstP---------->|
                         |
                    span center
                   
----------------------------------------------------------------------------*/
    float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
    float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
    bool directionN = dstN < dstP;
    #if FXAA_DEBUG_NEGPOS
        if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
        else           return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
    #endif
    lumaEndN = directionN ? lumaEndN : lumaEndP;
   
/*----------------------------------------------------------------------------
         CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
------------------------------------------------------------------------------
If both the pair luma at the end of the span (lumaEndN)
and middle pixel luma (lumaM)
are on the same side of the middle pair average luma (lumaN),
then don't filter.
 
Cases,
 
(1.) "L",
 
               lumaM
                 |
                 V    XXXXXXXX <- other line averaged
         XXXXXXX[X]XXXXXXXXXXX <- source pixel line
        |      .      |
    --------------------------                   
       [ ]xxxxxx[x]xx[X]XXXXXX <- pair average
    --------------------------           
        ^      ^ ^    ^
        |      | |    |
        .      |<---->|<---------- no filter region
        .      | |    |
        . center |    |
        .        |  lumaEndN
        .        |    .
        .      lumaN  .
        .             .
        |<--- span -->|
       
                       
(2.) "^" and "-",
 
                               <- other line averaged
          XXXXX[X]XXX          <- source pixel line
         |     |     |
    --------------------------                   
        [ ]xxxx[x]xx[ ]        <- pair average
    --------------------------           
         |     |     |
         |<--->|<--->|<---------- filter both sides
 
 
(3.) "v" and inverse of "-",
 
    XXXXXX           XXXXXXXXX <- other line averaged
    XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
         |     |     |
    --------------------------                   
    XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
    --------------------------           
         |     |     |
         |<--->|<--->|<---------- don't filter both!
 
         
Note the "v" case for FXAA requires no filtering.
This is because the inverse of the "-" case is the "v".
Filtering "v" case turns open spans like this,
 
    XXXXXXXXX
   
Into this (which is not desired),
 
    x+.   .+x
    XXXXXXXXX
 
----------------------------------------------------------------------------*/
    if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
        lengthSign = 0.0;
 
/*----------------------------------------------------------------------------
                COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
------------------------------------------------------------------------------
FXAA filters using a bilinear texture fetch offset
from the middle pixel M towards the center of the pair (NM below).
Maximum filtering will be half way between pair.
Reminder, at this point in the code,
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
 
    +-------+
    |       |    0.5 offset
    |   N   |     |
    |       |     V
    +-------+....---
    |       |
    |   M...|....---
    |       |     ^
    +-------+     |
    .       .    0.0 offset
    .   S   .
    .       .
    .........
 
Position on span is used to compute sub-pixel filter offset using simple ramp,
 
             posN           posP
              |\             |<------- 0.5 pixel offset into pair pixel
              | \            |
              |  \           |
    ---.......|...\..........|<------- 0.25 pixel offset into pair pixel
     ^        |   ^\         |
     |        |   | \        |
     V        |   |  \       |
    ---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
     ^        .   |   ^      .
     |        .  pos  |      .
     |        .   .   |      .
     |        .   . center   .
     |        .   .          .
     |        |<->|<---------.-------- dstN
     |        .   .          .   
     |        .   |<-------->|<------- dstP   
     |        .             .
     |        |<------------>|<------- spanLength   
     |
    subPixelOffset
   
----------------------------------------------------------------------------*/
    float spanLength = (dstP + dstN);
    dstN = directionN ? dstN : dstP;
    float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
    #if FXAA_DEBUG_OFFSET
        float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
        float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
        if(ox < 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(1.0, 0.0, 0.0), -ox));
        if(ox > 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(0.0, 0.0, 1.0),  ox));
        if(oy < 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(1.0, 0.6, 0.2), -oy));
        if(oy > 0.0) return FxaaFilterReturn(
            FxaaLerp3(FxaaToFloat3(lumaO),
                      FxaaFloat3(0.2, 0.6, 1.0),  oy));
        return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
    #endif
    float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
        pos.x + (horzSpan ? 0.0 : subPixelOffset),
        pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
    #if FXAA_SUBPIX == 0
        return FxaaFilterReturn(rgbF);
    #else       
        return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
    #endif
}

uniform sampler2D tex0;
varying vec2 rcpFrame;
noperspective varying vec2 pos;

void main() {
gl_FragColor.xyz = FxaaPixelShader(pos, tex0, rcpFrame);
}


A refined version from earlier. Changes include:
     Removing all the HLSL stuff (as we don't use it)
     Adding a "FXAA_PRESET == 6" for those of you daring enough to use it
     A slight tweak to FXAA_PRESET 5.
Title: Re: FXAA in FSO
Post by: The E on May 18, 2011, 06:43:39 am
First post has been updated. You may wish to redownload the builds and shaders.
Title: Re: FXAA in FSO
Post by: Zacam on May 18, 2011, 07:03:01 am

Do note, the shaders I last linked work for the first builds E posted.

They may even work in the new builds. But the first post has updated shaders for use with the newer builds which allows you to "preview" the FXAA Presets in the LAB and then set a preset option in the commandline. It's highly recommended that you use those. Mine will remain posted for no other reason than I'm lazy.
Title: Re: FXAA in FSO
Post by: Kolgena on May 18, 2011, 11:02:26 am
btw, thought I should mention that FXAA is especially awesome for all the effects in the game. Beams look sooo much nicer when not aliased.
Title: Re: FXAA in FSO
Post by: DaBrain on May 25, 2011, 03:57:10 pm
It does reduce the image sharpness a bit, but I can live with that. I kills aliasing pretty well and even helps with shader aliasing and texture shimmering.
I hardly noticed any performance drop and I'm only using an older Geforce 260. ;)


The only thing I mind is the option in the launcher for AA.
Either take it out, or update it. It never worked and now that might even lead people to the assumption AA is not possible in FSO at all.


Anyway, great work!
Title: Re: FXAA in FSO
Post by: Luis Dias on May 25, 2011, 04:28:56 pm
clap clap clap!
Title: Re: FXAA in FSO
Post by: Sobbsy on May 25, 2011, 10:17:52 pm
This appears to work really well. I tested it out in a few missions and it has pretty much no effect on the framerates, to my surprise.

Out of curiosity, is there a way to stop the 'Hide post-processing' flag from being set in the F3 lab? Every time I fire up the game I have to go into that and untick that option to get FXAA and Post-Processing to work together. I have PP enabled in the launcher along with FXAA, so I don't see why it's doing that.

Looks fantastic though... Finally some working AA!
Title: Re: FXAA in FSO
Post by: Zacam on May 26, 2011, 11:36:10 am

Unless you are missing "-bloom_intensity ###" and "-fxaa_preset #" in your command line, you don't need to go to the Lab to set values for gameplay use.

And if you don't have the command line settings, then default values will get used. Which if you are changing those in the Lab, will carry through to game-play.

But you do not need to go into the Lab to turn on Post-Processing that is already turned on in the launcher in order to have it work.

The "Hide Post Processing" tick box is not an on/off switch for the game, it's just a visual aid element. Most people still use the Lab when modding/modeling for the game, so it defaults to not showing the post processing effects. But again, it is not an on/off switch for the game itself.
Title: Re: FXAA in FSO
Post by: Sobbsy on May 26, 2011, 06:27:37 pm
Interesting, I'll have to double check when I get home again later. I do have both of those commands entered properly into my command line. Initially, I enabled FXAA and Post-Processing, made sure the command line was correct, then just fired up FS2 and proceeded to test a mission (The Great Hunt - it offers some good contrast against the nebula background to test with) and noticed that there was absolutely no sign of any post-processing or AA. So I went back to the main menu, opened the lab and unticked that 'Hide post-processing' option (which made it work just fine in the lab there) and fired up the same mission... Seemed to fix the problem and it was clearly working.

I'll check it again later but on at least one other occasion after that I had to do the same thing to get it working in-game - fire up the lab, uncheck 'Hide post-processing'. Is there absolutely in no way, shape or form any kind of link between the lab and the actual game? Maybe I've just got some obscure little problem and the controls in the lab are fiddling with the actual application ingame somehow... I will have to take another look tonight just to be absolutely certain that I'm not having a brainfart!

Thanks again.
Title: Re: FXAA in FSO
Post by: Ace on May 26, 2011, 08:16:40 pm
I've been having some issues with FXAA when combined with render to texture, resulting in crashes. I think this probably has more to do with the RTT code than post processing, but here's a log:
http://www.hard-light.net/forums/index.php?action=dlattach;topic=76339.0;attach=16468
Title: Re: FXAA in FSO
Post by: The E on May 27, 2011, 02:50:08 am
Ummm... I can't open that link. Could you either attach the log to your post here, in this thread, or paste it into your post (surrounded by [code] tags, of course)?
Title: Re: FXAA in FSO
Post by: The E on May 27, 2011, 05:17:10 am
I'll check it again later but on at least one other occasion after that I had to do the same thing to get it working in-game - fire up the lab, uncheck 'Hide post-processing'. Is there absolutely in no way, shape or form any kind of link between the lab and the actual game? Maybe I've just got some obscure little problem and the controls in the lab are fiddling with the actual application ingame somehow... I will have to take another look tonight just to be absolutely certain that I'm not having a brainfart!

Thanks again.

The "Hide post-processing" checkbox is a lab-only override. Technically, the lab uses the same render pipeline as the regular game, including post-processing. If the "Hide post-processing" box is marked, the lab (and only the lab!) will skip the PP render stage. It doesn't have any effect beyond the lab.

That being said, it would be helplful if I could get some more info. What builds are you using? Which version of the FXAA shaders? And, above all else, can you post an fs2_open.log?
Title: Re: FXAA in FSO
Post by: Macfie on June 10, 2011, 11:56:07 am
Do the FXAA shaders replace the the main-f and main-v shaders or are they used in addition to them?
Title: Re: FXAA in FSO
Post by: The E on June 10, 2011, 12:09:34 pm
They are used in addition to the rest of the shaders (Note: Recent nightlies have the shaders integrated into the exe, so you don't need the files posted here to use FXAA).

FXAA is a separate rendering step, inserted into the pipeline before the rest of the post-processing effects.
Title: Re: FXAA in FSO
Post by: Macfie on June 10, 2011, 02:38:09 pm
They are used in addition to the rest of the shaders (Note: Recent nightlies have the shaders integrated into the exe, so you don't need the files posted here to use FXAA).

FXAA is a separate rendering step, inserted into the pipeline before the rest of the post-processing effects.

Does that mean I don't need the FXAA-f and FXAA-V shader files in the effects Folder?
Is the same true for the main-f and main-v shader files?
Title: Re: FXAA in FSO
Post by: Angelus on June 10, 2011, 02:55:38 pm
Yeah, shader files in the folder will override the built-in ones.
Title: Re: FXAA in FSO
Post by: The E on June 10, 2011, 03:39:40 pm
Does that mean I don't need the FXAA-f and FXAA-V shader files in the effects Folder?
Is the same true for the main-f and main-v shader files?

Yes and yes.
Title: Re: FXAA in FSO
Post by: Kolgena on June 24, 2011, 03:59:30 pm
Quick suggestion: Make the preset 0 instead use the fast and dirty console version. Ver2 shader is like twice as fast, and at least to me, looks better than preset 0.
Title: Re: FXAA in FSO
Post by: Zacam on June 24, 2011, 04:09:15 pm

Wait, what? That entirely made no sense what so ever.

If the ver2 is twice as fas and looks better, then why would we make preset 0 of the "console" version the default?

The presets are arranged in terms of staging the available options so that a user can scale the option based on performance feedback. Not everybody is going to be able to rock out with preset 6, for example.
Title: Re: FXAA in FSO
Post by: The E on June 24, 2011, 04:28:04 pm
Preset 0 is the quick-and-dirty console version, more or less.x

EDIT: But given that there are still some differences between the two, I would recommend using them as optional shaders. It's impossible to simply add the Console version to the v1 version because of a few differences in calling conventions between the two (The v2 version passes different information between shader stages).
Title: Re: FXAA in FSO
Post by: Kolgena on June 24, 2011, 06:14:34 pm
Okay, that makes sense. I thought that it could have been "If fxaa_preset ==0, then ignore everything else and use this block of code", but then again, I'm illiterate, so that might come across as something stupid to assume.

@ Zacam: This is the ver2 I was talking about. It does indeed run a fair bit faster than preset zero in this thread.
Code: [Select]
uniform sampler2D tex0; // 0
//uniform float vx_offset;
uniform float rt_w; // GeeXLab built-in
uniform float rt_h; // GeeXLab built-in
#define FXAA_SPAN_MAX 8.0
#define FXAA_REDUCE_MUL (1.0/8.0)
varying vec4 posPos;

#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)

void main()
{
  vec2 rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
  vec4 c = vec4(0.0);
  c.a = 1.0;

/*---------------------------------------------------------*/
    #define FXAA_REDUCE_MIN   (1.0/128.0)
    //#define FXAA_REDUCE_MUL   (1.0/8.0)
    //#define FXAA_SPAN_MAX     8.0
/*---------------------------------------------------------*/
    vec3 rgbNW = FxaaTexLod0(tex0, posPos.zw).xyz;
    vec3 rgbNE = FxaaTexOff(tex0, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;
    vec3 rgbSW = FxaaTexOff(tex0, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;
    vec3 rgbSE = FxaaTexOff(tex0, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;
    vec3 rgbM  = FxaaTexLod0(tex0, posPos.xy).xyz;
/*---------------------------------------------------------*/
    vec3 luma = vec3(0.299, 0.587, 0.114);
    float lumaNW = dot(rgbNW, luma);
    float lumaNE = dot(rgbNE, luma);
    float lumaSW = dot(rgbSW, luma);
    float lumaSE = dot(rgbSE, luma);
    float lumaM  = dot(rgbM,  luma);
/*---------------------------------------------------------*/
    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
/*---------------------------------------------------------*/
    vec2 dir;
    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
/*---------------------------------------------------------*/
    float dirReduce = max(
        (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
        FXAA_REDUCE_MIN);
    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
    dir = min(FxaaFloat2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX),
          max(FxaaFloat2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
          dir * rcpDirMin)) * rcpFrame.xy;
/*--------------------------------------------------------*/
    vec3 rgbA = (1.0/2.0) * (
        FxaaTexLod0(tex0, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +
        FxaaTexLod0(tex0, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
        FxaaTexLod0(tex0, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +
        FxaaTexLod0(tex0, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
    float lumaB = dot(rgbB, luma);
    if((lumaB < lumaMin) || (lumaB > lumaMax)) c.rgb = rgbA;
    else c.rgb = rgbB;

gl_FragColor = c;
}

Just to make sure we're talking about the same thing here.
Title: Re: FXAA in FSO
Post by: The E on June 24, 2011, 06:17:29 pm
Well, what we will be doing is distribute v2 with the next MediaVPs root, with v1 being in mv_advanced.
Title: Re: FXAA in FSO
Post by: Kolgena on June 24, 2011, 06:18:24 pm
...

That's a very smart idea and definitely something that I would never have thought of :P
Title: Re: FXAA in FSO
Post by: The E on June 25, 2011, 08:04:44 am
Okay, I've been looking at the FXAA v2 shaders and found a bit of configurability. If you replace your FXAA-v.sdr with this:

**CODE REMOVED**

The -fxaa_preset argument will work for you as well. Quality presets once again go from 0 to 6, with 0 being worst and 6 being best.

IMPORTANT NOTE! Do NOT use these with the v1 shaders posted in this thread, sa using both WILL cause issues.
Title: Re: FXAA in FSO
Post by: The E on July 04, 2011, 07:41:07 pm
:bump:

Also, double post.

Timothy Lottes has been hard at work optimizing FXAA. So here's FXAA version 3, Console Edition (There's a PC edition too, but I seem to have trouble getting it to work correctly, so watch this space for updates).

EDIT: Code removed, see my next post.
Title: Re: FXAA in FSO
Post by: MetalDestroyer on July 05, 2011, 06:44:29 am
What are the change with the previous version ?
- better performance ?
- better anti-aliasing ?
- ??
Title: Re: FXAA in FSO
Post by: The E on July 05, 2011, 06:59:33 am
Okay, So I worked on it a bit and got the full FXAA v3 package to run.

**CODE REMOVED, USE A RECENT NIGHTLY BUILD**

This increases the range of presets to 0-9 inclusive. Presets 0-4 use the fast & dirty console versions, 5-9 use the PC algorithm. This version is supposed to be faster, and higher quality.
Title: Re: FXAA in FSO
Post by: Cogitation on July 13, 2011, 01:30:29 pm
I'm brand new to the forum and to freespace 2 actually.  I just read on gamespot that one of their reviewers considered it one of the best games of all time, and I used to really love the X-wing/Tie Fighter series back in the day, so I thought I'd check it out.

Would anyone participating in the thread be able to tell me how best to enable this FXAA in my install, once I get it set up?  (I'm still reading FAQ's and downloading files at the moment, trying to get organized to go through the install process)  Should I be using the recommended build, or a nightly build?  Can I just put a shader file in a directory and it will work?

Appreciate the help if anyone sees this.
Title: Re: FXAA in FSO
Post by: Macfie on July 13, 2011, 02:11:01 pm
FXAA is included in the nightly builds.  If you use the latest nightly build you will have the FXAA.  There is a selection in the launcher to enable FXAA.  You will also have to enable post processing.
Title: Re: FXAA in FSO
Post by: Cogitation on July 13, 2011, 02:39:11 pm
Okay, cool.  Is there anything I need to be aware of to use the latest nightly build versus the recommended, other than just a disclaimer "you might encounter bugs" ?

Will I perhaps encounter issues/bugs, or will I almost certainly?

Is it possible to enable FXAA in the stable build at all, or is it a feature only available in the newest compiles?
Title: Re: FXAA in FSO
Post by: Dragon on July 13, 2011, 02:44:25 pm
Nightlies are pretty stable, you shouldn't encouncer bugs in normal gameplay.
FXAA is only available on most recent builds and thus, nothing more stable than a nightly is equipped with it.
Title: Re: FXAA in FSO
Post by: Cogitation on July 13, 2011, 07:25:18 pm
Thanks guys.  And thanks for all the work done on this project too.
Title: Re: FXAA in FSO
Post by: The E on July 14, 2011, 12:19:56 pm
Well well well.

Timothy Lottes has been busy working on FXAA some more, and recently released FXAA v3.9. It it purported to be a bit faster, and with better handling of some edge cases. Please try this shader, and see if you can spot any positive difference between this and the one built into the engine.

To use this, save it as fxaa-f.sdr in FS2/data/effects (or, if you have a previous version of this shader, overwrite it with this one).
Code: [Select]
#extension GL_EXT_gpu_shader4 : enable


/*==========================================================================*/
#define FXAA_EARLY_EXIT 1
#define FXAA_DISCARD 1
#define FXAA_LINEAR 0
/*--------------------------------------------------------------------------*/
#ifndef FXAA_FAST_PIXEL_OFFSET
    #ifdef GL_EXT_gpu_shader4
        #define FXAA_FAST_PIXEL_OFFSET 1
    #endif
    #ifdef GL_NV_gpu_shader5
        #define FXAA_FAST_PIXEL_OFFSET 1
    #endif
    #ifdef GL_ARB_gpu_shader5
        #define FXAA_FAST_PIXEL_OFFSET 1
    #endif
    #ifndef FXAA_FAST_PIXEL_OFFSET
        #define FXAA_FAST_PIXEL_OFFSET 0
    #endif
#endif

#ifndef FXAA_GATHER4_ALPHA
    //
    // 1 = API supports gather4 on alpha channel.
    // 0 = API does not support gather4 on alpha channel.
    //
    #if (FXAA_HLSL_5 == 1)
        #define FXAA_GATHER4_ALPHA 1
    #endif
    #ifdef GL_ARB_gpu_shader5
        #define FXAA_GATHER4_ALPHA 1
    #endif
    #ifdef GL_NV_gpu_shader5
        #define FXAA_GATHER4_ALPHA 1
    #endif
    #ifndef FXAA_GATHER4_ALPHA
        #define FXAA_GATHER4_ALPHA 0
    #endif
#endif
/*--------------------------------------------------------------------------*/

/*============================================================================
                         TUNING KNOBS
============================================================================*/
float EDGE_SHARPNESS = 0.0;

float EDGE_THRESHOLD = 0.0;
float EDGE_THRESHOLD_MIN = 0.0;

float SUBPIX_CAP = 0.0;
float SUBPIX_TRIM = 0.0;

void fxaa_choose_preset(int preset) {
if (preset == 0) {
EDGE_SHARPNESS = 8.0;
EDGE_THRESHOLD = 1.0/8.0;
EDGE_THRESHOLD_MIN = 0.05;
} else if (preset == 1) {
EDGE_SHARPNESS = 7.0;
EDGE_THRESHOLD = 1.0/7.0;
EDGE_THRESHOLD_MIN = 0.04;
}  else if (preset == 2) {
EDGE_SHARPNESS = 6.0;
EDGE_THRESHOLD = 1.0/6.0;
EDGE_THRESHOLD_MIN = 0.03;
} else if (preset == 3) {
EDGE_SHARPNESS = 5.0;
EDGE_THRESHOLD = 1.0/5.0;
EDGE_THRESHOLD_MIN = 0.02;
} else if (preset == 4) {
EDGE_SHARPNESS = 4.0;
EDGE_THRESHOLD = 1.0/4.0;
EDGE_THRESHOLD_MIN = 0.01;
} else if (preset == 5) {
EDGE_THRESHOLD = 1.0/3.0;
EDGE_THRESHOLD_MIN = 1.0/16.0;
SUBPIX_CAP = 3.0/4.0;
} else if (preset == 6) {
EDGE_THRESHOLD = 1.0/5.0;
EDGE_THRESHOLD_MIN = 1.0/20.0;
SUBPIX_CAP = 4.0/5.0;
} else if (preset == 7) {
EDGE_THRESHOLD = 1.0/7.0;
EDGE_THRESHOLD_MIN = 1.0/24.0;
SUBPIX_CAP = 5.0/6.0;
} else if (preset == 8) {
EDGE_THRESHOLD = 1.0/10.0;
EDGE_THRESHOLD_MIN = 1.0/28.0;
SUBPIX_CAP = 7.0/8.0;
} else {
EDGE_THRESHOLD = 1.0/12.0;
EDGE_THRESHOLD_MIN = 1.0/32.0;
SUBPIX_CAP = 1.0;
}
}

/*============================================================================

                                 API PORTING
                                 
============================================================================*/

//Choose API

#if SHADER_MODEL == 2
    #define FXAA_GLSL_120 1
#define FXAA_GLSL_130 0
#endif
#if SHADER_MODEL > 2
    #define FXAA_GLSL_130 1
#define FXAA_GLSL_120 0
#endif

#if FXAA_GLSL_120
    // Requires,
    //  #version 120
    // And at least,
    //  #extension GL_EXT_gpu_shader4 : enable
    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
    #define half float
    #define half2 vec2
    #define half3 vec3
    #define half4 vec4
    #define int2 ivec2
    #define float2 vec2
    #define float3 vec3
    #define float4 vec4
    #define FxaaInt2 ivec2
    #define FxaaFloat2 vec2
    #define FxaaFloat3 vec3
    #define FxaaFloat4 vec4
    #define FxaaDiscard discard
    #define FxaaDot3(a, b) dot(a, b)
    #define FxaaSat(x) clamp(x, 0.0, 1.0)
    #define FxaaLerp(x,y,s) mix(x,y,s)
    #define FxaaTex sampler2D
    #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
    #if (FXAA_FAST_PIXEL_OFFSET == 1)
        #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
    #else
        #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
    #endif
    #if (FXAA_GATHER4_ALPHA == 1)
        // use #extension GL_ARB_gpu_shader5 : enable
        #define FxaaTexAlpha4(t, p, r) textureGather(t, p, 3)
        #define FxaaTexOffAlpha4(t, p, o, r) textureGatherOffset(t, p, o, 3)
    #endif       
#endif
/*--------------------------------------------------------------------------*/
#if FXAA_GLSL_130
    // Requires "#version 130" or better
    #define half float
    #define half2 vec2
    #define half3 vec3
    #define half4 vec4
    #define int2 ivec2
    #define float2 vec2
    #define float3 vec3
    #define float4 vec4
    #define FxaaInt2 ivec2
    #define FxaaFloat2 vec2
    #define FxaaFloat3 vec3
    #define FxaaFloat4 vec4
    #define FxaaDiscard discard
    #define FxaaDot3(a, b) dot(a, b)
    #define FxaaSat(x) clamp(x, 0.0, 1.0)
    #define FxaaLerp(x,y,s) mix(x,y,s)
    #define FxaaTex sampler2D
    #define FxaaTexTop(t, p) textureLod(t, p, 0.0)
    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
    #if (FXAA_GATHER4_ALPHA == 1)
        // use #extension GL_ARB_gpu_shader5 : enable
        #define FxaaTexAlpha4(t, p, r) textureGather(t, p, 3)
        #define FxaaTexOffAlpha4(t, p, o, r) textureGatherOffset(t, p, o, 3)
    #endif       
#endif

float getLuma(vec4 color) {
return dot(color.rgb, float3(0.299, 0.587, 0.114)); // compute luma
}

/*============================================================================

                      FXAA3 CONSOLE - PC PIXEL SHADER

------------------------------------------------------------------------------
Using a modified version of the PS3 version here to best target old hardware.
============================================================================*/
/*--------------------------------------------------------------------------*/
half4 FxaaPixelShader(
    // {xy} = center of pixel
    float2 pos,
    // {xy__} = upper left of pixel
    // {__zw} = lower right of pixel
    float4 posPos,
    // {rgb_} = color in linear or perceptual color space
    // {___a} = alpha output is junk value
    FxaaTex tex,
    // This must be from a constant/uniform.
    // {xy} = rcpFrame not used on PC version of FXAA Console
    float2 rcpFrame,
    // This must be from a constant/uniform.
    // {x___} = 2.0/screenWidthInPixels
    // {_y__} = 2.0/screenHeightInPixels
    // {__z_} = 0.5/screenWidthInPixels
    // {___w} = 0.5/screenHeightInPixels
    float4 rcpFrameOpt
) {
/*--------------------------------------------------------------------------*/
    half4 dir;
    dir.y = 0.0;
    half4 lumaNe = FxaaTexTop(tex, posPos.zy);
    lumaNe.w += half(1.0/384.0);
    dir.x = -lumaNe.w;
    dir.z = -lumaNe.w;
/*--------------------------------------------------------------------------*/
    half4 lumaSw = FxaaTexTop(tex, posPos.xw);
    dir.x += lumaSw.w;
    dir.z += lumaSw.w;
/*--------------------------------------------------------------------------*/
    half4 lumaNw = FxaaTexTop(tex, posPos.xy);
    dir.x -= lumaNw.w;
    dir.z += lumaNw.w;
/*--------------------------------------------------------------------------*/
    half4 lumaSe = FxaaTexTop(tex, posPos.zw);
    dir.x += lumaSe.w;
    dir.z -= lumaSe.w;
/*==========================================================================*/
    #if (FXAA_EARLY_EXIT == 1)
        half4 rgbyM = FxaaTexTop(tex, pos.xy);
/*--------------------------------------------------------------------------*/
        half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
        half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
/*--------------------------------------------------------------------------*/
        half lumaMinM = min(lumaMin, rgbyM.w);
        half lumaMaxM = max(lumaMax, rgbyM.w);
/*--------------------------------------------------------------------------*/
        if((lumaMaxM - lumaMinM) < max(EDGE_THRESHOLD_MIN, lumaMax * EDGE_THRESHOLD))
            #if (FXAA_DISCARD == 1)
                FxaaDiscard;
            #else
                return rgbyM;
            #endif
    #endif
/*==========================================================================*/
    half4 dir1_pos;
    dir1_pos.xy = normalize(dir.xyz).xz;
    half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(EDGE_SHARPNESS);
/*--------------------------------------------------------------------------*/
    half4 dir2_pos;
    dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
    dir1_pos.zw = pos.xy;
    dir2_pos.zw = pos.xy;
    half4 temp1N;
    temp1N.xy = dir1_pos.zw - dir1_pos.xy * rcpFrameOpt.zw;
/*--------------------------------------------------------------------------*/
    temp1N = FxaaTexTop(tex, temp1N.xy);
    half4 rgby1;
    rgby1.xy = dir1_pos.zw + dir1_pos.xy * rcpFrameOpt.zw;
/*--------------------------------------------------------------------------*/
    rgby1 = FxaaTexTop(tex, rgby1.xy);
    rgby1 = (temp1N + rgby1) * 0.5;
/*--------------------------------------------------------------------------*/
    half4 temp2N;
    temp2N.xy = dir2_pos.zw - dir2_pos.xy * rcpFrameOpt.xy;
    temp2N = FxaaTexTop(tex, temp2N.xy);
/*--------------------------------------------------------------------------*/
    half4 rgby2;
    rgby2.xy = dir2_pos.zw + dir2_pos.xy * rcpFrameOpt.xy;
    rgby2 = FxaaTexTop(tex, rgby2.xy);
    rgby2 = (temp2N + rgby2) * 0.5;
/*--------------------------------------------------------------------------*/
    #if (FXAA_EARLY_EXIT == 0)
        half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
        half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
    #endif
    rgby2 = (rgby2 + rgby1) * 0.5;
/*--------------------------------------------------------------------------*/
    bool twoTapLt = rgby2.w < lumaMin;
    bool twoTapGt = rgby2.w > lumaMax;
/*--------------------------------------------------------------------------*/
    if(twoTapLt || twoTapGt) rgby2 = rgby1;
/*--------------------------------------------------------------------------*/
    return rgby2; }
/*==========================================================================*/

float4 FxaaPixelShaderPC(
    // {xy} = center of pixel
    float2 pos,
    // {xyzw} = not used on FXAA3 Quality
    float4 posPos,       
    // {rgb_} = color in linear or perceptual color space
    // {___a} = luma in perceptual color space (not linear)
    FxaaTex tex,
    // This must be from a constant/uniform.
    // {x_} = 1.0/screenWidthInPixels
    // {_y} = 1.0/screenHeightInPixels
    float2 rcpFrame,
    // {xyzw} = not used on FXAA3 Quality
    float4 rcpFrameOpt
) {   
/*--------------------------------------------------------------------------*/
    float2 posM;
    posM.x = pos.x;
    posM.y = pos.y;
    #if (FXAA_GATHER4_ALPHA == 1)
        #if (FXAA_DISCARD == 0)
            float4 rgbyM = FxaaTexTop(tex, posM);
            #define lumaM rgbyM.w
        #endif           
        float4 luma4A = FxaaTexAlpha4(tex, posM, rcpFrame.xy);
        float4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1), rcpFrame.xy);
        #if (FXAA_DISCARD == 1)
            #define lumaM luma4A.w
        #endif
        #define lumaE luma4A.z
        #define lumaS luma4A.x
        #define lumaSE luma4A.y
        #define lumaNW luma4B.w
        #define lumaN luma4B.z
        #define lumaW luma4B.x
    #else
        float4 rgbyM = FxaaTexTop(tex, posM);
        #define lumaM rgbyM.w
        float lumaS = FxaaTexOff(tex, posM, FxaaInt2( 0, 1), rcpFrame.xy).w;
        float lumaE = FxaaTexOff(tex, posM, FxaaInt2( 1, 0), rcpFrame.xy).w;
        float lumaN = FxaaTexOff(tex, posM, FxaaInt2( 0,-1), rcpFrame.xy).w;
        float lumaW = FxaaTexOff(tex, posM, FxaaInt2(-1, 0), rcpFrame.xy).w;
    #endif
/*--------------------------------------------------------------------------*/
    float maxSM = max(lumaS, lumaM);
    float minSM = min(lumaS, lumaM);
    float maxESM = max(lumaE, maxSM);
    float minESM = min(lumaE, minSM);
    float maxWN = max(lumaN, lumaW);
    float minWN = min(lumaN, lumaW);
    float rangeMax = max(maxWN, maxESM);
    float rangeMin = min(minWN, minESM);
    float rangeMaxScaled = rangeMax * EDGE_THRESHOLD;
    float range = rangeMax - rangeMin;
    float rangeMaxClamped = max(EDGE_THRESHOLD_MIN, rangeMaxScaled);
    bool earlyExit = range < rangeMaxClamped;
/*--------------------------------------------------------------------------*/
    if(earlyExit)
        #if (FXAA_DISCARD == 1)
            FxaaDiscard;
        #else
            return rgbyM;
        #endif
/*--------------------------------------------------------------------------*/
    #if (FXAA_GATHER4_ALPHA == 0)
        float lumaNW = FxaaTexOff(tex, posM, FxaaInt2(-1,-1), rcpFrame.xy).w;
        float lumaSE = FxaaTexOff(tex, posM, FxaaInt2( 1, 1), rcpFrame.xy).w;
        float lumaNE = FxaaTexOff(tex, posM, FxaaInt2( 1,-1), rcpFrame.xy).w;
        float lumaSW = FxaaTexOff(tex, posM, FxaaInt2(-1, 1), rcpFrame.xy).w;
    #else
        float lumaNE = FxaaTexOff(tex, posM, FxaaInt2(1, -1), rcpFrame.xy).w;
        float lumaSW = FxaaTexOff(tex, posM, FxaaInt2(-1, 1), rcpFrame.xy).w;
    #endif
/*--------------------------------------------------------------------------*/
    float lumaNS = lumaN + lumaS;
    float lumaWE = lumaW + lumaE;
    float subpixRcpRange = 1.0/range;
    float subpixNSWE = lumaNS + lumaWE;
    float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
    float edgeVert1 = (-2.0 * lumaM) + lumaWE;
/*--------------------------------------------------------------------------*/
    float lumaNESE = lumaNE + lumaSE;
    float lumaNWNE = lumaNW + lumaNE;
    float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
    float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
/*--------------------------------------------------------------------------*/
    float lumaNWSW = lumaNW + lumaSW;
    float lumaSWSE = lumaSW + lumaSE;
    float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
    float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
    float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
    float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
    float edgeHorz = abs(edgeHorz3) + edgeHorz4;
    float edgeVert = abs(edgeVert3) + edgeVert4;
/*--------------------------------------------------------------------------*/
    float subpixNWSWNESE = lumaNWSW + lumaNESE;
    float lengthSign = rcpFrame.x;
    bool horzSpan = edgeHorz >= edgeVert;
    float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
/*--------------------------------------------------------------------------*/
    if(!horzSpan) lumaN = lumaW;
    if(!horzSpan) lumaS = lumaE;
    if(horzSpan) lengthSign = rcpFrame.y;
    float subpixB = (subpixA * (1.0/12.0)) - lumaM;
/*--------------------------------------------------------------------------*/
    float gradientN = lumaN - lumaM;
    float gradientS = lumaS - lumaM;
    float lumaNN = lumaN + lumaM;
    float lumaSS = lumaS + lumaM;
    bool pairN = abs(gradientN) >= abs(gradientS);
    float gradient = max(abs(gradientN), abs(gradientS));
    if(pairN) lengthSign = -lengthSign;
    float subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
/*--------------------------------------------------------------------------*/
    float2 posB;
    posB.x = posM.x;
    posB.y = posM.y;
    float2 offNP;
    offNP.x = (!horzSpan) ? 0.0 : rcpFrame.x;
    offNP.y = ( horzSpan) ? 0.0 : rcpFrame.y;
    if(!horzSpan) posB.x += lengthSign * 0.5;
    if( horzSpan) posB.y += lengthSign * 0.5;
/*--------------------------------------------------------------------------*/
    float2 posN;
    posN.x = posB.x - offNP.x;
    posN.y = posB.y - offNP.y;
    float2 posP;
    posP.x = posB.x + offNP.x;
    posP.y = posB.y + offNP.y;
    float subpixD = ((-2.0)*subpixC) + 3.0;
    float lumaEndN = FxaaTexTop(tex, posN).w;
    float subpixE = subpixC * subpixC;
    float lumaEndP = FxaaTexTop(tex, posP).w;
/*--------------------------------------------------------------------------*/
    if(!pairN) lumaNN = lumaSS;
    float gradientScaled = gradient * 1.0/4.0;
    float lumaMM = lumaM - lumaNN * 0.5;
    float subpixF = subpixD * subpixE;
    bool lumaMLTZero = lumaMM < 0.0;
/*--------------------------------------------------------------------------*/
    lumaEndN -= lumaNN * 0.5;
    lumaEndP -= lumaNN * 0.5;
    bool doneN = abs(lumaEndN) >= gradientScaled;
    bool doneP = abs(lumaEndP) >= gradientScaled;
    if(!doneN) posN.x -= offNP.x * 1.5;
    if(!doneN) posN.y -= offNP.y * 1.5;
    bool doneNP = (!doneN) || (!doneP);
    if(!doneP) posP.x += offNP.x * 1.5;
    if(!doneP) posP.y += offNP.y * 1.5;
    if(doneNP) {
/*--------------------------------------------------------------------------*/
        if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;
        if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;
        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
        doneN = abs(lumaEndN) >= gradientScaled;
        doneP = abs(lumaEndP) >= gradientScaled;
        if(!doneN) posN.x -= offNP.x * 2.0;
        if(!doneN) posN.y -= offNP.y * 2.0;
        doneNP = (!doneN) || (!doneP);
        if(!doneP) posP.x += offNP.x * 2.0;
        if(!doneP) posP.y += offNP.y * 2.0;
        if(doneNP) {
/*--------------------------------------------------------------------------*/
            if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;
            if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;
            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
            doneN = abs(lumaEndN) >= gradientScaled;
            doneP = abs(lumaEndP) >= gradientScaled;
            if(!doneN) posN.x -= offNP.x * 2.0;
            if(!doneN) posN.y -= offNP.y * 2.0;
            doneNP = (!doneN) || (!doneP);
            if(!doneP) posP.x += offNP.x * 2.0;
            if(!doneP) posP.y += offNP.y * 2.0;
            if(doneNP) {
/*--------------------------------------------------------------------------*/
                if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;
                if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;
                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
                doneN = abs(lumaEndN) >= gradientScaled;
                doneP = abs(lumaEndP) >= gradientScaled;
                if(!doneN) posN.x -= offNP.x * 4.0;
                if(!doneN) posN.y -= offNP.y * 4.0;
                doneNP = (!doneN) || (!doneP);
                if(!doneP) posP.x += offNP.x * 4.0;
                if(!doneP) posP.y += offNP.y * 4.0;
                if(doneNP) {
/*--------------------------------------------------------------------------*/
                    if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;
                    if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;
                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
                    doneN = abs(lumaEndN) >= gradientScaled;
                    doneP = abs(lumaEndP) >= gradientScaled;
                    if(!doneN) posN.x -= offNP.x * 2.0;
                    if(!doneN) posN.y -= offNP.y * 2.0;
                    if(!doneP) posP.x += offNP.x * 2.0;
                    if(!doneP) posP.y += offNP.y * 2.0; } } } }
/*--------------------------------------------------------------------------*/
    float dstN = posM.x - posN.x;
    float dstP = posP.x - posM.x;
    if(!horzSpan) dstN = posM.y - posN.y;
    if(!horzSpan) dstP = posP.y - posM.y;
/*--------------------------------------------------------------------------*/
    bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
    float spanLength = (dstP + dstN);
    bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
    float spanLengthRcp = 1.0/spanLength;
/*--------------------------------------------------------------------------*/
    bool directionN = dstN < dstP;
    float dst = min(dstN, dstP);
    bool goodSpan = directionN ? goodSpanN : goodSpanP;
    float subpixG = subpixF * subpixF;
    float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
    float subpixH = subpixG * SUBPIX_CAP;
/*--------------------------------------------------------------------------*/
    float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
    float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
    return FxaaTexTop(tex, posM); }
/*==========================================================================*/

uniform sampler2D tex0;
uniform int fxaa_preset;

varying vec2 v_rcpFrame;
varying vec4 v_rcpFrameOpt;
varying vec2 v_pos;
varying vec4 v_posPos;

void main() {
fxaa_choose_preset(fxaa_preset);
if (fxaa_preset < 4)
gl_FragColor = FxaaPixelShader(v_pos, v_posPos, tex0, v_rcpFrame, v_rcpFrameOpt);
else
gl_FragColor = FxaaPixelShaderPC(v_pos, v_posPos, tex0, v_rcpFrame, v_rcpFrameOpt);
}

Title: Re: FXAA in FSO
Post by: Cogitation on July 14, 2011, 01:38:36 pm
See, this is what I was trying to ask.  How can I try that shader, E?  Do I have to do a compile, or can I just copy that code to a file and stick it in the right directory?
Title: Re: FXAA in FSO
Post by: The E on July 14, 2011, 02:01:09 pm
Copy the code, save it as fxaa-f.sdr, and put that file in Freespace2/data/effects.
Title: Re: FXAA in FSO
Post by: Macfie on July 18, 2011, 07:25:38 pm
Tried V.3.9 it runs much faster than the one in the engine.  It runs without any framerate drop.  With the one in the engine I get a drop to as low as 30 fps for explosions and high light effects.  With 3.9 it is steady at 60 fps
Title: Re: FXAA in FSO
Post by: Kolgena on July 20, 2011, 01:40:19 am
Big problems with my install of this newest version of FXAA. I'll look into what I've probably screwed up before posting logs and screenshots.

In case anyone else gets this:

Using Valathil's beam lighting build, with the shaders posted above. None of the presets work to apply AA. Instead, for example on the Ulysses, I get weird texture artifacting that blinks in time to the flashing glow points. It looks like streaks of ship texture. AF is forced in the control panel, and it's not due to overclocking.
Title: Re: FXAA in FSO
Post by: The E on July 20, 2011, 03:34:41 am
Please post a log.
Title: Re: FXAA in FSO
Post by: Kolgena on July 20, 2011, 10:46:24 am
Hmm. Valathil's build doesn't come with a debug build, so I'll use the latest nightly instead.

Also had to reinstall photoshop, since I couldn't open TGA. Anyways, I should be able to get something up this evening.
Title: Re: FXAA in FSO
Post by: The E on July 20, 2011, 10:52:59 am
Why use photoshop when something much more lightweight (like, for example, irfanview) would suffice?

Also, if you can't get a debug log out of valathils' builds, use a nightly.
Title: Re: FXAA in FSO
Post by: Kolgena on July 20, 2011, 11:04:19 am
Yes, I did say that I was going to use a nightly. I'll also check if the same artifacting happens on a nightly as well.

I use PS for a bunch of things, and I had it lying around with CS4. Since I just did a clean install, it was more that I was missing everything, rather than needing to grab photoshop just to read .tga.
Title: Re: FXAA in FSO
Post by: The E on July 21, 2011, 08:10:00 am
FXAA version 3.10 has been released. (http://timothylottes.blogspot.com/2011/07/fxaa-310-released.html)

It has been integrated into FSO already, and will be in the next (7366++) nightly. One thing to note is that due to necessary changes, you absolutely HAVE to delete all previous fxaa shaders, as they are incompatible with the new way of using fxaa.
Title: Re: FXAA in FSO
Post by: Kolgena on July 21, 2011, 11:02:35 am
Since we've changed FXAA versions, it is temporarily impossible (for me) to get a build with FXAA 3.10 and Valathil's beam lighting at the same time.

I'll worry about troubleshooting this if at some point it becomes possible to get both together. Sound okay?

Edit: Wait, is Valathil's beam code in the nightlies already? (7367) Anyways, I used 7367 and Valathil's posted main-f.sdr from his beam lighting release thread, and I don't get problems.
Title: Re: FXAA in FSO
Post by: Kolgena on July 22, 2011, 03:11:09 pm
The newest iteration of the shader fails to compile using catalyst 10.7.

Code: [Select]
==========================================================================
DEBUG SPEW: No debug_filter.cfg found, so only general, error, and warning
categories can be shown and no debug_filter.cfg info will be saved.
==========================================================================
FreeSpace version: 3.6.13
Passed cmdline options:
  -spec_exp 4
  -fov .6
  -ogl_spec 90
  -spec_static 2.3
  -spec_point 0.85
  -spec_tube 1.2
  -ambient_factor 80
  -env
  -missile_lighting
  -glow
  -nomotiondebris
  -spec
  -normal
  -post_process
  -bloom_intensity 80
  -fxaa
  -fxaa_preset 1
  -cache_bitmaps
  -no_vsync
  -orbradar
  -3dwarp
  -ship_choice_3d
  -warp_flash
  -snd_preload
  -mod blueplanet2,blueplanet,mediavps_3612
Building file index...
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-adv-visuals.vp' with a checksum of 0x2fa0cebd
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-audio1.vp' with a checksum of 0x60465ead
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-core.vp' with a checksum of 0x24b50f90
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals1.vp' with a checksum of 0x5d4c1bfb
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals2.vp' with a checksum of 0x8fea63ef
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-adv-visuals.vp' with a checksum of 0x1541da12
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio1.vp' with a checksum of 0xcc452f9d
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio2.vp' with a checksum of 0x060bee91
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-core.vp' with a checksum of 0xe2219ccf
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals1.vp' with a checksum of 0x7e75407b
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals2.vp' with a checksum of 0x44c7e8dd
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Advanced.vp' with a checksum of 0x4b8b0f5a
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_AnimGlows.vp' with a checksum of 0x6a554026
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.3612.vp' with a checksum of 0x59649c21
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.vp' with a checksum of 0x529cc70f
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_1.vp' with a checksum of 0x6b831455
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_2.vp' with a checksum of 0xd1e3fc51
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.3612.vp' with a checksum of 0x9c510aa0
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.vp' with a checksum of 0xb9a9a485
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Music.vp' with a checksum of 0xb3e21469
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.3612.vp' with a checksum of 0x7c9d7e74
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.vp' with a checksum of 0x6ffd5c78
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\SathMod.vp' with a checksum of 0x42fb4bfa
Found root pack 'C:\Program Files (x86)\Freespace\FS2OGGcutscenepack.vp' with a checksum of 0x84396e99
Found root pack 'C:\Program Files (x86)\Freespace\multi-mission-pack.vp' with a checksum of 0x377695e0
Found root pack 'C:\Program Files (x86)\Freespace\multi-voice-pack.vp' with a checksum of 0xd50e7442
Found root pack 'C:\Program Files (x86)\Freespace\root_fs2.vp' with a checksum of 0xce10d76c
Found root pack 'C:\Program Files (x86)\Freespace\smarty_fs2.vp' with a checksum of 0xddeb3b1e
Found root pack 'C:\Program Files (x86)\Freespace\sparky_fs2.vp' with a checksum of 0x164fe65a
Found root pack 'C:\Program Files (x86)\Freespace\sparky_hi_fs2.vp' with a checksum of 0xa11d56f1
Found root pack 'C:\Program Files (x86)\Freespace\stu_fs2.vp' with a checksum of 0xd77da83a
Found root pack 'C:\Program Files (x86)\Freespace\tango1_fs2.vp' with a checksum of 0x4c25221e
Found root pack 'C:\Program Files (x86)\Freespace\tango2_fs2.vp' with a checksum of 0x86920b82
Found root pack 'C:\Program Files (x86)\Freespace\tango3_fs2.vp' with a checksum of 0x705e8d71
Found root pack 'C:\Program Files (x86)\Freespace\warble_fs2.vp' with a checksum of 0xd85c305d
Searching root 'C:\Program Files (x86)\Freespace\blueplanet2\' ... 95 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-adv-visuals.vp' ... 23 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-audio1.vp' ... 154 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-core.vp' ... 61 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals1.vp' ... 494 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals2.vp' ... 1976 files
Searching root 'C:\Program Files (x86)\Freespace\blueplanet\' ... 2 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-adv-visuals.vp' ... 403 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio1.vp' ... 41 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio2.vp' ... 685 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-core.vp' ... 46 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals1.vp' ... 326 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals2.vp' ... 1488 files
Searching root 'C:\Program Files (x86)\Freespace\mediavps_3612\' ... 119 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Advanced.vp' ... 1283 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_AnimGlows.vp' ... 1641 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.3612.vp' ... 315 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.vp' ... 1527 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_1.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_2.vp' ... 52 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.3612.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.vp' ... 1876 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Music.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.3612.vp' ... 13 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.vp' ... 94 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\SathMod.vp' ... 15 files
Searching root 'C:\Program Files (x86)\Freespace\' ... 26 files
Searching root pack 'C:\Program Files (x86)\Freespace\FS2OGGcutscenepack.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\multi-mission-pack.vp' ... 110 files
Searching root pack 'C:\Program Files (x86)\Freespace\multi-voice-pack.vp' ... 307 files
Searching root pack 'C:\Program Files (x86)\Freespace\root_fs2.vp' ... 157 files
Searching root pack 'C:\Program Files (x86)\Freespace\smarty_fs2.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\sparky_fs2.vp' ... 3027 files
Searching root pack 'C:\Program Files (x86)\Freespace\sparky_hi_fs2.vp' ... 1337 files
Searching root pack 'C:\Program Files (x86)\Freespace\stu_fs2.vp' ... 2355 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango1_fs2.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango2_fs2.vp' ... 15 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango3_fs2.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\warble_fs2.vp' ... 52 files
Found 39 roots and 20251 files.
AutoLang: Language auto-detection successful...
Setting language to English
TBM  =>  Starting parse of 'mv_core-lcl.tbm' ...
Initializing OpenAL...
  OpenAL Vendor     : Creative Labs Inc.
  OpenAL Renderer   : Software
  OpenAL Version    : 1.1

  Found extension "ALC_EXT_EFX".

  Sample rate: 44100 (44100)
  EFX version: 1.0
  Max auxiliary sends: 1
  Playback device: Generic Software on Speaker/HP (Realtek High Definition Audio)
  Capture device: Microphone (Realtek High Defini
... OpenAL successfully initialized!
Failed to init speech
Initializing OpenGL graphics device at 1680x945 with 32-bit color...
  Initializing WGL...
  Requested WGL Video values = R: 8, G: 8, B: 8, depth: 32, double-buffer: 1
  Actual WGL Video values    = R: 8, G: 8, B: 8, depth: 32, double-buffer: 1
  OpenGL Vendor    : ATI Technologies Inc.
  OpenGL Renderer  : ATI Mobility Radeon HD 3650
  OpenGL Version   : 3.3.10148 Compatibility Profile Context

  Using extension "GL_EXT_fog_coord".
  Using extension "GL_ARB_multitexture".
  Using extension "GL_ARB_texture_env_add".
  Using extension "GL_ARB_texture_compression".
  Using extension "GL_EXT_texture_compression_s3tc".
  Using extension "GL_EXT_texture_filter_anisotropic".
  Using extension "GL_ARB_texture_env_combine".
  Using extension "GL_EXT_compiled_vertex_array".
  Using extension "GL_EXT_draw_range_elements".
  Using extension "GL_ARB_texture_mirrored_repeat".
  Using extension "GL_ARB_texture_non_power_of_two".
  Using extension "GL_ARB_vertex_buffer_object".
  Using extension "GL_ARB_pixel_buffer_object".
  Using extension "GL_SGIS_generate_mipmap".
  Using extension "GL_EXT_framebuffer_object".
  Using extension "GL_ARB_texture_rectangle".
  Using extension "GL_EXT_bgra".
  Using extension "GL_ARB_texture_cube_map".
  Using extension "GL_EXT_texture_lod_bias".
  Using extension "GL_ARB_point_sprite".
  Using extension "GL_ARB_shading_language_100".
  Using extension "GL_ARB_shader_objects".
  Using extension "GL_ARB_vertex_shader".
  Using extension "GL_ARB_fragment_shader".
  Using extension "GL_ARB_shader_texture_lod".
  Found special extension function "wglSwapIntervalEXT".

  Compiling shader: main-v.sdr (null-v.sdr), main-f.sdr (null-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lb-f.sdr)
  Compiling shader: main-v.sdr (b-v.sdr), main-f.sdr (b-f.sdr)
  Compiling shader: main-v.sdr (b-v.sdr), main-f.sdr (bg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbgs-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbs-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lbgse-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lbse-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbgn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbgsn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbsn-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lbgsne-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lbsne-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfb-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbg-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbgs-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbs-f.sdr)
  Compiling shader: main-v.sdr (lfe-v.sdr), main-f.sdr (lfbgse-f.sdr)
  Compiling shader: main-v.sdr (lfe-v.sdr), main-f.sdr (lfbse-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbgn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbgsn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbsn-f.sdr)
  Compiling shader: main-v.sdr (lfne-v.sdr), main-f.sdr (lfbgsne-f.sdr)
  Compiling shader: main-v.sdr (lfne-v.sdr), main-f.sdr (lfbsne-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (null-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lgs-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (ls-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lgse-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lse-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lgn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lgsn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (ln-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lsn-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lgsne-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lsne-f.sdr)

  Compiling post-processing shader 1 ...
  Compiling post-processing shader 2 ...
  Compiling post-processing shader 3 ...
  Compiling post-processing shader 4 ...
  Compiling post-processing shader 5 ...
Loading built-in default shader for: fxaa-v.sdr
Loading built-in default shader for: fxaa-f.sdr
Fragment shader failed to compile:
Fragment shader failed to compile with the following errors:
ERROR: 0:44: error(#71) Syntax error incorrect preprocessor directive
WARNING: 0:44: warning(#64) Unexpected tokens following the preprocessor directive - expected a newline(#if )
ERROR: 0:51: error(#71) Syntax error incorrect preprocessor directive
WARNING: 0:51: warning(#64) Unexpected tokens following the preprocessor directive - expected a newline(#if )
ERROR: 0:52: error(#101) Macro redefined FXAA_QUALITY__ERROR! Unable to create fragment shader!
Error while compiling FXAA shaders. FXAA will be unavailable.
  Compiling post-processing shader 6 ...
Loading built-in default shader for: fxaapre-f.sdr

  Max texture units: 8 (16)
  Max elements vertices: 2147483647
  Max elements indices: 16777215
  Max texture size: 8192x8192
  Max render buffer size: 8192x8192
  Can use compressed textures: YES
  Texture compression available: YES
  Post-processing enabled: YES
  Using trilinear texture filter.
  Using GLSL for model rendering.
  OpenGL Shader Version: 3.30
... OpenGL init is complete!
Size of bitmap info = 760 KB
Size of bitmap extra info = 52 bytes
ANI cursorweb with size 24x24 (25.0% wasted)
GRAPHICS: Initializing default colors...
SCRIPTING: Beginning initialization sequence...
SCRIPTING: Beginning Lua initialization...
LUA: Opening LUA state...
LUA: Initializing base Lua libraries...
LUA: Beginning ADE initialization
ADE: Initializing enumeration constants...
ADE: Assigning Lua session...
SCRIPTING: Beginning main hook parse sequence....
Wokka!  Error opening file (scripting.tbl)!
TABLES: Unable to parse 'scripting.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_flak-sct.tbm' ...
TBM  =>  Starting parse of 'mv_dbrs-sct.tbm' ...
TBM  =>  Starting parse of 'mv_exp-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-tcard-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-stupid-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-csc-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-betty-sct.tbm' ...
SCRIPTING: Inititialization complete.
SCRIPTING: Splash screen overrides checked
SCRIPTING: Splash hook has been run
SCRIPTING: Splash screen conditional hook has been run
Using high memory settings...
Wokka!  Error opening file (interface.tbl)!
WMCGUI: Unable to parse 'interface.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_effects-sdf.tbm' ...
TBM  =>  Starting parse of 'bp-sdf.tbm' ...
Windows reported 16 joysticks, we found 0
Current soundtrack set to -1 in event_music_reset_choices
TBM  =>  Starting parse of 'mv_music-mus.tbm' ...
TBM  =>  Starting parse of 'bp-mus.tbm' ...
TBM  =>  Starting parse of 'bp2-mus.tbm' ...
TBM  =>  Starting parse of 'mv_effects-mfl.tbm' ...
TBM  =>  Starting parse of 'bp-mfl.tbm' ...
TBM  =>  Starting parse of 'bp2-mfl.tbm' ...
Wokka!  Error opening file (armor.tbl)!
TABLES: Unable to parse 'armor.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_effects-amr.tbm' ...
TBM  =>  Starting parse of 'bp2-amr.tbm' ...
TBM  =>  Starting parse of 'mv_effects-wxp.tbm' ...
TBM  =>  Starting parse of 'bp-wxp.tbm' ...
BMPMAN: Found EFF (exp20.eff) with 75 frames at 20 fps.
BMPMAN: Found EFF (ExpMissileHit1.eff) with 92 frames at 20 fps.
BMPMAN: Found EFF (exp04.eff) with 49 frames at 22 fps.
BMPMAN: Found EFF (exp05.eff) with 93 frames at 20 fps.
BMPMAN: Found EFF (exp06.eff) with 92 frames at 22 fps.
BMPMAN: Found EFF (capflash.eff) with 40 frames at 10 fps.
BMPMAN: Found EFF (Maxim_Impact.eff) with 23 frames at 30 fps.
ANI Lamprey_Impact with size 80x80 (37.5% wasted)
BMPMAN: Found EFF (explo3.eff) with 48 frames at 22 fps.
BMPMAN: Found EFF (HFlakExp.eff) with 48 frames at 22 fps.
BMPMAN: Found EFF (exp06b.eff) with 92 frames at 22 fps.
BMPMAN: Found EFF (bomb_flare.eff) with 69 frames at 20 fps.
TBM  =>  Starting parse of 'mv_core-wep.tbm' ...
TBM  =>  Starting parse of 'mv_effects-wep.tbm' ...
TBM  =>  Starting parse of 'mv_assets-wep.tbm' ...
TBM  =>  Starting parse of 'bp-wep.tbm' ...
TBM  =>  Starting parse of 'bp2-wep.tbm' ...
Weapon 'Hornet#Weak' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Harpoon#Weak' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Hornet#Weak#Shivan' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Harpoon#Weak#Shivan' requires the "player allowed" flag, but it's not listed!  Adding it by default.
WARNING: Unrecognized parameter in ai_profiles: $disarm or disable cause global ai goal effects: YES

TBM  =>  Starting parse of 'bp-aip.tbm' ...
TBM  =>  Starting parse of 'bp2-aip.tbm' ...
TBM  =>  Starting parse of 'mv_effects-obt.tbm' ...
TBM  =>  Starting parse of 'bp2-obt.tbm' ...
TBM  =>  Starting parse of 'Sath-shp.tbm' ...
TBM  =>  Starting parse of 'mv_core-shp.tbm' ...
TBM  =>  Starting parse of 'mv_effects-shp.tbm' ...
TBM  =>  Starting parse of 'mv_assets-shp.tbm' ...
TBM  =>  Starting parse of 'radar-shp.tbm' ...
TBM  =>  Starting parse of 'boa-shp.tbm' ...
TBM  =>  Starting parse of 'artemistest-shp.tbm' ...
TBM  =>  Starting parse of 'bp-shp.tbm' ...
TBM  =>  Starting parse of 'bp2-shp.tbm' ...
Particle effect for impact spew disabled on ship 'Moon Landscape'.
Particle effect for damage spew disabled on ship 'Moon Landscape'.
TBM  =>  Starting parse of 'bp2-radaricons-shp.tbm' ...
ANI support1 with size 108x24 (25.0% wasted)
ANI damage1 with size 148x25 (21.9% wasted)
ANI wingman1 with size 71x53 (17.2% wasted)
ANI wingman2 with size 35x53 (17.2% wasted)
ANI wingman3 with size 14x53 (17.2% wasted)
ANI toggle1 with size 57x20 (37.5% wasted)
ANI head1 with size 164x132 (48.4% wasted)
ANI weapons1 with size 126x20 (37.5% wasted)
ANI weapons1_b with size 150x20 (37.5% wasted)
ANI objective1 with size 149x21 (34.4% wasted)
ANI energy1 with size 12x41 (35.9% wasted)
ANI targetview1 with size 137x156 (39.1% wasted)
ANI targetview2 with size 4x96 (25.0% wasted)
ANI targetview3 with size 7x20 (37.5% wasted)
ANI 2_radar1 with size 209x170 (33.6% wasted)
ANI 2_energy2 with size 86x96 (25.0% wasted)
ANI 2_reticle1 with size 40x24 (25.0% wasted)
ANI targhit1 with size 31x21 (34.4% wasted)
ANI 2_leftarc with size 103x252 (1.6% wasted)
ANI 2_rightarc1 with size 103x252 (1.6% wasted)
ANI 2_toparc2 with size 35x24 (25.0% wasted)
ANI 2_toparc3 with size 41x29 (9.4% wasted)
ANI netlag1 with size 29x30 (6.3% wasted)
ANI 2_lead1 with size 26x26 (18.8% wasted)
ANI 2_lock1 with size 56x53 (17.2% wasted)
ANI 2_lockspin with size 100x100 (21.9% wasted)
ANI time1 with size 47x23 (28.1% wasted)
TBM  =>  Starting parse of 'mv_core-hdg.tbm' ...
TBM  =>  Starting parse of 'mv_effects-str.tbm' ...
TBM  =>  Starting parse of 'bp-str.tbm' ...
TBM  =>  Starting parse of 'bp2-str.tbm' ...
loading animated cursor "cursor"
MediaVPs: Flaming debris script loaded!
MediaVPs: Explosions script loaded!
Ships.tbl is : VALID
Weapons.tbl is : VALID
cfile_init() took 1358
Got event GS_EVENT_GAME_INIT (49) in state NOT A VALID STATE (0)
Got event GS_EVENT_MAIN_MENU (0) in state GS_STATE_INITIAL_PLAYER_SELECT (37)
Someone passed an extension to bm_load for file 'hammer1.pcx'
WARNING!, Could not load door anim 2_Exit in main hall
WARNING!, Could not load door anim 2_Pilot in main hall
WARNING!, Could not load door anim 2_Continue in main hall
WARNING!, Could not load door anim 2_Tech in main hall
WARNING!, Could not load door anim 2_Option in main hall
WARNING!, Could not load door anim 2_Campaign in main hall
Frame  0 too long!!: frametime = 0.279 (0.279)
Got event GS_EVENT_LAB (64) in state GS_STATE_MAIN_MENU (1)
Loading model 'fighter2t-04.pof'
IBX: Found a good IBX to read for 'fighter2t-04.pof'.
IBX-DEBUG => POF checksum: 0xe611ce17, IBX checksum: 0x97cf5fc2 -- "fighter2t-04.pof"
Frame  0 too long!!: frametime = 0.595 (0.595)
Frame  1 too long!!: frametime = 0.307 (0.307)
Loading model 'asteroid01.pof'
IBX: Found a good IBX to read for 'asteroid01.pof'.
IBX-DEBUG => POF checksum: 0x68da3c4f, IBX checksum: 0x9812c450 -- "asteroid01.pof"
Submodel 'asteroid02b' is detail level 1 of 'asteroid02a'
Submodel 'asteroid02c' is detail level 2 of 'asteroid02a'
Loading model 'escapepod01.pof'
IBX: Found a good IBX to read for 'escapepod01.pof'.
IBX-DEBUG => POF checksum: 0x43783a23, IBX checksum: 0xadea2ade -- "escapepod01.pof"
Submodel 'flightpod01b' is detail level 1 of 'flightpod01a'
Submodel 'flightpod01c' is detail level 2 of 'flightpod01a'
Submodel 'flightpod01d' is detail level 3 of 'flightpod01a'
Loading model 'NavajoHTL.pof'
IBX: Starting a new IBX for 'NavajoHTL.pof'.
Frame 12673 too long!!: frametime = 15.852 (15.852)
Loading model 'capital03.pof'
Potential problem found: Unrecognized subsystem type 'fighterbay 1', believed to be in ship capital03.pof
Potential problem found: Unrecognized subsystem type 'fighterbay 2', believed to be in ship capital03.pof
IBX: Found a good IBX to read for 'capital03.pof'.
IBX-DEBUG => POF checksum: 0x0865f9b4, IBX checksum: 0x1d5cbdd6 -- "capital03.pof"
Submodel 'capital03b-hull' is detail level 1 of 'capital03a-hull'
Submodel 'capital03c-hull' is detail level 2 of 'capital03a-hull'
Submodel 'capital03d-hull' is detail level 3 of 'capital03a-hull'
Frame 16052 too long!!: frametime = 0.577 (0.577)
Got event GS_EVENT_QUIT_GAME (5) in state GS_STATE_LAB (50)
SOUND: c:\code\fs2_open_0\code\sound\ds.cpp:1273 - OpenAL error = 'Invalid Operation'
Freeing all existing models...
... Log closed, Fri Jul 22 15:07:30 2011
Title: Re: FXAA in FSO
Post by: The E on July 22, 2011, 03:33:35 pm
Please try this build (http://blueplanet.fsmods.net/E/stuff/fs2_open_3_6_13d_INF_SSE2.7z).
Title: Re: FXAA in FSO
Post by: Kolgena on July 22, 2011, 03:51:49 pm
Works now.

Code: [Select]
==========================================================================
DEBUG SPEW: No debug_filter.cfg found, so only general, error, and warning
categories can be shown and no debug_filter.cfg info will be saved.
==========================================================================
FreeSpace version: 3.6.13
Passed cmdline options:
  -spec_exp 4
  -fov .6
  -ogl_spec 90
  -spec_static 2.3
  -spec_point 0.85
  -spec_tube 1.2
  -ambient_factor 80
  -env
  -missile_lighting
  -glow
  -nomotiondebris
  -spec
  -normal
  -post_process
  -bloom_intensity 80
  -fxaa
  -fxaa_preset 1
  -cache_bitmaps
  -no_vsync
  -orbradar
  -3dwarp
  -ship_choice_3d
  -warp_flash
  -snd_preload
  -mod blueplanet2,blueplanet,mediavps_3612
Building file index...
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-adv-visuals.vp' with a checksum of 0x2fa0cebd
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-audio1.vp' with a checksum of 0x60465ead
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-core.vp' with a checksum of 0x24b50f90
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals1.vp' with a checksum of 0x5d4c1bfb
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals2.vp' with a checksum of 0x8fea63ef
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-adv-visuals.vp' with a checksum of 0x1541da12
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio1.vp' with a checksum of 0xcc452f9d
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio2.vp' with a checksum of 0x060bee91
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-core.vp' with a checksum of 0xe2219ccf
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals1.vp' with a checksum of 0x7e75407b
Found root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals2.vp' with a checksum of 0x44c7e8dd
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Advanced.vp' with a checksum of 0x4b8b0f5a
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_AnimGlows.vp' with a checksum of 0x6a554026
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.3612.vp' with a checksum of 0x59649c21
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.vp' with a checksum of 0x529cc70f
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_1.vp' with a checksum of 0x6b831455
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_2.vp' with a checksum of 0xd1e3fc51
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.3612.vp' with a checksum of 0x9c510aa0
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.vp' with a checksum of 0xb9a9a485
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Music.vp' with a checksum of 0xb3e21469
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.3612.vp' with a checksum of 0x7c9d7e74
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.vp' with a checksum of 0x6ffd5c78
Found root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\SathMod.vp' with a checksum of 0x42fb4bfa
Found root pack 'C:\Program Files (x86)\Freespace\FS2OGGcutscenepack.vp' with a checksum of 0x84396e99
Found root pack 'C:\Program Files (x86)\Freespace\multi-mission-pack.vp' with a checksum of 0x377695e0
Found root pack 'C:\Program Files (x86)\Freespace\multi-voice-pack.vp' with a checksum of 0xd50e7442
Found root pack 'C:\Program Files (x86)\Freespace\root_fs2.vp' with a checksum of 0xce10d76c
Found root pack 'C:\Program Files (x86)\Freespace\smarty_fs2.vp' with a checksum of 0xddeb3b1e
Found root pack 'C:\Program Files (x86)\Freespace\sparky_fs2.vp' with a checksum of 0x164fe65a
Found root pack 'C:\Program Files (x86)\Freespace\sparky_hi_fs2.vp' with a checksum of 0xa11d56f1
Found root pack 'C:\Program Files (x86)\Freespace\stu_fs2.vp' with a checksum of 0xd77da83a
Found root pack 'C:\Program Files (x86)\Freespace\tango1_fs2.vp' with a checksum of 0x4c25221e
Found root pack 'C:\Program Files (x86)\Freespace\tango2_fs2.vp' with a checksum of 0x86920b82
Found root pack 'C:\Program Files (x86)\Freespace\tango3_fs2.vp' with a checksum of 0x705e8d71
Found root pack 'C:\Program Files (x86)\Freespace\warble_fs2.vp' with a checksum of 0xd85c305d
Searching root 'C:\Program Files (x86)\Freespace\blueplanet2\' ... 96 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-adv-visuals.vp' ... 23 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-audio1.vp' ... 154 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-core.vp' ... 61 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals1.vp' ... 494 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet2\bp2-visuals2.vp' ... 1976 files
Searching root 'C:\Program Files (x86)\Freespace\blueplanet\' ... 2 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-adv-visuals.vp' ... 403 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio1.vp' ... 41 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-audio2.vp' ... 685 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-core.vp' ... 46 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals1.vp' ... 326 files
Searching root pack 'C:\Program Files (x86)\Freespace\blueplanet\bp-visuals2.vp' ... 1488 files
Searching root 'C:\Program Files (x86)\Freespace\mediavps_3612\' ... 119 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Advanced.vp' ... 1283 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_AnimGlows.vp' ... 1641 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.3612.vp' ... 315 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Assets.vp' ... 1527 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_1.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_CB_ANI_2.vp' ... 52 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.3612.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Effects.vp' ... 1876 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Music.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.3612.vp' ... 13 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\MV_Root.vp' ... 94 files
Searching root pack 'C:\Program Files (x86)\Freespace\mediavps_3612\SathMod.vp' ... 15 files
Searching root 'C:\Program Files (x86)\Freespace\' ... 26 files
Searching root pack 'C:\Program Files (x86)\Freespace\FS2OGGcutscenepack.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\multi-mission-pack.vp' ... 110 files
Searching root pack 'C:\Program Files (x86)\Freespace\multi-voice-pack.vp' ... 307 files
Searching root pack 'C:\Program Files (x86)\Freespace\root_fs2.vp' ... 157 files
Searching root pack 'C:\Program Files (x86)\Freespace\smarty_fs2.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\sparky_fs2.vp' ... 3027 files
Searching root pack 'C:\Program Files (x86)\Freespace\sparky_hi_fs2.vp' ... 1337 files
Searching root pack 'C:\Program Files (x86)\Freespace\stu_fs2.vp' ... 2355 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango1_fs2.vp' ... 32 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango2_fs2.vp' ... 15 files
Searching root pack 'C:\Program Files (x86)\Freespace\tango3_fs2.vp' ... 10 files
Searching root pack 'C:\Program Files (x86)\Freespace\warble_fs2.vp' ... 52 files
Found 39 roots and 20252 files.
AutoLang: Language auto-detection successful...
Setting language to English
TBM  =>  Starting parse of 'mv_core-lcl.tbm' ...
Initializing OpenAL...
  OpenAL Vendor     : Creative Labs Inc.
  OpenAL Renderer   : Software
  OpenAL Version    : 1.1

  Found extension "ALC_EXT_EFX".

  Sample rate: 44100 (44100)
  EFX version: 1.0
  Max auxiliary sends: 1
  Playback device: Generic Software on Speaker/HP (Realtek High Definition Audio)
  Capture device: Microphone (Realtek High Defini
... OpenAL successfully initialized!
Failed to init speech
Initializing OpenGL graphics device at 1680x945 with 32-bit color...
  Initializing WGL...
  Requested WGL Video values = R: 8, G: 8, B: 8, depth: 32, double-buffer: 1
  Actual WGL Video values    = R: 8, G: 8, B: 8, depth: 32, double-buffer: 1
  OpenGL Vendor    : ATI Technologies Inc.
  OpenGL Renderer  : ATI Mobility Radeon HD 3650
  OpenGL Version   : 3.3.10148 Compatibility Profile Context

  Using extension "GL_EXT_fog_coord".
  Using extension "GL_ARB_multitexture".
  Using extension "GL_ARB_texture_env_add".
  Using extension "GL_ARB_texture_compression".
  Using extension "GL_EXT_texture_compression_s3tc".
  Using extension "GL_EXT_texture_filter_anisotropic".
  Using extension "GL_ARB_texture_env_combine".
  Using extension "GL_EXT_compiled_vertex_array".
  Using extension "GL_EXT_draw_range_elements".
  Using extension "GL_ARB_texture_mirrored_repeat".
  Using extension "GL_ARB_texture_non_power_of_two".
  Using extension "GL_ARB_vertex_buffer_object".
  Using extension "GL_ARB_pixel_buffer_object".
  Using extension "GL_SGIS_generate_mipmap".
  Using extension "GL_EXT_framebuffer_object".
  Using extension "GL_ARB_texture_rectangle".
  Using extension "GL_EXT_bgra".
  Using extension "GL_ARB_texture_cube_map".
  Using extension "GL_EXT_texture_lod_bias".
  Using extension "GL_ARB_point_sprite".
  Using extension "GL_ARB_shading_language_100".
  Using extension "GL_ARB_shader_objects".
  Using extension "GL_ARB_vertex_shader".
  Using extension "GL_ARB_fragment_shader".
  Using extension "GL_ARB_shader_texture_lod".
  Found special extension function "wglSwapIntervalEXT".

  Compiling shader: main-v.sdr (null-v.sdr), main-f.sdr (null-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lb-f.sdr)
  Compiling shader: main-v.sdr (b-v.sdr), main-f.sdr (b-f.sdr)
  Compiling shader: main-v.sdr (b-v.sdr), main-f.sdr (bg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbgs-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lbs-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lbgse-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lbse-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbgn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbgsn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lbsn-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lbgsne-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lbsne-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfb-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbg-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbgs-f.sdr)
  Compiling shader: main-v.sdr (lf-v.sdr), main-f.sdr (lfbs-f.sdr)
  Compiling shader: main-v.sdr (lfe-v.sdr), main-f.sdr (lfbgse-f.sdr)
  Compiling shader: main-v.sdr (lfe-v.sdr), main-f.sdr (lfbse-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbgn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbgsn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbn-f.sdr)
  Compiling shader: main-v.sdr (lfn-v.sdr), main-f.sdr (lfbsn-f.sdr)
  Compiling shader: main-v.sdr (lfne-v.sdr), main-f.sdr (lfbgsne-f.sdr)
  Compiling shader: main-v.sdr (lfne-v.sdr), main-f.sdr (lfbsne-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (null-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lg-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (lgs-f.sdr)
  Compiling shader: main-v.sdr (l-v.sdr), main-f.sdr (ls-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lgse-f.sdr)
  Compiling shader: main-v.sdr (le-v.sdr), main-f.sdr (lse-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lgn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lgsn-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (ln-f.sdr)
  Compiling shader: main-v.sdr (ln-v.sdr), main-f.sdr (lsn-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lgsne-f.sdr)
  Compiling shader: main-v.sdr (lne-v.sdr), main-f.sdr (lsne-f.sdr)

  Compiling post-processing shader 1 ...
  Compiling post-processing shader 2 ...
  Compiling post-processing shader 3 ...
  Compiling post-processing shader 4 ...
  Compiling post-processing shader 5 ...
Loading built-in default shader for: fxaa-v.sdr
Loading built-in default shader for: fxaa-f.sdr
  Compiling post-processing shader 6 ...
Loading built-in default shader for: fxaapre-f.sdr

  Max texture units: 8 (16)
  Max elements vertices: 2147483647
  Max elements indices: 16777215
  Max texture size: 8192x8192
  Max render buffer size: 8192x8192
  Can use compressed textures: YES
  Texture compression available: YES
  Post-processing enabled: YES
  Using trilinear texture filter.
  Using GLSL for model rendering.
  OpenGL Shader Version: 3.30
... OpenGL init is complete!
Size of bitmap info = 760 KB
Size of bitmap extra info = 52 bytes
ANI cursorweb with size 24x24 (25.0% wasted)
GRAPHICS: Initializing default colors...
SCRIPTING: Beginning initialization sequence...
SCRIPTING: Beginning Lua initialization...
LUA: Opening LUA state...
LUA: Initializing base Lua libraries...
LUA: Beginning ADE initialization
ADE: Initializing enumeration constants...
ADE: Assigning Lua session...
SCRIPTING: Beginning main hook parse sequence....
Wokka!  Error opening file (scripting.tbl)!
TABLES: Unable to parse 'scripting.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_flak-sct.tbm' ...
TBM  =>  Starting parse of 'mv_dbrs-sct.tbm' ...
TBM  =>  Starting parse of 'mv_exp-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-tcard-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-stupid-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-csc-sct.tbm' ...
TBM  =>  Starting parse of 'bp2-betty-sct.tbm' ...
SCRIPTING: Inititialization complete.
SCRIPTING: Splash screen overrides checked
SCRIPTING: Splash hook has been run
SCRIPTING: Splash screen conditional hook has been run
Using high memory settings...
Wokka!  Error opening file (interface.tbl)!
WMCGUI: Unable to parse 'interface.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_effects-sdf.tbm' ...
TBM  =>  Starting parse of 'bp-sdf.tbm' ...
Windows reported 16 joysticks, we found 0
Current soundtrack set to -1 in event_music_reset_choices
TBM  =>  Starting parse of 'mv_music-mus.tbm' ...
TBM  =>  Starting parse of 'bp-mus.tbm' ...
TBM  =>  Starting parse of 'bp2-mus.tbm' ...
TBM  =>  Starting parse of 'mv_effects-mfl.tbm' ...
TBM  =>  Starting parse of 'bp-mfl.tbm' ...
TBM  =>  Starting parse of 'bp2-mfl.tbm' ...
Wokka!  Error opening file (armor.tbl)!
TABLES: Unable to parse 'armor.tbl'!  Error code = 5.
TBM  =>  Starting parse of 'mv_effects-amr.tbm' ...
TBM  =>  Starting parse of 'bp2-amr.tbm' ...
TBM  =>  Starting parse of 'mv_effects-wxp.tbm' ...
TBM  =>  Starting parse of 'bp-wxp.tbm' ...
BMPMAN: Found EFF (exp20.eff) with 75 frames at 20 fps.
BMPMAN: Found EFF (ExpMissileHit1.eff) with 92 frames at 20 fps.
BMPMAN: Found EFF (exp04.eff) with 49 frames at 22 fps.
BMPMAN: Found EFF (exp05.eff) with 93 frames at 20 fps.
BMPMAN: Found EFF (exp06.eff) with 92 frames at 22 fps.
BMPMAN: Found EFF (capflash.eff) with 40 frames at 10 fps.
BMPMAN: Found EFF (Maxim_Impact.eff) with 23 frames at 30 fps.
ANI Lamprey_Impact with size 80x80 (37.5% wasted)
BMPMAN: Found EFF (explo3.eff) with 48 frames at 22 fps.
BMPMAN: Found EFF (HFlakExp.eff) with 48 frames at 22 fps.
BMPMAN: Found EFF (exp06b.eff) with 92 frames at 22 fps.
BMPMAN: Found EFF (bomb_flare.eff) with 69 frames at 20 fps.
TBM  =>  Starting parse of 'mv_core-wep.tbm' ...
TBM  =>  Starting parse of 'mv_effects-wep.tbm' ...
TBM  =>  Starting parse of 'mv_assets-wep.tbm' ...
TBM  =>  Starting parse of 'bp-wep.tbm' ...
TBM  =>  Starting parse of 'bp2-wep.tbm' ...
Weapon 'Hornet#Weak' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Harpoon#Weak' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Hornet#Weak#Shivan' requires the "player allowed" flag, but it's not listed!  Adding it by default.
Weapon 'Harpoon#Weak#Shivan' requires the "player allowed" flag, but it's not listed!  Adding it by default.
WARNING: Unrecognized parameter in ai_profiles: $disarm or disable cause global ai goal effects: YES

TBM  =>  Starting parse of 'bp-aip.tbm' ...
TBM  =>  Starting parse of 'bp2-aip.tbm' ...
TBM  =>  Starting parse of 'mv_effects-obt.tbm' ...
TBM  =>  Starting parse of 'bp2-obt.tbm' ...
TBM  =>  Starting parse of 'Sath-shp.tbm' ...
TBM  =>  Starting parse of 'mv_core-shp.tbm' ...
TBM  =>  Starting parse of 'mv_effects-shp.tbm' ...
TBM  =>  Starting parse of 'mv_assets-shp.tbm' ...
TBM  =>  Starting parse of 'radar-shp.tbm' ...
TBM  =>  Starting parse of 'boa-shp.tbm' ...
TBM  =>  Starting parse of 'artemistest-shp.tbm' ...
TBM  =>  Starting parse of 'bp-shp.tbm' ...
TBM  =>  Starting parse of 'bp2-shp.tbm' ...
Particle effect for impact spew disabled on ship 'Moon Landscape'.
Particle effect for damage spew disabled on ship 'Moon Landscape'.
TBM  =>  Starting parse of 'bp2-radaricons-shp.tbm' ...
ANI support1 with size 108x24 (25.0% wasted)
ANI damage1 with size 148x25 (21.9% wasted)
ANI wingman1 with size 71x53 (17.2% wasted)
ANI wingman2 with size 35x53 (17.2% wasted)
ANI wingman3 with size 14x53 (17.2% wasted)
ANI toggle1 with size 57x20 (37.5% wasted)
ANI head1 with size 164x132 (48.4% wasted)
ANI weapons1 with size 126x20 (37.5% wasted)
ANI weapons1_b with size 150x20 (37.5% wasted)
ANI objective1 with size 149x21 (34.4% wasted)
ANI energy1 with size 12x41 (35.9% wasted)
ANI targetview1 with size 137x156 (39.1% wasted)
ANI targetview2 with size 4x96 (25.0% wasted)
ANI targetview3 with size 7x20 (37.5% wasted)
ANI 2_radar1 with size 209x170 (33.6% wasted)
ANI 2_energy2 with size 86x96 (25.0% wasted)
ANI 2_reticle1 with size 40x24 (25.0% wasted)
ANI targhit1 with size 31x21 (34.4% wasted)
ANI 2_leftarc with size 103x252 (1.6% wasted)
ANI 2_rightarc1 with size 103x252 (1.6% wasted)
ANI 2_toparc2 with size 35x24 (25.0% wasted)
ANI 2_toparc3 with size 41x29 (9.4% wasted)
ANI netlag1 with size 29x30 (6.3% wasted)
ANI 2_lead1 with size 26x26 (18.8% wasted)
ANI 2_lock1 with size 56x53 (17.2% wasted)
ANI 2_lockspin with size 100x100 (21.9% wasted)
ANI time1 with size 47x23 (28.1% wasted)
TBM  =>  Starting parse of 'mv_core-hdg.tbm' ...
TBM  =>  Starting parse of 'mv_effects-str.tbm' ...
TBM  =>  Starting parse of 'bp-str.tbm' ...
TBM  =>  Starting parse of 'bp2-str.tbm' ...
loading animated cursor "cursor"
MediaVPs: Flaming debris script loaded!
MediaVPs: Explosions script loaded!
Ships.tbl is : VALID
Weapons.tbl is : VALID
cfile_init() took 1520
Got event GS_EVENT_GAME_INIT (49) in state NOT A VALID STATE (0)
Got event GS_EVENT_MAIN_MENU (0) in state GS_STATE_INITIAL_PLAYER_SELECT (37)
Someone passed an extension to bm_load for file 'hammer1.pcx'
WARNING!, Could not load door anim 2_Exit in main hall
WARNING!, Could not load door anim 2_Pilot in main hall
WARNING!, Could not load door anim 2_Continue in main hall
WARNING!, Could not load door anim 2_Tech in main hall
WARNING!, Could not load door anim 2_Option in main hall
WARNING!, Could not load door anim 2_Campaign in main hall
Frame  0 too long!!: frametime = 0.296 (0.296)
Got event GS_EVENT_LAB (64) in state GS_STATE_MAIN_MENU (1)
Loading model 'fighter01.pof'
IBX: Found a good IBX to read for 'fighter01.pof'.
IBX-DEBUG => POF checksum: 0x3503498e, IBX checksum: 0x8f5f3d48 -- "fighter01.pof"
Frame  0 too long!!: frametime = 0.608 (0.608)
Frame  1 too long!!: frametime = 0.337 (0.337)
Loading model 'Sathanas.pof'
Potential problem found: Unrecognized subsystem type 'fighterbay', believed to be in ship Sathanas.pof
Found live debris model for 'turret01'
Found live debris model for 'turret02'
Found live debris model for 'turret03'
Found live debris model for 'turret04'
Found live debris model for 'turret49'
Found live debris model for 'turret50'
IBX: Found a good IBX to read for 'Sathanas.pof'.
IBX-DEBUG => POF checksum: 0x0f724334, IBX checksum: 0xdc74f1e9 -- "Sathanas.pof"
Frame 2496 too long!!: frametime = 4.098 (4.098)
Frame 2497 too long!!: frametime = 1.199 (1.199)
Got event GS_EVENT_PREVIOUS_STATE (7) in state GS_STATE_LAB (50)
WARNING!, Could not load door anim 2_Exit in main hall
WARNING!, Could not load door anim 2_Pilot in main hall
WARNING!, Could not load door anim 2_Continue in main hall
WARNING!, Could not load door anim 2_Tech in main hall
WARNING!, Could not load door anim 2_Option in main hall
WARNING!, Could not load door anim 2_Campaign in main hall
Got event GS_EVENT_QUIT_GAME (5) in state GS_STATE_MAIN_MENU (1)
SOUND: d:\fso\scp - clean\code\sound\ds.cpp:1273 - OpenAL error = 'Invalid Operation'
Freeing all existing models...
... Log closed, Fri Jul 22 15:51:10 2011
Title: Re: FXAA in FSO
Post by: The E on July 22, 2011, 03:53:45 pm
Fantastic.
Title: Re: FXAA in FSO
Post by: Cogitation on July 22, 2011, 07:46:09 pm
TBH I can't tell, due to inexperience with the game if this is related to FXAA or something else but I did install/create the new shader file for version 3.9 and since doing so, I'm having some issues.  When I play the game, after about 20 to 30 minutes, I start getting mild visual glitching.  Just little flashes of light along polygon edges...  Then after about an hour or so, I suddenly get massive visual corruption, where I get what looks like flat rectangular textures covering nearly everything on the screen that move with normal game movement and the game is still running.  Didn't think to take a screenshot at the time.

Not, I suspect, a video card problem because it only happens with FSO.

Will look up how to post a log for you.

<edit>

Apologies.  I didn't see all the progress in the thread since the last page.  The problem I had occured using the version 3.9 shader.  Will grab the newest nightly and see if it is corrected.
Title: Re: FXAA in FSO
Post by: The E on July 23, 2011, 03:50:49 am
Well, it would be nice to know if this is actually related to FXAA. Because it sounds more like some hardware failure due to overheating to me.
Title: Re: FXAA in FSO
Post by: Cogitation on July 23, 2011, 08:05:16 am
I kind of realized it would sound like that, which is why I addressed it.  I'm a computer tech, and I'm familiar with the kind of weird visual glitches a failing/overheating video card causes.  This is very much an in-game looking glitch though.  I had a different version of it happen to me as I was playing the last mission of the main campaign (got caught in the supernova 1000m from the node...did a SW Episode III "NOOOOOOO!") that forced me to quit and restart.  An explosion texture went off and instead of disappearing, it froze in place and suddenly popped on top of everything except a few pieces of the HUD and the targeting recticle on my current target, though I was able to move normally, and in fact when I fired primary cannons, I could see those normally too.  I tried to take a screenshot this time, but when when I pasted into paint, I just got my desktop, so maybe I'll need to use fraps to try to capture it or something.

It happened pretty infrequently.  In fact I now think it wasn't time-related, as it seemed to happen more randomly during the beginning/middle/end of a mission as I continued through the campaign.  Definitely didn't happen before I installed the version 3.9 shader, but then again I had only played 4 or 5 missions before doing that.  Do you want me to post a log?

Entirely irrelevant sidenote, I've noticed the spell-checker when typing in this window marks a lot of words as misspelled when they're not.  I don't know if that's Firefox or the hard-light forums, but it's pretty funny that recticle, shader and ad infinitum get underlined red. :P
Title: Re: FXAA in FSO
Post by: The E on July 23, 2011, 08:22:05 am
Well, given that I just finished an upgrade to FXAA 3.11 (coming soon to a nightly near you!), I am not that interested in seeing a log there. In all probability, the log wouldn't tell me anything anyway; It sounds a lot like an issue relating to graphics memory corruption (whether it's caused by the hardware, the driver, or FSO is impossible to tell for me at this point).

So, given that 3.11 will have a much more simplified and faster shader for fxaa (no conditional jumps, yay!), I'd suggest to try that. Also, I'm still interested in seeing if a) this is related to FXAA specifically, or b) post-processing in general, or c) a general issue with our graphics pipeline.
Title: Re: FXAA in FSO
Post by: Cogitation on July 23, 2011, 08:42:34 am
Okay.  I'll check the new version out.  I grabbed the latest nightly last night.  Which release is it part of?  And you're right; it could always be the newest version of the Catalyst driver, which I installed about a ten days ago.  They care a lot more about making the newest game gain 3fps than they do about not breaking stuff that used to work...
Title: Re: FXAA in FSO
Post by: Kolgena on July 23, 2011, 10:17:59 am
http://www.hard-light.net/forums/index.php?topic=77244.0

This is the latest release with FXAA 3.11

Just tried it out. I notice that compared to 3.10, the presets 0-8 no longer divide performance into two tiers (0-4 is fast, 5-8 is slow) with different strengths of AA. Instead, presets 0-9 seem to do something, and performance scales linearly.

Personally, I find that the anti-aliasing of the low-end presets are much much better in 3.11, and performance is still comparable to low-end of 3.10. Good stuff.
Title: Re: FXAA in FSO
Post by: Plombo on July 27, 2011, 08:50:04 am
What part(s) of the GL_EXT_gpu_shader4 extension does FXAA require?
Title: Re: FXAA in FSO
Post by: The E on July 27, 2011, 08:56:19 am
texture2DLodOffset(), mostly. It will also take advantage of GL_ARB_gpu_shader5/GL_NV_gpu_shader5's textureGather functions.
Title: Re: FXAA in FSO
Post by: Plombo on July 27, 2011, 09:07:12 am
texture2DLodOffset(), mostly. It will also take advantage of GL_ARB_gpu_shader5/GL_NV_gpu_shader5's textureGather functions.

Ah.  Will the ARB_texture_gather functions work or will it need the extended versions in GL_ARB_gpu_shader5/GL_NV_gpu_shader5?
Title: Re: FXAA in FSO
Post by: The E on July 27, 2011, 09:59:24 am
It wants the extended versions, however it can also work if those functions aren't present (although it will be slower).
Title: Re: FXAA in FSO
Post by: Plombo on July 27, 2011, 11:34:56 am
It wants the extended versions, however it can also work if those functions aren't present (although it will be slower).

Hm, is this (http://pastebin.com/uHaTh2Nb) the version you're talking about that uses textureGrad?  If so, it doesn't look to me like it uses any of the EXT_gpu_shader5 extensions...
Title: Re: FXAA in FSO
Post by: The E on July 27, 2011, 11:37:15 am
No, it's not, but look at the FXAA_GATHER4_ALPHA codepath.
Title: Re: FXAA in FSO
Post by: Plombo on July 27, 2011, 01:03:33 pm
No, it's not, but look at the FXAA_GATHER4_ALPHA codepath.

I did.  All the uses of textureGather use the ARB_texture_gather prototypes, as far as I can tell.
Title: Re: FXAA in FSO
Post by: The E on July 27, 2011, 01:10:12 pm
Well, I am not entirely sure about it all. But then, I am not the one who wrote the shader :P
Title: Re: FXAA in FSO
Post by: Kolgena on July 28, 2011, 10:56:51 am
Nightly 7380 leaves mouse trails in-mission if FXAA is on and you access the ESC menu. Doesn't happen if FXAA is off. Game doesn't let me print-screen it, so you'll just have to go duplicate it yourself.

Turn on FXAA (I used preset 0)
Run any mission.
Hit ESC to bring up the quit/restart menu.
Move cursor off of the menu, into the 3D render space.
Cursor freaks out.

Pretty much a non-issue since it's completely harmless, similar to how the game no longer reports who kills you, but it's slightly annoying nonetheless.




[attachment deleted by ninja]
Title: Re: FXAA in FSO
Post by: Spoon on July 28, 2011, 11:25:53 am
Getting the same as Kolgena with FXAA enabled
Screen also flikkers on the borders when paused.
Title: Re: FXAA in FSO
Post by: Kolgena on July 28, 2011, 12:03:41 pm
Flicker only happens if your scene was in motion prior to pausing. If you are absolutely still, there's no screen flicker.
Title: Re: FXAA in FSO
Post by: Davros on August 14, 2011, 09:56:53 pm
Out of curiosity, what does it look like if you also have ati's mlaa enabled ?
Title: Re: FXAA in FSO
Post by: The E on August 15, 2011, 07:15:07 am
It shouldn't look much different, as the MLAA shader would run on the FXAA-processed image, and would thus find only very little to do except waste performance.
Title: Re: FXAA in FSO
Post by: noxnoctum on May 01, 2012, 11:13:12 pm
Sorry but is there a file I'm supposed to download to make this change or do I need to manually edit this stuff in?
Title: Re: FXAA in FSO
Post by: General Battuta on May 01, 2012, 11:31:24 pm
It's built into recent builds as a launcher option. Not sure if those builds are available to the public, check 3.6.14 RC5.
Title: Re: FXAA in FSO
Post by: Kolgena on May 02, 2012, 02:06:17 am
It shouldn't look much different, as the MLAA shader would run on the FXAA-processed image, and would thus find only very little to do except waste performance.

A key difference would be that MLAA will apply blurring/anti-aliasing to the HUD. So, if that's what you desire for some reason, then it can offer you that for massive performance cost.

3.6.14 RC5 has FXAA.
Title: Re: FXAA in FSO
Post by: MetalDestroyer on May 02, 2012, 08:33:50 am
Is-it possible to implement SMAA in Open GL engine and so into FSO ?
Here some technical info:
http://www.iryoku.com/smaa/

It has better rendering than FXAA and can be added with classic MSAA. So, playing a game with MSAA 2x + SMAA = WIN ! :)
Title: Re: FXAA in FSO
Post by: The E on May 02, 2012, 08:41:40 am
I'll look into it, but given that SMAA is a multi-stage algorithm that requires external textures to work correctly, I still prefer FXAA for its simplicity.
Title: Re: FXAA in FSO
Post by: Samus on May 02, 2012, 12:44:12 pm
Can the engine support normal antialiasing with postprocessing? I run the game with 32x AA + FXAA with my gtx 580, the game looks sharp and I still have effects like bloom, framebuffer explosions etc. Just want to make sure I'm not missing out on anything.
Title: Re: FXAA in FSO
Post by: Samus on May 02, 2012, 12:47:48 pm
Oh and sorry if this is not the right topic, but if I may ask, how do I get height maps working? I added the command line -height but I see no difference.

Thanks!
Title: Re: FXAA in FSO
Post by: General Battuta on May 02, 2012, 12:56:16 pm
Normal maps do everything height maps did but way better.
Title: Re: FXAA in FSO
Post by: The E on May 02, 2012, 12:57:45 pm
Can the engine support normal antialiasing with postprocessing? I run the game with 32x AA + FXAA with my gtx 580, the game looks sharp and I still have effects like bloom, framebuffer explosions etc. Just want to make sure I'm not missing out on anything.

Driver-enforced antialiasing should still work.

Oh and sorry if this is not the right topic, but if I may ask, how do I get height maps working? I added the command line -height but I see no difference.

Thanks!

You can't get height maps to work. First, because there are no height maps for any of the ships, second because there's no code in the shaders to make them work.

And no, this was not the right thread to ask. Especially not with a double post. There's a post modification function for that purpose.

Normal maps do everything height maps did but way better.

No. True parallax mapping would be a very nice thing to have, as it generally produces better visuals than standard normal mapping.
Title: Re: FXAA in FSO
Post by: Dragon on May 02, 2012, 03:39:33 pm
Would a proper parallax mapping implementation require and additions to FSO code, or can it be done entirely in shaders? Some form of it was in some time ago (and TVWP had maps for it), but it looked rather ugly (though maybe it was caused by improper -height maps).
Title: Re: FXAA in FSO
Post by: Kolgena on May 02, 2012, 06:29:06 pm
The only place I can think of where POM is better than normal maps are in greebled areas. However, I don't think they'd be worth the performance hit to use, especially if they end up breaking driver-forced AF.

Regarding SMAA: Some say it runs faster than FXAA, but I've consistently found that it is far slower than FXAA when using injectors of both for a number of games. Maybe the injectors suck or my hardware is too old, but it's something to keep in mind, I guess.
Title: Re: FXAA in FSO
Post by: The E on May 03, 2012, 02:55:55 am
Given how SMAA works, it is almost certainly slower than FXAA. Which is why FXAA will not get removed, even if SMAA integration is no problem.
Title: Re: FXAA in FSO
Post by: MetalDestroyer on May 03, 2012, 09:43:04 am
Given how SMAA works, it is almost certainly slower than FXAA. Which is why FXAA will not get removed, even if SMAA integration is no problem.

Yep, it is a little slower than FXAA. You will lost perhaps 5 fps.
Title: Re: FXAA in FSO
Post by: The E on May 03, 2012, 10:14:27 am
No offense, MD, but without knowing exactly what your graphics hardware is, "5 FPS lost" means exactly nothing.

To illustrate, if your hardware can render FSO at a framerate of 120 fps, losing 5 fps will not be really noticeable, as that represents only a 4.16% decreasin framerate. If, on the other hand, your hardware is struggling to maintain 30 FPS, then losing 5 FPS represents quite noticeable drop (by 16.67%, to be exact).