gpt4 book ai didi

java - OpenGL ES 2.0/3.0 中有很多对象时出现 alpha 混合问题

转载 作者:行者123 更新时间:2023-12-01 14:27:16 25 4
gpt4 key购买 nike

游戏 3D 场景有很多对象(背景、小行星、火箭):

private Background background;
private Asteroid[] asteroids = new Asteroid[NUMBER_ASTEROIDS];
private Rocket[] rockets = new Rocket[NUMBER_ROCKETS];
...
public void onDrawFrame(GL10 glUnused) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
...
background.draw();
for (Asteroid asteroid: asteroids) asteroid.draw(); // draw all asteroids
for (Rocket rocket: rockets) rocket.draw(); // draw all rockets
...
}

小行星和火箭的物体使用 alpha 混合:

public class IceAsteroid extends Object3D implements Asteroid {
...
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
... // draw an object with a texture
GLES20.glDisable(GLES20.GL_BLEND);
...
}

public class Rocket extends Object3D {
...
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
... // draw an object without a texture
GLES20.glDisable(GLES20.GL_BLEND);
...
}

一般来说,半透明对于 3D 场景效果很好,除了当火箭在小行星后面时它们(火箭)是不可见的。似乎此时小行星的透明度不起作用,虽然小行星后面的背景是可见的。谁能建议为什么在小行星后面看不到火箭?提前致谢!

注意:我尝试这样做:

background.draw();
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
for (Asteroid asteroid: asteroids) asteroid.draw(); // draw all asteroids
for (Rocket rocket: rockets) rocket.draw(); // draw all rockets
GLES20.glDisable(GLES20.GL_BLEND);

但这并没有解决问题。

解决方案:根据Rabbid76的建议,我将所有的半透明物体按照从后到前的顺序排序:

Comparator<Object3D> comparatorByZ = (objectA, objectB) -> {
Float z1 = objectA.getZ();
Float z2 = objectB.getZ();
return z1.compareTo(z2);
};
...
background.draw();
Collections.sort(transparentObjects, comparatorByZ);
for (Object3D object3D: transparentObjects) object3D.draw();

就我而言,这就足够了。

最佳答案

你不能同时拥有,Blending以及 Depth Test 的好处.您必须分两次绘制场景。先绘制不透明物体,开启深度测试,关闭混合,然后绘制透明物体,开启深度测试,但不写入深度缓冲区,开启混合,从后往前排序。参见 Transparency Sorting .

  1. 启用深度测试并禁用混合
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthMask(GLES20.GL_TRUE);
GLES20.glDisable(GLES20.GL_BLEND);
  1. 绘制不透明物体

  2. 启用深度测试,禁用写入深度缓冲区并启用混合

GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthMask(GLES20.GL_FALSE);
GLES20.glEnable(GLES20.GL_BLEND);
  1. 按照从后到前的顺序绘制透明物体。

如果不对透明对象进行排序,则与不透明对象相比,透明对象仍将正确排列,但透明对象本身可能无法正确排列。当您使用混合时,顺序很重要。混合函数不是 commutative , 改变覆盖透明物体的顺序结果是不同的。

关于java - OpenGL ES 2.0/3.0 中有很多对象时出现 alpha 混合问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61890341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com