【问题标题】:Rendering to a non-null render tarhet in XNA disables antialiasing在 XNA 中渲染到非空渲染目标禁用抗锯齿
【发布时间】:2014-05-30 01:15:45
【问题描述】:

我正在将 3d 模型渲染到 rendertarget2D,然后我使用 sprite 批处理将其绘制到屏幕上。我使用这一行在我的构造函数中启用了抗锯齿:

graphics.PreferMultiSampling = true;

当我将模型直接渲染到后台缓冲区时,抗锯齿按预期工作。现在我正在渲染到 rendertarget2D,抗锯齿不再起作用,并且我得到锯齿状边缘。 (我没有调整或旋转 rendertarget2D。)

请您为我解释一下这个谜团吗?

代码:

public MyGame()
        {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        graphics.PreferredBackBufferHeight = 720;
        graphics.PreferredBackBufferWidth = 1208;
        graphics.PreparingDeviceSettings += setBackbufferPreserveContents;

        graphics.PreferMultiSampling = true;

        this.IsMouseVisible = true;
        this.Window.Title = "MyGame";

        graphics.ApplyChanges();
        }

public void setBackbufferPreserveContents(object sender, PreparingDeviceSettingsEventArgs e)
        {
        e.GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage = RenderTargetUsage.PreserveContents;
        }

protected override void Draw(GameTime gameTime)
        {
        GraphicsDevice.SetRenderTarget(BoardScreen);
        GraphicsDevice.Clear(Color.Transparent);
        Board.DrawMe(cam);

        GraphicsDevice.SetRenderTarget(null);
        GraphicsDevice.Clear(Color.CornflowerBlue);

        sb.Begin();
        sb.Draw((Texture2D)BoardScreen, new Rectangle(0, 0, 720, 720), Color.White);
        sb.End();

        base.Draw(gameTime);
        }

Board 属于 DrawableModel 类,它包含一个模型和方法 DrawMe(Camera camera),它只是将模型绘制到屏幕上。 Camera 是一个简单的类,包含投影和视图矩阵、相机的位置和目标位置。

更新:

DrawMe 方法的作用如下:

public void DrawMe(Camera camera)
        {
        foreach (ModelMesh mesh in ModelToDraw.Meshes)
            {
            foreach (BasicEffect effect in mesh.Effects)
                {
                effect.EnableDefaultLighting();
                effect.PreferPerPixelLighting = true;

                effect.World = Matrix.CreateTranslation(Translation);
                effect.Projection = camera.Projection;
                effect.View = camera.View;
                }
            mesh.Draw();
            }
        }

更新 2:

这是我已经完成的主 XNA 文件中的其余函数(更新和 UnloadContent 尚未更改。):

protected override void Initialize()
        {
        BoardScreen = new RenderTarget2D(graphics.GraphicsDevice, 720, 720);
        base.Initialize();
        }

    protected override void LoadContent()
        {
        sb = new SpriteBatch(GraphicsDevice);
        Board = new DrawableModel(Content.Load<Model>("Models/Board"), Vector3.Zero, Vector3.Zero, Vector3.One);
        }

【问题讨论】:

  • 在 DrawMe() 函数中,您是否使用任何类型的 SamplerState 初始化您的 spritebatch?更具体地说是 PointClamp 采样器状态?
  • 没有。我正在使用一个最小的模型绘图循环,它遍历模型中的网格和每个网格中的效果,为网格启用基本照明和每像素照明,并为每个效果设置世界、投影和视图矩阵网格,然后调用 ModelMesh 实例的 Draw 方法。
  • 有没有可能你的 Draw Rectangle 和你的 RenderTarget (BoardScreen) 大小不一样,导致失真?
  • 它们都是 720x720 像素。

标签: c# xna xna-4.0 antialiasing rendertarget


【解决方案1】:

编辑、更新:

graphics.PreferMultiSampling 仅在后台缓冲区启用抗锯齿。我认为问题可能在于,当绘制到您的渲染目标时,它没有使用抗锯齿进行绘制。

RenderTarget2D 构造函数有一个采用preferredMultiSampleCount 参数的重载。尝试调用它并将 4 作为首选的多样本计数传递。如果这样可行,您也许可以关闭后台缓冲区的多重采样。


旧: 我遇到了同样的问题,因为我在 3D 中渲染以从多边形中创建非方形图块,然后切换到 SpriteBatch 以绘制 2D *。 SpriteBatch.Begin() 在幕后改变了一大堆渲染状态,这将搞砸后续(甚至下一帧)3D 绘制。所以你需要在进行 3D 绘图之前重置这些状态。

There's more detail here 但 IIRC 我需要更改的状态比那篇文章提到的要多。

希望这就是问题所在。

*虽然抗锯齿不是我的问题,但更严重的是它只是没有绘图。

编辑:answer to a similar but not identical question that provides a longer list of the kind of stuff to try reseting


【讨论】:

  • 谢谢,这解决了部分谜团。但是,我对所有 3D 东西都是全新的,所以如果您能像在和孩子说话一样为我拼写出来,我需要做什么来解决这个问题,我将非常感激。 :)
  • 对不起,我想我现在的回答是错误的,这不是您遇到的问题。我用另一个想法更新了答案
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多