Examples of using Nvidia FXAA (smoothing shaders) in XNA 4.0 winforms?

I am using this XNA 4.0 form control example in the application I am writing: http://creators.xna.com/en-US/sample/winforms_series1

If you are not familiar with FXAA, check out the creator's website: http://timothylottes.blogspot.com/2011/03/nvidia-fxaa.html

I spent a lot of time trying to understand, use it without luck (so far ...). It’s true that I don’t have much experience with graphic programming, but currently I have a good application, it looks really very bad with jagged lines. I know about the built-in method for AA, but it does not work for me and my laptop. Therefore, my request is about using FXAA, and not about built-in methods.

At this point: I have an FXAA 3.11 header file in a Content project. I have a generic FX file created by a visual studio, with a few things like:

#define FXAA_PC_CONSOLE 1 #define FXAA_HLSL_5 1 #define FXAA_QUALITY__PRESET 12 #include "Includes/Fxaa3_11.h" 

I just ask here to see if anyone can provide some examples of XNA 4.0, in particular using this custom Windows forms method.

I appreciate any help anyone can provide.

Edit 3: I was trying to figure out how to get FXAA to work since I posted this post. I found this: http://www.gamedev.net/topic/609638-fxaa-help/page__st__20 and this: http://fxaa-pp-inject.assembla.me/trunk/DirectX9/shader.fx

I split FXAA into bare bones FXAA_PC_CONSOLE and compiled it. I just need to figure out the fxaaConsolePosPos parameter, which is the upper left and lower right positions of each pixel. In any case, it looks like FXAA_PC_CONSOLE can work with the shader model 2.0, which I need to use with REACH and XNA-based winforms.

+6
source share
2 answers

So, I realized, at least, using a smaller version of FXAA designed for consoles and low-maintenance computers. I can not guarantee that my parameters in the shader code are correct, but I see a noticeable difference when it works.

Here is the complete solution with my shredded shader and pieces of C # XNA 4.0 code:

The shader code is used first (put it in the .fx file in the Content sub-project): note that I replaced tex2Dlod with tex2D under the assumption that SM2.0 does not support the first type

 #define FxaaBool bool #define FxaaDiscard clip(-1) #define FxaaFloat float #define FxaaFloat2 float2 #define FxaaFloat3 float3 #define FxaaFloat4 float4 #define FxaaHalf half #define FxaaHalf2 half2 #define FxaaHalf3 half3 #define FxaaHalf4 half4 #define FxaaSat(x) saturate(x) #define FxaaInt2 float2 #define FxaaTex sampler2D #define FxaaTexTop(t, p) tex2D(t, float4(p, 0.0, 0.0)) #define FxaaTexOff(t, p, o, r) tex2D(t, float4(p + (o * r), 0, 0)) FxaaFloat FxaaLuma(FxaaFloat4 rgba) { rgba.w = dot(rgba.rgb, FxaaFloat3(0.299, 0.587, 0.114)); return rgba.w; } /*============================================================================ FXAA3 CONSOLE - PC VERSION ============================================================================*/ FxaaFloat4 FxaaPixelShader( FxaaFloat2 pos, FxaaFloat4 fxaaConsolePosPos, FxaaTex tex, FxaaFloat4 fxaaConsoleRcpFrameOpt, FxaaFloat4 fxaaConsoleRcpFrameOpt2, FxaaFloat fxaaConsoleEdgeSharpness, FxaaFloat fxaaConsoleEdgeThreshold, FxaaFloat fxaaConsoleEdgeThresholdMin) { FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); #if (FXAA_GREEN_AS_LUMA == 0) FxaaFloat lumaM = rgbyM.w; #else FxaaFloat lumaM = rgbyM.y; #endif FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); lumaNe += 1.0/384.0; FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; FxaaFloat lumaMinM = min(lumaMin, lumaM); FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); FxaaFloat lumaMaxM = max(lumaMax, lumaM); FxaaFloat dirSwMinusNe = lumaSw - lumaNe; FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; FxaaFloat dirSeMinusNw = lumaSe - lumaNw; if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; FxaaFloat2 dir; dir.x = dirSwMinusNe + dirSeMinusNw; dir.y = dirSwMinusNe - dirSeMinusNw; FxaaFloat2 dir1 = normalize(dir.xy); FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); #if (FXAA_GREEN_AS_LUMA == 0) FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); #else FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); #endif if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; return rgbyB; } /*==========================================================================*/ uniform extern float SCREEN_WIDTH; uniform extern float SCREEN_HEIGHT; uniform extern texture gScreenTexture; sampler screenSampler = sampler_state { Texture = <gScreenTexture>; /*MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp;*/ }; float4 PixelShaderFunction(float2 tc : TEXCOORD0) : COLOR0 { float pixelWidth = (1 / SCREEN_WIDTH); float pixelHeight = (1 / SCREEN_HEIGHT); float2 pixelCenter = float2(tc.x - pixelWidth, tc.y - pixelHeight); float4 fxaaConsolePosPos = float4(tc.x, tc.y, tc.x + pixelWidth, tc.y + pixelHeight); return FxaaPixelShader( pixelCenter, fxaaConsolePosPos, screenSampler, float4(-0.50 / SCREEN_WIDTH, -0.50 / SCREEN_HEIGHT, 0.50 / SCREEN_WIDTH, 0.50 / SCREEN_HEIGHT), float4(-2.0 / SCREEN_WIDTH, -2.0 / SCREEN_HEIGHT, 2.0 / SCREEN_WIDTH, 2.0 / SCREEN_HEIGHT), 8.0, 0.125, 0.05); } technique ppfxaa { pass Pass1 { PixelShader = compile ps_2_0 PixelShaderFunction(); } } 

Here is a C-sharp code snippet for applying a shader:

 //.......................................... //these objects are used in managing the FXAA operation //FXAA objects (anti-aliasing) RenderTarget2D renderTarget; SpriteBatch spriteBatch; Effect fxaaAntialiasing; //.......................................... //initialize the render target and set effect parameters //code to handle a final antialiasing using a pixel shader renderTarget = new RenderTarget2D( GraphicsDevice, GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight, false, GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); spriteBatch = new SpriteBatch(GraphicsDevice); fxaaAntialiasing = content.Load<Effect>("sfxaa"); fxaaAntialiasing.CurrentTechnique = fxaaAntialiasing.Techniques["ppfxaa"]; fxaaAntialiasing.Parameters["SCREEN_WIDTH"].SetValue(renderTarget.Width); fxaaAntialiasing.Parameters["SCREEN_HEIGHT"].SetValue(renderTarget.Height); fxaaAntialiasing.Parameters["gScreenTexture"].SetValue(renderTarget as Texture2D); //.......................................... //this should happen in your Draw() method //change to our offscreen render target GraphicsDevice.SetRenderTarget(renderTarget); GraphicsDevice.Clear(Color.CornflowerBlue); // //draw all of your models and such here... // GraphicsDevice.SetRenderTarget(null); GraphicsDevice.Clear(Color.Black); //this where the shader antialiasing happens to the frame we just filled with content spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone, fxaaAntialiasing); //draw the buffer we made to the screen spriteBatch.Draw(renderTarget as Texture2D, new Rectangle(0, 0, renderTarget.Width, renderTarget.Height), Color.White); spriteBatch.End(); 
+6
source

I recently applied this technique in my game, but for some reason my edges remain "flabby." Is there a way to change the code somewhere to soften the jagged edges a bit? Thanks.

-1
source

Source: https://habr.com/ru/post/898792/


All Articles