2012-02-09 14 views
18

Quando disegno un allungato Texture2D, i pixel ricevono un effetto simile alla sfocatura.'Più vicino' zoom

Voglio utilizzare la grafica 'pixelata' nel mio gioco e vorrei sapere come disabilitare questo in favore del più vicino vicino zoom.

Ho creato questa immagine per l'illustrazione: (x4 zoom)
enter image description here

In che modo posso ottenere questo risultato?

+8

+1 per lo sprite Star Control. – Rotem

risposta

15

In XNA 4, modificare lo SpriteBatch.Begin() per impostare lo stato campionatore SamplerState.PointClamp

+5

Ho usato il metodo in questo modo dopo aver cercato i valori predefiniti su MSDN: 'spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise);' e funziona bene . Grazie! Il disegno – Acidic

5

Se si sta utilizzando uno shader per disegnare l'immagine, è possibile modificare lo stato campionatore:

sampler2D mySampler = sampler_state 
{ 
    Texture=<SomeTexture>; 
    Filter=POINT; 
}; 

campionamento Point dovrebbe impedire la GPU di interpolazione durante il campionamento l'immagine, che è probabilmente ciò che sta causando i vostri antialias/comportamento di sfocatura.

Se stai usando solo SpriteBatch per disegnare l'immagine, è possibile impostare il filtro utilizzando:

Device.SamplerStates[0] = SamplerState.PointClamp; 

Inoltre, sembra che potrebbe essere necessario impostare lo SpriteBatch per utilizzare la modalità immediata. See this article on MSDN for more information o this thread on the App Hub forums.

Ecco un precedente SO filo che probabilmente sarà utile:

See this thread for more information.

texture sono campionati con coordinate normalizzate (0..1, 0..1), piuttosto che le coordinate Texel. La GPU troverà i quattro texel più vicini per una determinata coordinata della trama e li interpolerà in base alla posizione del punto di campionamento all'interno di quel quadrato.

Quindi, se ho una trama di 10 x 10 pixel e cerco di leggere, diciamo, (0.15, 0.15), la GPU interpolerà tra i texelli a (1,1), (2, 1), (1,2) e (2,2). In questo caso, lo 0,05 dovrebbe far sì che il pixel risultante sullo schermo sia semplicemente la media dei quattro pixel circostanti. Tuttavia, se la trama fosse campionata a (0,19, 0,19), il colore risultante sarebbe fortemente distorto verso il texel a (2,2).

Il campionamento dei punti fa sì che la GPU legga sempre un colore esatto dalla trama sottostante anziché le coordinate di ponderazione attorno all'area campione.

Ecco un .draw metodo di lavoro() che illustra tutto questo:

protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.Black); 

     var largeRect = new Rectangle(50, 50, sprite.Width * 3, sprite.Height * 3); 

     /// start the batch, but in immediate mode to avoid antialiasing 
     spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); 

     /// set the filter to Point 
     GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; 

     /// draw the sprite 
     spriteBatch.Draw(sprite, largeRect, Color.White); 

     /// done! 
     spriteBatch.End(); 

     // TODO: Add your drawing code here 

     base.Draw(gameTime); 
    } 
+0

Sto semplicemente usando il metodo 'spriteBatch.Draw (...)'. Sia disegnandolo in un rettangolo più grande che usando il risultato della proprietà 'scale' in questo effetto. – Acidic

+0

@Acidico aggiornato. SpriteBatch fornisce una proprietà per l'impostazione del metodo di filtro. –

+0

Cercando di cambiare il valore di 'SamplerStates [0].Filter' genera un errore, affermando che si tratta di una proprietà di sola lettura. – Acidic

0

È necessario assicurati che le tue coordinate x, y siano valori interi. Le coordinate o le dimensioni frazionali producono l'anti-aliasing applicato per simulare offset di pixel "frazionari".

Quindi la sfocatura.

+0

con un oggetto 'Rectangle' crea ancora l'effetto indesiderato. Alla domanda è stata data risposta comunque. :) – Acidic