3D基元,XNA 4.0上的透明纹理问题

我需要画一大堆立方体,每一面都有(可能)独特的纹理。 一些纹理也具有透明度的部分。 具有透明纹理的立方体后面的立方体应通过透明纹理显示。 但是,我绘制立方体的顺序似乎决定了透明度是否有效,这是我想要避免的。 看这里:

cubeEffect.CurrentTechnique = cubeEffect.Techniques["Textured"]; Block[] cubes = new Block[4]; cubes[0] = new Block(BlockType.leaves, new Vector3(0, 0, 3)); cubes[1] = new Block(BlockType.dirt, new Vector3(0, 1, 3)); cubes[2] = new Block(BlockType.log, new Vector3(0, 0, 4)); cubes[3] = new Block(BlockType.gold, new Vector3(0, 1, 4)); foreach(Block b in cubes) { b.shape.RenderShape(GraphicsDevice, cubeEffect); } 

这是Draw方法中的代码。 它产生了这个结果: 第一张图片http://oi53.tinypic.com/av4tv7.jpg

如您所见,叶子立方体后面的纹理在另一侧是不可见的。 当我在数组中反转索引3和0时,我得到这个: 正确的形象

很明显,绘图的顺序正在影响立方体。 我怀疑它可能与混合模式有关,但我不知道从哪里开始。

您依靠深度缓冲来实现遮挡。 此技术仅适用于不透明对象。

要为包含透明对象的场景实现正确的遮挡:

  1. 将DepthBufferEnable和DepthBufferWriteEnable设置为true

  2. 绘制所有不透明的几何体

  3. 将DepthBufferEnable设置为true,但将DepthBufferWriteEnable更改为false

  4. 按照距相机的距离对alpha混合对象进行排序,然后按照从后到前的顺序绘制它们

由Shawn Hargreaves从深度排序alpha混合对象中提取

正确地绘制透明对象比常规对象更难。 原因是默认情况下渲染面部时,它会将所有像素标记为在特定深度绘制,因此后面的像素根本不会被绘制。 我建议你买一本关于3d渲染的书,然后查看更多细节。

您已经找到的最简单的方法 – 在非透明对象之后绘制透明对象。 适用于转化和半透明物体。 请注意,需要对透明对象进行排序才能正确绘制(与非透明对象不同)。

在您的特定情况下(非半透明),您可以将纹理渲染更改为不渲染透明部分的任何内容。

如果对象上没有半透明像素,则可以使用此方法。 它要么完全呈现,要么不会写入Z-Buffer。 与Riemers Alpha Testing一样 。

XNA(以及DirectX和所有主要的3D库)都考虑了一些叫做剔除的东西。 虽然从你的代码我无法确定,从图像我认为这是你的问题。 您没有看到的多边形的顶点顺序错误。 如果这是问题,您有两个解决方案:

  • 要么剔除( device.RenderState.CullMode = CullMode.None;如果我没记错的话)
  • 应用纹理两次,多边形的点按顺时针顺序和逆时针顺序排列