【问题标题】:The depth buffer is ignored depending the X/Y position using an orthographic projection根据使用正交投影的 X/Y 位置忽略深度缓冲区
【发布时间】:2018-12-11 16:24:12
【问题描述】:

使用 libgdx,我想使用深度缓冲区丢弃被遮挡的精灵。为此,我将提供的 Decal 和 DecalBatch 与 OrthographicCamera 一起使用,并手动设置 z 位置。

根据我的精灵在 x 和 y 轴上的位置,深度缓冲区是否按预期工作。

红色方块 z = 98 绿色正方形 z = 10

正方形是 50% 透明的,所以我可以看到深度测试是否按预期进行。

这里是测试代码:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.decals.CameraGroupStrategy;
import com.badlogic.gdx.graphics.g3d.decals.Decal;
import com.badlogic.gdx.graphics.g3d.decals.DecalBatch;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import fr.t4c.ui.GdxTest;

public class DecalTest extends GdxTest {
    DecalBatch batch;
    Array<Decal> decals = new Array<Decal>();
    OrthographicCamera camera;
    OrthoCamController controller;
    FPSLogger logger = new FPSLogger();

    Decal redDecal;
    Decal greenDecal;

    public void create() {

        camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        //camera.near = 1;
        camera.position.set(600, 600, 100);
        camera.near = 1;
        camera.far = 100;

        controller = new OrthoCamController(camera);

        Gdx.input.setInputProcessor(controller);
        batch = new DecalBatch(new CameraGroupStrategy(camera));

        TextureRegion[] textures = {
                new TextureRegion(new Texture(Gdx.files.internal("src/test/resources/redsquare.png"))),
                new TextureRegion(new Texture(Gdx.files.internal("src/test/resources/greensquare.png")
                ))};

        redDecal = Decal.newDecal(textures[0], true);
        redDecal.setPosition(600, 600, 98f);
        decals.add(redDecal);

        greenDecal = Decal.newDecal(textures[1], true);
        greenDecal.setPosition(630, 632f, 10f);
        decals.add(greenDecal);

        Decal decal = Decal.newDecal(textures[0], true);
        decal.setPosition(400, 500, 98f);
        decals.add(decal);

        decal = Decal.newDecal(textures[1], true);
        decal.setPosition(430f, 532f, 10f);
        decals.add(decal);
    }

    public void render() {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
        Gdx.gl.glDepthFunc(GL20.GL_LEQUAL);

        camera.update();
        for (int i = 0; i < decals.size; i++) {
            Decal decal = decals.get(i);
            batch.add(decal);
        }
        batch.flush();
    }

    @Override
    public void dispose() {
        batch.dispose();
    }

    public static void main(String[] args) {
        LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
        cfg.useGL30 = false;
        cfg.width = 640;
        cfg.height = 480;
        cfg.resizable = false;
        cfg.foregroundFPS = 0; // Setting to 0 disables foreground fps
        // throttling
        cfg.backgroundFPS = 0; // Setting to 0 disables background fps
        new LwjglApplication(new DecalTest(), cfg);
    }
}

这是一个深度缓冲区精度问题,是相机的方向搞砸了计算还是其他什么?

编辑: 如果精灵在另一个精灵后面,我希望它们会被遮挡。所以在我的例子中,红色方块应该遮挡住他前面的绿色部分。 左下方的方块具有正确的行为,但右上方的方块没有。事情是红色方块具有相同的 Z 值,绿色方块也具有相同的 Z 值(当然与红色方块 Z 不同)。因此,唯一使方形对不同的是它们的 x 和 y 位置,这不应该影响深度测试。

所以,我想要的是一种一致的深度测试行为,它可以遮挡隐藏的纹理,正如我们看到的左下角方块,无论它们的 x 和 y 位置如何。 根据评论,我添加了有关我期望的信息。

【问题讨论】:

  • 不清楚是什么问题?写更多信息,你想得到什么
  • 我在编辑部分添加了一些解释。
  • 您说“正方形是 50% 透明的,因此我可以查看深度测试是否按预期进行。”然后“如果精灵在另一个精灵后面,我希望精灵被遮挡。”。它们是透明的还是不透明的?在我看来,在这两个例子中,红色方块都在绿色方块的前面,但其中一个是透明的,另一个不是。如果你只有一个红色和一个绿色方块并移动它们会发生什么?
  • 所有精灵在 50% 时都是透明的。因此,如果它们像右上角的方块一样混合在一起,则意味着深度测试无法正常工作,因为显示了红色方块后面的绿色像素。如果深度测试按我的预期工作,它确实像左下角的方块(尽管它们是透明的,但它们不会混合,因为绿色像素被丢弃了)。这个解释清楚吗?
  • 这不是深度缓冲区问题,而是顺序问题。所有不透明网格应首先从前到后绘制,然后所有透明网格应从后到前绘制。在您的情况下,透明的前面对象可能在其后面的对象之前绘制。

标签: libgdx depth-buffer orthographic decal


【解决方案1】:

Decal 和 DecalBatch 依赖 GroupStrategy 进行深度排序,而不是相机。此外,这些策略通过与相机的距离或仅通过 Z 轴对深度进行排序,这对于透视相机来说是必需的,即贴花更接近并且应该由 Z 测量而被遮挡,可能会更远地通过与相机的距离来测量.

即(x,y,z) 相机 0,0,1。

贴花 A 1,1,0(Z 距离 1,矢量距离 1.73)

贴花 B 0,0,-0.1(Z 距离 1.1,矢量距离 1.1)

您为上述贴花选择的深度策略可以先考虑 A 或 B。

最常见的推荐GroupStrategy是CameraGroupStrategy,但是这不是按Z排序,而是使用相机距离。如果你用 SimpleOrthoGroupStrategy 初始化 DecalBatch,那么深度将纯粹按 Z 排序,这里是深度排序,你可以查看其他组策略并查看其纯粹的绝对距离。

    class Comparator implements java.util.Comparator<Decal> {
        @Override
        public int compare (Decal a, Decal b) {
            if (a.getZ() == b.getZ()) return 0;
            return a.getZ() - b.getZ() < 0 ? -1 : 1;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 2011-09-21
    相关资源
    最近更新 更多