2010-07-20 70 views
2

在XNA框架中,是否有一種方法可以使用典型的SpriteBatch方法渲染2D場景,然後在渲染幀之後將效果應用於整個圖像?在XNA中將渲染效果應用於SpriteBatch

例如,模糊,棕褐色,甚至使整個事情看起來像舊時代的電影電影,穀物,灰塵,線條等?

回答

3

是的 - 你要做的就是將渲染目標設置爲渲染到紋理而不是你的圖形硬件。然後,一旦你的輸出在紋理中,你就會應用你的像素着色器效果,並將其發送出去。

一些偉大的基本採樣效果可在這裏(我衷心建議您訂閱這個博客也) http://blogs.msdn.com/b/shawnhar/archive/2007/05/23/transitions-part-four-rendertargets.aspx

+1

還有在創作者俱樂部一整套後處理的樣品:http://creators.xna.com/en-美國/教育/目錄/?devarea = 15(Bl你想要的樣本是一個很好的例子。) – 2010-07-21 01:48:10

2

這裏是我的泛着代碼,我有興趣,關於如何提高它的意見。基本上我有物體分爲發光和正常。我創造我的初始化方法,具有深度緩衝其中的一二RenderTarget2D對象,因爲我在做3D:

GlowTarget = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, SurfaceFormat.Color, DepthFormat.Depth24Stencil8); 
GlowTarget2 = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, SurfaceFormat.Color, DepthFormat.None); 

在我的畫法我使正常的對象,我GlowTarget然後清除顏色爲黑色零Alpha並繪製發光物體。我使用自定義效果像素着色器將其繪製到GlowTarget2上,以在X方向上模糊它。然後清除渲染目標並繪製普通對象。最後,我將GlowTarget2紋理與另一個自定義效果一起在Y方向上模糊。

/// <summary> 
/// This is called when the game should draw itself. 
/// </summary> 
/// <param name="gameTime">Provides a snapshot of timing values.</param> 
protected override void Draw(GameTime gameTime) 
{ 
    // draw clear GlowTarget and draw normal, non-glowing objects to set depth buffer 
    GraphicsDevice.SetRenderTarget(GlowTarget); 
    GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil | ClearOptions.Target, Color.FromNonPremultiplied(0, 0, 0, 0), 1f, 0); 
    MyScene.DrawNormal(); 

    // clear target only and set color to black WITH ZERO ALPHA, then draw glowing objects 
    // so they will be the only ones that appear and they will be hidden by objects in front of them 
    GraphicsDevice.Clear(ClearOptions.Target, Color.FromNonPremultiplied(0, 0, 0, 0), 1f, 0); 
    MyScene.DrawGlow(); 

    // blur objects horizontally into GlowTarget2 
    GraphicsDevice.SetRenderTarget(GlowTarget2); 
    GraphicsDevice.Clear(Color.FromNonPremultiplied(0, 0, 0, 0)); 
    using (SpriteBatch sb = new SpriteBatch(GlowTarget2.GraphicsDevice)) 
    { 
     blurXEffect.Parameters["PixelSize"].SetValue((float)(1.0f/(float)GlowTarget.Width)); 
     sb.Begin(0, BlendState.Additive, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, blurXEffect); 
     sb.Draw(GlowTarget, new Rectangle(GraphicsDevice.Viewport.X, GraphicsDevice.Viewport.Y, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White); 
     sb.End(); 
    } 

    // now reset context and clear for actual drawing 
    GraphicsDevice.SetRenderTarget(null); 
    GraphicsDevice.BlendState = BlendState.Opaque; 
    GraphicsDevice.Clear(Color.Black); 

    // TODO: Add your drawing code here 
    base.Draw(gameTime); 

    // draw scene to graphics card back buffer 
    MyScene.DrawNormal(); 

    using (SpriteBatch sprite = new SpriteBatch(GraphicsDevice)) 
    { 
     // draw glowing texture and blur Y this time 
     blurYEffect.Parameters["PixelSize"].SetValue((float)(1.0f/(float)GlowTarget.Height)); 
     sprite.Begin(0, BlendState.Additive, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, blurYEffect); 

     //sprite.Draw(GlowTarget, new Vector2(0, 0), Color.White); 
     sprite.Draw(GlowTarget2, new Rectangle(GraphicsDevice.Viewport.X, GraphicsDevice.Viewport.Y, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White); 
     sprite.End(); 
    } 
} 

如果你正在做類似應用一個效果,那麼你可以只設置在SpriteBatch.Begin(自定義效果一些簡單的2D)打電話......這是我的bluring X着色器:

// texture we are rendering 
sampler2D tex : register(S0); 

float PixelSize; 

// pixel shader function 
float4 main(float2 uv : TEXCOORD) : COLOR 
{ 
    float4 c = 0; // will get max of each value for c 
    float alpha = 0; // alpha will be average 

    float2 myuv = uv; 
    for(int i = -7; i <= 7; i++) 
    { 
     myuv.x = uv.x + (i * PixelSize * 1.5); 
     float4 sample = tex2D(tex, myuv); 
     c = max(c, sample); 
     alpha += sample.a; 
    } 

    c.a = saturate(pow(abs(alpha/6), 0.4)); 
    return(c); 
} 

technique Technique1 
{ 
    pass Pass1 
    { 
     PixelShader = compile ps_2_0 main(); 
    } 
} 

下面是一個示例圖像,紅,綠,藍色正方形正常發光的版本在他們之上: Glow Sample