Vì vậy, tôi đã tìm ra, ít nhất bằng cách sử dụng phiên bản thấp hơn của FXAA được thiết kế cho bảng điều khiển và máy tính cấp thấp. Tôi không thể đảm bảo thông số của mình cho mã trình đổ bóng là chính xác nhưng tôi thấy sự khác biệt đáng chú ý khi nó đang chạy.
Dưới đây là giải pháp hoàn chỉnh với xắt nhỏ lên shader và mẩu mã C# XNA 4.0 của tôi:
Mã đổ bóng đầu tiên (đặt rằng trong một tập tin .fx trong tiểu dự án nội dung của bạn): lưu ý mà tôi thay thế tex2Dlod với tex2D theo một gợi ý rằng SM2.0 không hỗ trợ các loại đầu tiên
#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();
}
}
Dưới đây là một đoạn mã C-sắc nét để áp dụng các 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();
MLAA có phải là tùy chọn cho bạn không? Tôi không nghĩ rằng bạn sẽ tìm thấy một ví dụ về mã bằng cách sử dụng ví dụ WinForms và FXAA trong một hướng dẫn. –
Mọi thứ nhưng tính năng chống răng cưa tích hợp phải là một tùy chọn nếu nó hoạt động trên phần cứng ít hơn. Bạn có biết nơi tôi có thể tìm thấy một cái gì đó cho xna winforms một MLAA? – Scott
Cũng thực sự bất cứ điều gì với XNA ở tất cả (miễn là nó không sử dụng các lớp trò chơi và như vậy) ... Tôi đã không tìm thấy bất cứ điều gì được nêu ra và tôi vẫn đang cố gắng để làm việc nó ra bản thân mình bằng cách học càng nhiều càng tốt Tôi có thể về xna shaders – Scott