我正在尝试在android上构建一个3d透明地球(在水域的地方有透明区域),我正在这样做的方法是用Libgdx创建一个球体模型,然后用.png填充它。透明水域的地球纹理。它工作正常,除了我禁用剔除面(能够看到球体的背面)后,我观察到一些三角形缺失,当我旋转三维模型时背面消失:Pic1,{{ 3}}。如果我以其他角度旋转球体,它可以很好地工作,我可以毫无问题地看到地球的背面。
我在这里放了一些相关代码:
渲染:
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
camController.update();
modelBatch.begin(cam);
modelBatch.render(instance, environment);
modelBatch.end();
我已经为DepthTestAttribute尝试了所有可能的值,但似乎没有办法摆脱这种非常奇怪的效果。请给我一些建议,非常感谢。
答案 0 :(得分:0)
这看起来像透明度和深度测试之间的典型冲突。
绘制一个透明像素,但是会向深度缓冲区写入一个值,导致其背后的像素 - 应该是可见的 - 由于深度测试失败而被丢弃。
这里也是如此。首先绘制前面的一些元素 - 写入深度缓冲区,即使部分是半透明的 - 因此不会绘制其后面的元素。
快速而肮脏的修复方法是通过启用alpha测试(或在以后的OpenGL版本中将其丢弃在着色器中)来丢弃alpha值低于特定阈值的像素。但是,这在大多数情况下会导致可见的伪影。
更好的方法是将地球的各个元素/三角形相对于相机从后向前排序,然后按顺序绘制它们。
上阅读OpenGL wiki答案 1 :(得分:0)
在一般几何体的情况下,一种常见的方法是对三角形进行排序,并按照前后顺序渲染它们。
然而,由于球体的特殊属性,我相信有一种更简单,更有效的方法应该可以很好地运作。对于球体,您始终只有一层背面三角形和一层正面三角形。因此,如果首先渲染后向三角形,然后是前置三角形,则会得到一个顺序,其中先前渲染的三角形永远不会出现在稍后渲染的三角形之前,这足以获得正确的透明度渲染。
您已经想出如何仅渲染正面三角形:通过启用背面的剔除。除了调用正面之外,仅渲染背面三角形是一回事。所以代码看起来像这样:
glBlendFunc(...);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glClear(...);
glCullFace(GL_FRONT);
// draw sphere
glCullFace(GL_BACK);
// draw sphere