如何在2.5D世界中同时使用深度测试和纹理透明度?


11

注意:我已经找到了答案(我将在这个问题之后发布)-我只是想知道我是否做对了,或者是否有更好的方法。

我正在使用OpenGL ES(JOGL)制作“ 2.5D”等距游戏。“ 2.5D”是指世界是3D,但使用2D等距图块进行渲染。

我必须解决的原始问题是必须按顺序(从后到前)渲染纹理,以便图块正确重叠以产生合适的效果。经过一番阅读,我很快意识到这是2D的“老帽子”方法。由于玩家可以修改3D世界(因此东西可以出现在3D空间中的任何地方),因此很难有效地做到这一点-因此,我利用深度缓冲区似乎是合乎逻辑的。这意味着我不必担心以正确的顺序渲染内容。

但是,我遇到了一个问题。如果将GL_DEPTH_TESTGL_BLEND一起使用,则会创建一种效果,在将对象与背景混合之前,先按z顺序对其进行“排序”(这意味着您应该在透明度应达到的地方获得一种奇怪的重叠)。

透明度重叠问题

这是一些应该说明问题的伪代码(顺便说一句,我在Android上使用libgdx)。

create() {
    // ...
    // some other code here
    // ...

    Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL10.GL_BLEND);
}

render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

    // ...
    // bind texture and create vertices
    // ...
}

所以问题是:如何解决透明度重叠问题?


2
只是一条评论,告诉您,我使用2D引擎的方式与您完全相同:首先尝试变得聪明,自己对Z-sort进行平铺,然后意识到没有理由使场景平整,从而给我的平铺Z坐标并激活alpha测试。不确定您是否正确,但您并不孤单:-)
sam hocevar 2011年

Answers:


7

好,所以这是我的解决方案(如果可以做得更好,请发表评论)...

事实证明,我实际上应该使用alpha测试(尽管我是偶然发现的,所以我不完全确定为什么会这样)。

create() {
    // ...
    // some other code here
    // ...

    Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL10.GL_ALPHA_TEST);
}

render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    Gdx.gl10.glAlphaFunc(GL10.GL_GREATER, 0);

    // ...
    // bind texture and create vertices
    // ...
}

使用注意事项GL_ALPHA_TEST,和glAlphaFunc


它也解决了我的问题。感谢分享。您很棒
Mathlover 2014年

2

Alpha测试用于停止渲染器将像素绘制到任何缓冲区(包括z缓冲区)。Alpha混合只是一种视觉效果-值仍会写入zbuffer中,这可能会导致类似的问题-不可见像素位于后续渲染像素的前面,这意味着在绘制新像素时它们将无法通过ztest。这就是您在给定的图像中看到的ztest失败。

关闭z写入也将达到相同的目的,但是您必须确保将所有int都拉回到最前面。在您的等距游戏中,这应该很容易做到。


1
我认为,只有在您拥有固定的Y平面并且设计师完全掌控整个世界的情况下,在2D iso游戏中从头到尾绘制内容才是容易的。但是,当填充物可以存在于3D空间中的任何位置,并且您允许用户更改填充物时,它将变得更加复杂。我认为使用深度缓冲将使我的生活更加轻松。
尼克·博尔顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.