【问题标题】:Transparent objects in OpenGl ES 2.0OpenGL ES 2.0 中的透明对象
【发布时间】:2013-11-07 20:26:41
【问题描述】:

所以我一直在 Android 上使用 OpenGL ES 2.0,但现在遇到了一个我无法解决的问题。提前道歉,看来我不允许发布超过两个链接(还),所以我将我的三张图片放在 Photobucket 相册here

我正在尝试创建一个由透明区域(“彩色玻璃”)包围的 3D 环境。为了看看它是否有效,我还在里面放了一个不透明的立方体。我启用了以下功能:

GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

现在图片看起来像这样(屏幕截图 1)。不错,但不完全是我想要的:后面的(下)墙和右边的墙应该是可见的,因为我正在看的墙是透明的。

然后我找到that并尝试在绘制不透明对象之前使用GLES20.glDepthMask(true);,在绘制透明对象之前使用GLES20.glDepthMask(false);,以及在绘制不透明对象时禁用混合。

结果(屏幕截图 2)看起来很混乱。但后来我有了另一个想法,不是关闭对深度缓冲区的写入,而是完全关闭GLES20.DEPTH_TEST,同时绘制透明对象。

那(屏幕截图 3)让我最接近我正在寻找的图片。您终于可以看到后墙和右侧墙了,但是由于在绘制不透明物体时禁用了深度测试,立方体被后墙部分覆盖,这是不应该的。

有人知道如何获得我想要的效果吗?

【问题讨论】:

  • 你在这里是正确的。至少您分别绘制不透明几何体和半透明几何体(并且可能首先完成不透明传递)。但是,当您使用此混合模式时,您还需要从后到前对半透明几何图形进行排序。但是,您肯定希望在进行半透明传递时保持启用深度测试,因为应该允许不透明几何体遮挡半透明几何体。
  • 是的,我先做不透明的对象。我读过关于使用透明度时从后到前绘制(否则从前到后)的信息,但是,我希望避免这种情况,因为我想移动相机(显示在屏幕上的 POV)很多,我不知道有一种方法可以可靠地检测何时应该绘制哪个透明对象。您说“[...] 当您使用此混合模式时。”,这是否意味着还有另一种可能更适合的混合模式?我不熟悉可以与 glBlendFunc(..) 一起使用的选项。为什么使用 glDepthMask(..) 有它的效果?
  • 1.这是一个与顺序相关的混合函数,还有与顺序无关的附加混合函数......它们会将当前片段添加到帧缓冲区,而不是基于 alpha 分量进行调制(几乎肯定不是你想要的)。 2. 如果你禁用深度写入,那么你的半透明几何体不会更新深度缓冲区——换句话说,它不会阻塞额外的半透明几何体层。这就是您需要深度排序的原因,您需要确保没有尚未绘制的深度较深的多边形以使 Alpha 混合起作用。
  • 顺便说一下,如果你有相互交叉的半透明多边形,事情就会变得复杂。在这种情况下,您必须至少绘制一个多边形两次。顺序相关性在计算机图形学中并不是一个漂亮的话题,目前所有顺序无关透明度的解决方案都相当复杂。除了 SEGA Dreamcast,没有任何商品硬件/软件可以简单地说:“独立混合这个订单”。
  • @Andon M. Coleman +1 明确指出没有独立的混合顺序功能。计算机图形领域的几乎每个人都应该知道这一点。

标签: android opengl-es opengl-es-2.0


【解决方案1】:

认为我解决了它。我的意思是它适用于我的情况,但我不知道这是否只是巧合......

我像往常一样启用深度测试和混合。然后,在绘图时,我先绘制不透明的形状,然后再绘制透明的形状,就像以前一样。但是,在绘制透明形状时,我将GLES20.glDepthMask(..) 关闭以不写入深度缓冲区,从而绘制所有未被不透明形状覆盖的透明形状。我以前做过(图 2),但它完全搞砸了,但我现在反过来做 - 禁用透明形状的深度蒙版,而不是不透明的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    相关资源
    最近更新 更多