2011-05-12 66 views
1

即时渲染PNG的简单方块在opengl ES 2.0,但是当我尝试和画一个广场后面的东西我已经绘制了我的顶部广场的透明区域呈现与背景相同的颜色。opengl z排序透明

我在每次呈现调用的开始时调用这些函数。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glEnable(GL_DEPTH_TEST); 
glEnable (GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+0

你可以发布一个截图吗? – ChrisF 2011-05-12 21:51:04

回答

5

您的标题基本上就是您的问题的答案!

通常透明度是通过首先渲染场景中的所有不透明对象(让z缓冲区找出可见的东西),然后渲染所有透明对象。

+0

好的,所以我需要先渲染后面的。没有其他解决方法。 – user346443 2011-05-12 22:02:20

+1

@ user346443:没有。这是所有栅格化器的一个基本原理,OpenGL是根据光栅器定义的。顺序独立渲染透明面是一个非常热门的研究课题,但到目前为止所有的方法实现了使用多个渲染目标或类似的背对背排序算法。 – datenwolf 2011-05-12 22:21:44

4

德鲁霍尔给你一个很好的答案,但另一种选择是设置glEnable(GL_ALPHA_TEST)glAlphaFunc(GL_GREATER, 0.1f)。这将防止透明像素(在这种情况下,具有alpha < 0.1f的像素)完全不被渲染。这样他们不会写入Z缓冲区,其他的东西可以“显示”。但是,这只适用于完全透明的对象。它在0.1 alpha边缘的任何地方都有粗糙的边缘,并且对于与对象相比像素较大的远处特征而言,这看起来很糟糕。

+0

在es 2.0中是否存在GL_ALPHA_TEST和glAlphaFunc?我无法找到他们。 – user346443 2011-05-12 22:08:48

+0

如果你正在编写自己的着色器,你可以通过丢弃alpha值低于给定值的任何片段来模拟这种效果。 – 2011-05-13 01:46:20

5

想通了。你可以丢弃在片段着色器中

mediump vec4 basecolor = texture2D(sTexture, TexCoord); 

if (basecolor.a == 0.0){ 
    discard; 
} 

gl_FragColor = basecolor; 
+0

是的,这相当于'GL_ALPHA_TEST'在固定功能流水线中做了什么,除了测试是用'glAlphaFunc'配置的。 – 2011-05-13 01:47:16

+0

我发现这对绘图树时的z排序问题非常有用。虽然我的树被排序回到前面,但有时候两棵密集的树靠得很近,以致它们的距离相等,因此一棵树被拉过另一棵树,引起一个令人讨厌的框。抛出低alpha像素解决了这个问题,但我仍然必须先排序,因为如果我不这样做,粗放弃可能看起来不愉快。 – locka 2013-01-24 14:38:43

+2

这是一个更好的答案,海事组织 - 因为大多数人只是在寻找简单的透明度。半透明需要其他技术,并且这是很有误导性的,有多少人告诉你,如果不进行重新排序(或类似深度剥离),您将无法做到透明。 – 2013-05-18 19:17:13