2011-10-06 8 views
6

Sto utilizzando XNA 4.0 controllo di modulo questo esempio di progetto in un'applicazione che sto scrivendo: http://creators.xna.com/en-US/sample/winforms_series1Esempi di utilizzo di Nvidia FXAA (antialiasing dello shader) nelle winform XNA 4.0?

Se si ha familiarità con FXAA, controlla il sito del creatore: http://timothylottes.blogspot.com/2011/03/nvidia-fxaa.html

Ho passato abbastanza un po 'di tempo finora cercando di capire di usarlo senza fortuna (finora ...). È vero, non ho molta esperienza con la programmazione grafica, ma attualmente ho una bella applicazione in esecuzione, sembra davvero molto povera con le linee frastagliate. Conosco il metodo integrato per AA, ma non funziona per me e il mio computer portatile. Quindi la mia richiesta riguarda l'uso di FXAA e non i metodi incorporati.

A questo punto: Ho il file di intestazione FXAA 3.11 nel mio progetto Contenuto. Ho un file FX generiche acquisite tramite Visual Studio con un paio di cose come:

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

Sto solo chiedendo qui per vedere se qualcuno potrebbe fornire alcuni esempi XNA 4.0, in particolare con l'utilizzo di tale metodo finestre personalizzate forme.

Apprezzo qualsiasi aiuto che qualcuno potrebbe essere in grado di fornire.

Modifica 3: Ho cercato di capire come far funzionare FXAA da quando ho postato questo messaggio. ho trovato questo: http://www.gamedev.net/topic/609638-fxaa-help/page__st__20 e questo: http://fxaa-pp-inject.assembla.me/trunk/DirectX9/shader.fx

io a strisce giù FXAA a nudo le ossa tipo FXAA_PC_CONSOLE e compila. Ho solo bisogno di capire il parametro fxaaConsolePosPos che è la posizione in alto a sinistra e in basso a destra di ciascun pixel. Ad ogni modo, sembra che FXAA_PC_CONSOLE possa funzionare con lo shader model 2.0 che devo usare con REACH e WinNA basato su XNA.

+0

MLAA è un'opzione per te? Non penso che troverai un esempio di codice usando l'esempio WinForms più FXAA in un tutorial. –

+0

Qualsiasi cosa tranne l'antialiasing incorporato dovrebbe essere un'opzione se funziona su hardware inferiore. Sai dove posso trovare qualcosa per xna winforms un MLAA? – Scott

+0

Beh, davvero niente con XNA affatto (purché non usi la classe di gioco e così) ... Non ho ancora trovato nulla e sto ancora cercando di risolverlo da solo imparando quanto Posso circa xna shaders – Scott

risposta

6

Quindi l'ho capito, almeno utilizzando la versione minore di FXAA progettata per console e PC di fascia bassa. Non posso garantire che i miei parametri per il codice dello shader siano corretti, ma vedo una differenza notevole quando è in esecuzione.

Ecco la soluzione completa con la mia tritato shader e pezzi di codice C# XNA 4.0:

Il codice dello shader prima (che mettere in un file .fx nel sottoprogetto Content): nota che ho sostituito con tex2Dlod tex2D secondo un suggerimento che SM2.0 non supporta il primo tipo

#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(); 
    } 
} 

Ecco un frammento di codice C diesis applicare 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(); 
+0

Ciao a tutti, cercherò di implementare FXAA come PixelShader da utilizzare nei progetti WPF. In un progetto su cui sto lavorando, ho un sacco di manipolazioni a livello di bitmap e voglio applicare un pixelhader per aiutare a smussare i bordi frastagliati. WPF supporta PS3.0 e Silverlight supporta PS2.0 nel tipo ShaderEffect integrato. Hai qualche esperienza con WPF/SL e ti dispiacerebbe se facessi alcune domande se e quando sarò bloccato sullo sviluppo? –

+0

Siamo spiacenti, non ho usato WPF/Silverlight. Fondamentalmente per questo progetto ho trascorso alcune settimane di pausa e alla ricerca del problema perché c'erano così poche informazioni e ne ho fatto abbastanza per farlo funzionare. Non credo di poter essere di grande aiuto. – Scott

-1

Recentemente ho implementato questa tecnica nel mio gioco, ma per qualche motivo i miei bordi rimangono ancora "jaggy". C'è un modo per modificare il codice da qualche parte per ammorbidire un po 'i bordi frastagliati? Grazie.

+0

Non rispondere alla domanda, si prega di chiedere una nuova :) –

Problemi correlati