gpt4 book ai didi

xna - 在 MonoGame 中使用 "Wrap"模式时看到 "Clamp"纹理(含图片)

转载 作者:行者123 更新时间:2023-12-03 01:24:09 41 4
gpt4 key购买 nike

我正在使用 sprite 批处理在 MonoGame 项目中渲染图 block map 。

渲染代码如下:

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

SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, CameraManager.pInstance.pFinalTransform);

foreach( TmxLayer Layer in mCurrentTileMap.Layers)
{
for (int y = 0; y < mCurrentTileMap.Height; y++)
{
for (int x = 0; x < mCurrentTileMap.Width; x++)
{
TmxLayerTile Tile = Layer.Tiles[mCurrentTileMap.Width * y + x];
int TileID = -1;
Texture2D Texture = FindTileMapTextureForTileID(Tile.Gid, out TileID);
if (TileID > 0)
{
int atlasX = TileID % (Texture.Width / TileSize);
int atlasY = TileID / (Texture.Width / TileSize);

SpriteEffects FX = SpriteEffects.None;
if (Tile.HorizontalFlip)
{
FX = SpriteEffects.FlipHorizontally;
}

SpriteBatch.Draw(Texture, new Vector2(x * TileSize, y * TileSize), new Microsoft.Xna.Framework.Rectangle(atlasX * TileSize, atlasY * TileSize, TileSize, TileSize), Color.White, 0, Vector2.Zero, 1, FX, 0);
}
}
}
}

以下是我认为重要的代码行:

SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, 
null, null, null, CameraManager.pInstance.pFinalTransform);

SpriteBatch.Draw(Texture, new Vector2(x * TileSize, y * TileSize),
new Microsoft.Xna.Framework.Rectangle(atlasX * TileSize, atlasY * TileSize, TileSize, TileSize),
Color.White, 0, Vector2.Zero, 1, FX, 0);

如您所见,我正在使用SamplerState.PointClamp。然而,当我环游世界时,我偶尔会看到这种事情;在某些图 block 下方,您可以看到一行像素,这些像素是 Sprite 图集中位于该图 block 下方的像素。

Enlarge to see issue better点击放大可以清楚地看到问题...

我非常确定这种情况正在发生,因为应用于 Sprite 批处理的变换 (CameraManager.pInstance.pFinalTransform) 使用的是浮点精度。如果我强制将该转换的比例部分限制为整数,则不会出现问题。然而,这样做会导致相机移动非常不稳定(我的游戏放大得很厉害,因此显示器上的每个像素约为 10 个像素),因此这不是一个好的解决方案。

关于如何避免这种影响有什么想法吗?

这是源纹理 Sprite 表的样子,供引用。

enter image description here

最佳答案

I am pretty sure this is happening because the transform applied to the sprite batch (CameraManager.pInstance.pFinalTransform) is using floating point percision.

是的,这听起来很正确。当我们在MonoGame.Extended中编写Tiled map 渲染器时,我们遇到了类似的问题。在 map 图 block 被相机缩放后。

解决方案是将未缩放的 map 渲染为 RenderTarget2D首先,然后在第二遍中缩放整个事物。这样,您就不会缩放每个单独的图 block ,而是缩放整个 map 。

您可以在 TiledMap class 中了解它如何与 MonoGame.Extended 配合使用。 .

在您的情况下,代码可能如下所示:

private readonly RenderTarget2D _renderTarget;

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.SetRenderTarget(_renderTarget);

GraphicsDevice.Clear(Color.Black);

SpriteBatch.Begin(sortMode: SpriteSortMode.Deferred, samplerState: SamplerState.PointClamp);

foreach( TmxLayer Layer in mCurrentTileMap.Layers)
{
for (int y = 0; y < mCurrentTileMap.Height; y++)
{
for (int x = 0; x < mCurrentTileMap.Width; x++)
{
TmxLayerTile Tile = Layer.Tiles[mCurrentTileMap.Width * y + x];
int TileID = -1;
Texture2D Texture = FindTileMapTextureForTileID(Tile.Gid, out TileID);
if (TileID > 0)
{
int atlasX = TileID % (Texture.Width / TileSize);
int atlasY = TileID / (Texture.Width / TileSize);

SpriteEffects FX = SpriteEffects.None;
if (Tile.HorizontalFlip)
{
FX = SpriteEffects.FlipHorizontally;
}

SpriteBatch.Draw(Texture, new Vector2(x * TileSize, y * TileSize), new Microsoft.Xna.Framework.Rectangle(atlasX * TileSize, atlasY * TileSize, TileSize, TileSize), Color.White, 0, Vector2.Zero, 1, FX, 0);
}
}
}
}

SpriteBatch.End();

GraphicsDevice.SetRenderTarget(null);

SpriteBatch.Begin(sortMode: SpriteSortMode.Immediate, blendState: BlendState.NonPremultiplied,
samplerState: SamplerState.PointClamp, transformMatrix: CameraManager.pInstance.pFinalTransform);
SpriteBatch.Draw(_renderTarget, Vector2.Zero, Color.White);
SpriteBatch.End();
}

请注意,我已将相机变换移至第二个 SpriteBatch.Begin调用并推出新的_renderTarget成员变量。不要忘记声明_renderTarget在调用 Draw 之前的某处。像这样的事情:

_renderTarget = new RenderTarget2D(graphicsDevice, width*tileWidth, height*tileHeight);

它需要足够大才能渲染您的 map 。理想情况下,它会被优化为仅渲染 map 的可见部分,但那是另一个故事了。

关于xna - 在 MonoGame 中使用 "Wrap"模式时看到 "Clamp"纹理(含图片),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34626732/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com