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

时间:2011-01-13 17:18:04

标签: c# xna textures

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

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方法中的代码。它产生了这个结果: the first image http://oi53.tinypic.com/av4tv7.jpg

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

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

4 个答案:

答案 0 :(得分:7)

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

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

  1. 设置DepthBufferEnable和 DepthBufferWriteEnable为true

  2. 绘制所有不透明几何

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

  4. 按字母排序alpha混合对象 距离相机的距离,然后画出 他们按顺序从后到前

  5. Shawn Hargreaves从Depth sorting alpha blended objects提取

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:-2)

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

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