简体   繁体   English

XNA中的像素完美渲染

[英]Pixel perfect rendering in XNA

I have a 2D game in XNA which has a scrolling camera. 我在XNA中有一个带有滚动摄像头的2D游戏。 Unfortunately, when screen is moved, I can see some artifacts - mostly blur and additional lines on the screen. 不幸的是,当屏幕移动时,我可以看到一些伪像-大多数是模糊的,屏幕上还有其他线条。

I thought about changing coordinates before drawing (approximating with Ceiling() or Floor() consistently), but this seems a little inefficient. 我考虑过在绘制之前更改坐标Floor()始终与Ceiling()Floor()一致),但这似乎效率不高。 Is this the only way? 这是唯一的方法吗?

I use SpriteBatch for rendering. 我使用SpriteBatch进行渲染。

This is my drawing method from Camera: 这是我从Camera绘制的方法:

Vector2D works on doubles, Vector2 works on floats (used by XNA), Srpite is just a class with data for spriteBatch.Draw . Vector2D适用于双打, Vector2适用于浮点数(由XNA使用), Srpite只是具有spriteBatch.Draw数据的类。

public void DrawSprite(Sprite toDraw)
{
    Vector2D drawingPostion;
    Vector2 drawingPos;
    drawingPostion = toDraw.Position - transform.Position;
    drawingPos.X = (float) drawingPostion.X*UnitToPixels;
    drawingPos.Y = (float) drawingPostion.Y*UnitToPixels;

    spriteBatch.Draw(toDraw.Texture, drawingPos, toDraw.Source, toDraw.Color,
        toDraw.Rotation, toDraw.Origin, toDraw.Scale, toDraw.Effects, toDraw.LayerDepth + zsortingValue);
}

My idea is to do this: 我的想法是这样做:

drawingPos.X = (float) Math.Floor(drawingPostion.X*UnitToPixels);
drawingPos.Y = (float) Math.Floor(drawingPostion.Y*UnitToPixels);

And it solves the problem. 它解决了这个问题。 I think I can accept it this way. 我想我可以这样接受。 But are there any other options? 但是还有其他选择吗?

GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; 

This isn't so much a problem with your camera as it is the sampler. 这不是相机的问题,因为它是采样器。 Using a Point Sampler state tells the video card to take a single point color sample directly from the texture depending on the position. 使用Point Sampler状态指示视频卡根据位置直接从纹理中直接获取单个点颜色样本。 Other default modes like LinearWrap and LinearClamp will interpolate between texels (pixels on your source texture) and give it a very mushy, blurred look. 其他默认模式(例如LinearWrap和LinearClamp)将在纹理像素(源纹理上的像素)之间进行插值,并赋予其非常糊状,模糊的外观。 If you're going for pixel-graphics, you need Point sampling. 如果要使用像素图形,则需要点采样。

With linear interpolation, if you have red and white next to each other in your texture, and it samples between the two (by some aspect of the camera), you will get pink. 使用线性插值时,如果纹理中的红色和白色彼此相邻,并且在这两者之间进行采样(根据相机的某些方面),则将变为粉红色。 With point sampling, you get either red or white. 使用点采样,您将获得红色或白色。 Nothing in between. 两者之间什么都没有。

Yes it is possible... try something this... 是的,有可能……尝试一下……

bool redrawSprite = false;
Sprite toDraw;

void MainRenderer()
{
   if (redrawSprite)
   {
      DrawSprite(toDraw);
      redrawSprite = false;
   }
}

void ManualRefresh()
{
   "Create or set your sprite and set it to 'toDraw'"
   redrawSprite = true;
}

This way you will let main loop do the work like is intended. 这样,您将让主循环按预期方式工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM