首页 文章

根据使用正交投影的X / Y位置忽略深度缓冲区

提问于
浏览
1

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

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

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

Square comparaison

方块是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位置时,都隐藏了隐藏纹理 . 根据评论,我添加了有关我期望的信息 .

1 回答

  • 0

    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;
            }
        }
    

相关问题