2012-02-09 22 views
18

Cuando dibujo un Texture2D alargado, los píxeles reciben un efecto Blur-like.'Vecino más cercano' zoom

Quiero usar gráficos 'pixelados' en mi juego y me gustaría saber cómo deshabilitar esto en favor del zoom de vecino más simple más cercano.

He creado esta imagen para la ilustración: (zoom x4)
enter image description here

¿De qué manera puedo lograr esto?

+8

+1 para el sprite Star Control. – Rotem

Respuesta

15

En XNA 4, cambiar su SpriteBatch.Begin() para establecer el estado de toma de muestras a SamplerState.PointClamp

+5

he utilizado el método de esta manera después de buscar los valores por defecto en MSDN: 'spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise);' y funciona muy bien . ¡Gracias! – Acidic

5

Si utiliza un sombreado para dibujar la imagen, se puede modificar el estado de muestreo:

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

muestreo de puntos debe evitar que la GPU de interpolación cuando el muestreo de la imagen, que es probablemente lo que está causando sus antialias/desenfoque comportamiento.

Si sólo está utilizando SpriteBatch para dibujar la imagen, se puede establecer que el filtro usando:

Device.SamplerStates[0] = SamplerState.PointClamp; 

Además, parece que puede que tenga que configurar el SpriteBatch utilizar el modo inmediato. See this article on MSDN for more information, o this thread on the App Hub forums.

He aquí un SO anterior hilo que probablemente va a ser muy útil:

See this thread for more information.

texturas son muestreadas utilizando coordenadas normalizadas (0..1, 0..1) en lugar de las coordenadas Texel. La GPU encontrará los cuatro téxeles más cercanos para una determinada coordenada de textura e interpolará entre ellos en función de la posición del punto de muestra dentro de ese cuadrado.

Por lo tanto, si tengo una textura de 10 x 10 píxeles y trato de leer, digamos, (0.15, 0.15), la GPU interpolará entre los téxeles en (1,1), (2, 1), (1,2) y (2,2). En este caso, el 0.05 debería hacer que el pixel resultante en la pantalla sea simplemente el promedio de los cuatro píxeles circundantes. Sin embargo, si la textura se muestreara a (0,19, 0,19), el color resultante estaría muy sesgado hacia el téxel en (2,2).

El muestreo de puntos hará que la GPU lea siempre un color exacto de la textura subyacente en lugar de ponderar las coordenadas alrededor del área de muestra.

Aquí hay una .draw() método de trabajo que ilustra todo esto:

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

Simplemente estoy usando el método 'spriteBatch.Draw (...)'. Al dibujarlo en un rectángulo más grande y usar la propiedad 'scale' se obtiene este efecto. – Acidic

+0

@Acidic actualizado. SpriteBatch proporciona una propiedad para establecer el método de filtro. –

+0

Intentando cambiar el valor de 'SamplerStates [0].Filter' da como resultado un error, indicando que es una propiedad de solo lectura. – Acidic

0

Es necesario asegúrese de que sus coordenadas x, y sean valores enteros. Las coordenadas o dimensiones fraccionarias dan como resultado el antialiasing que se aplica para simular compensaciones de píxeles "fraccionales".

De ahí el desenfoque.

+0

dibujando con un objeto 'Rectangle' todavía crea el efecto no deseado. La pregunta fue respondida de todos modos. :) – Acidic

Cuestiones relacionadas