'最近邻'缩放

时间:2012-02-09 16:45:36

标签: c# image xna xna-4.0

当我绘制拉伸的Texture2D时,像素会产生类似模糊的效果。

我想在我的游戏中使用'像素化'图形,并想知道如何禁用这个以支持最简单的最近邻居缩放。

我已创建此图片以供说明:(x4 zoom)
enter image description here

我能以什么方式完成这项工作?

3 个答案:

答案 0 :(得分:15)

在XNA 4中,更改SpriteBatch.Begin()以将采样器状态设置为SamplerState.PointClamp

答案 1 :(得分:5)

如果您正在使用着色器绘制图像,则可以修改采样器状态:

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

点采样应该可以防止GPU在对图像进行采样时进行插值,这可能会导致您的抗锯齿/模糊行为。

如果您只是使用SpriteBatch绘制图片,则可以使用以下方式设置过滤器:

Device.SamplerStates[0] = SamplerState.PointClamp;

此外,您似乎可能必须将SpriteBatch设置为使用立即模式。 See this article on MSDN for more informationthis thread on the App Hub forums

这是一个早期的SO主题,可能会有所帮助:

See this thread for more information.

使用标准化坐标(0..1,0..1)而不是纹素坐标对纹理进行采样。 GPU将找到给定纹理坐标的四个最接近的纹素,并基于该正方形内的样本点的位置在它们之间进行插值。

所以,如果我的纹理是10 x 10像素,并且我尝试从(0.15,0.15)读取,那么GPU将在(1,1),(2,1)处的纹素之间进行插值),(1,2)和(2,2)。在这种情况下,0.05应该使得屏幕上的结果像素简单地是四个周围像素的平均值。但是,如果纹理在(0.19,0.19)处采样,则所得到的颜色将在(2,2)处严重偏向纹素。

点采样将使GPU始终从底层纹理中读取精确的颜色,而不是加权样本区域周围的坐标。

这是一个有效的.Draw()方法,它说明了所有这些:

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

答案 2 :(得分:0)

您需要确保x,y坐标是整数值。分数坐标或尺寸导致应用抗锯齿来模拟“分数”像素偏移。

因此模糊。