2012-03-10 227 views
2

所以我试图找出在OpenGL中渲染3D模型的最佳方式,其中一些纹理应用于Alpha通道。在OpenGL中渲染具有Alpha的纹理的3D模型

当我启用了深度缓冲区并开始绘制3D模型中的所有三角形时,如果它在模型中绘制了另一个三角形前面的三角形,它在获取后三角形时不会渲染它到它。问题在于前三角形具有透明度,并且应该能够看到它后面的三角形,但后面的三角形仍然不呈现。

禁用深度缓冲区可以消除这个问题,但会产生一个明显的问题,即如果三角形不透明,那么如果渲染之后它仍然会在顶部渲染三角形。

例如,我试图渲染一棵松树,基本上是一些锥体堆叠在彼此的顶部,有一个透明的基地。下图显示了启用深度缓冲时所产生的问题:

Depth Buffer Enabled

你可以看你怎么还能看到透明三角形的轮廓。

下图显示了深度缓冲区禁用时的样子。

Depth Buffer Disabled

在这里你可以看到一些在树后面的三角形都在树的其余部分的前面渲染。

任何想法如何解决这个问题,并正确渲染松树?

P.S.我正在使用着色器渲染一切。

回答

5

如果您没有使用任何部分透明度(一切都是0或255),您可以使用 glEnable(GL_ALPHA_TEST) ,这应该对您有所帮助。问题是,如果你先渲染顶锥,它会将整个四边形存放到z缓冲区(甚至是透明部分),所以下面的下面的分支在被绘制的时候被拒绝。如果Alpha测试未通过alpha测试 (使用glAlphaFunc设置) ,则启用alpha测试不会将像素写入z缓冲区。

如果您想要使用部分透明度,则需要从后到前或从下到上对呈现对象的顺序进行排序。

您还需要启用z-buffer。

哎呀,我意识到这些功能我不相信在你使用着色器时工作。在着色器的情况下,如果alpha值接近于零,则要在片段着色器中使用丢弃函数。

if(color.a < 0.01) { 
    discard; 
} else { 
    outcolor = color; 
} 
+3

...或者在片段着色器中使用“丢弃”,如果alpha在任何环境中低于所需的阈值(不支持alpha测试(如ES 2.0或WebGL))。 – Tommy 2012-03-10 02:56:02

+1

当你有着色器时(在桌面OpenGL中)它们可以工作。当你使用[核心OpenGL 3.1或更高版本](http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts)时,不起作用的是alpha测试。 – 2012-03-10 03:28:07

+0

@Tim所以我尝试使用放弃,它似乎删除片段着色器执行的任何颜色更改。但是,它似乎完全不影响深度缓冲区。使用放弃时,我会得到与深度缓冲区已启用的图片中显示的结果相同的结果。 – Jeremy 2012-03-10 03:28:57

-2

我可能是错的,但是这是因为当你在3D渲染使用的DirectX的默认设置,你就没有渲染三角形的背面,当Z为删除 - 它吸引过来,从而,与Z上它不再绘制三角形的背面。 即使启用了Z,也可以显示三角形的两侧,但我想这可能是它通常启用的原因..例如速度..

Device->SetRenderState(D3DRS_CULLMODE, Value); 

值可以等于

D3DCULL_NONE - Shows both sides of triangle 
D3DCULL_CW - Culls Front side of triangle 
D3DCULL_CCW - Default state 
0

您需要实现双通道算法。

第一次只渲染背面,而第二次渲染只渲染正面。

通过这种方式,您不需要对三角形进行排序,但是根据您的几何体是否凸起,某些工件可能会出现。