XNA:2D图元与3D模型共存时的渲染问题

来源:互联网 发布:厦门广电网络 营业时间 编辑:程序博客网 时间:2024/05/02 15:18

在XNA开发3D游戏过程中不可避免会用到2D纹理渲染,比如做游戏的主界面、背景图、选项框或者物品库等等,一般使用SpriteBatch方法渲染2D Texture,但这样会导致你的3D模型出错:变透明或是虚化,如果在3D空间中还有2D的图片(如作为空间内地板或者墙壁之用),这部分内容也将比例失常。究其原因是在SpriteBatch.begin()渲染完2D精灵(图片)以后你的3D图形管理器不再能正确使用,SpriteBatch 改变了一些驱动设备的渲染状态值,而这些值修改后令你的3D渲染不能正常工作。
       对于XNA的初学者来说,一种避免这个问题的简易方法是在SpriteBatch.begin()中的SaveStateMode设置为SaveStateMode.SaveState,但是这样会导致一个潜在的缺陷或危险:它使得你的保存和修改驱动设备状态变得更慢。所以你如果经常这么做的话,你的帧速将会受创。

       一种更为有效的方式是在你绘制任何图形图像之前总是设置这些值,而不管你所需要的渲染状态是什么。SpriteBatch将自动修改这些设置值以满足它绘制2D图形图像的需要,所以你只需要在绘制3D图形图像前将它们设置回来就行。

      那SpriteBatch 到底修改了哪些渲染状态呢?以下是完整列表:

   GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
    GraphicsDevice.RenderState.DepthBufferEnable = false;

    GraphicsDevice.RenderState.AlphaBlendEnable = true;
    GraphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;
    GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
    GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
    GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = false;

    GraphicsDevice.RenderState.AlphaTestEnable = true;
    GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Greater;
    GraphicsDevice.RenderState.ReferenceAlpha = 0;

    GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Clamp;
    GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Clamp;

    GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Linear;
    GraphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Linear;
    GraphicsDevice.SamplerStates[0].MipFilter = TextureFilter.Linear;

    GraphicsDevice.SamplerStates[0].MipMapLevelOfDetailBias = 0.0f;
    GraphicsDevice.SamplerStates[0].MaxMipLevel = 0;        SpriteBatch 也修改了GraphicsDevice的Vertices, Indices、VertexDeclaration、VertexShader和PixelShader 属性。

        对于2D和3D渲染,许多这些设置都是好的,但是在你绘制任何3D图形前可能需要重设这些状态,以使GraphicsDevice为3D模型渲染服务:

       GraphicsDevice.RenderState.DepthBufferEnable = true;
       GraphicsDevice.RenderState.AlphaBlendEnable = false;
       GraphicsDevice.RenderState.AlphaTestEnable = false;

        如果你还3D空间中渲染了立体的2D图片、纹理,那你还要设置以下属性:

    GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;     GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;

原文:http://blogs.msdn.com/b/shawnhar/archive/2006/11/13/spritebatch-and-renderstates.aspx

 

 

在做3D与2D混合的时候,由于改变参数要注意,2D的绘制方法

spriteBatch中有一个参数是saveStateMode,可以尝试使用,但会降低性能,需要综合考虑。

当调用Begin的时候会设置许多的参数,而利用SaveStateMode可以将其初始化(None)然后必须重新对这些参数设置,也可以设置成SaveState不进行设置,但是会影响到效果。特别是CullMode这样的参数如果不进行适当的更改而保持不变的话,在3D中效果是很明显不一样的。

 

原创粉丝点击