计算PerspectiveCamera的平截头体FOV

时间:2017-09-11 20:50:18

标签: android libgdx opengl-es-2.0 perspectivecamera

我目前有一个由两个区域组成的屏幕:

(这个特定示例的值只是假定的,当然可能因屏幕而异)。

总屏幕为1080x1432px(WxH),由两个区域组成,每个区域使用glViewPort进行剪裁。这是因为我希望区域(1)在缩放时不会填满屏幕。

  1. 游戏区域。可以放大。尺寸为1080x1277px(WxH),位于顶部。
  2. HUD(此处的FYI对象可以移动到区域(1)。不可缩放。大小为1080x154(WxH)。
  3. 两者都有自己的相机。

    区域(1)宽度为15f,高度大于15f(只要它至少为15f就无所谓)。

    我希望区域(2)的宽度为7f,高度为1f(为方便起见)。因此我想相应地设置相机。我试图通过计算FOV来做到这一点:

    float size = 1f;
    float halfHeight = size * 0.5f;
    halfHeight *= (float) 154 / (float) 1080;
    float fullHeight = 2 * halfHeight;
    float halfFovRadians = MathUtils.degreesToRadians * camera.fieldOfView * 0.5f;
    float distance = halfHeight / (float) Math.tan(halfFovRadians);
    
    camera.viewportWidth = 1080;
    camera.viewportHeight = 154;
    camera.position.set(0f, 0, distance);
    camera.lookAt(0, 0, 0);
    camera.update();
    

    我创建了一个对象:

    ModelBuilder builder = new ModelBuilder();
    builder.begin();
    builder.node();
    MeshPartBuilder meshBuilder = builder.part("lattice", GL20.GL_TRIANGLES,
            VertexAttributes.Usage.Position,
            new Material(ColorAttribute.createDiffuse(Color.GRAY)));
    
    BoxShapeBuilder.build(meshBuilder, 0f, 0f, 0f, 7f, 1f, 0f);
    Model model = builder.end();
    mHudModel = new ModelInstance(model);
    

    如果我手动尝试将距离设置为1f,我仍然可以查看该框,但如果我低于1.0f,则该框不会显示。并且计算的距离约为0.76f。

    我尝试使用与https://xoppa.github.io/blog/a-simple-card-game/相同的概念来计算FOV。它适用于区域(1)。

    我可以不这样使用相机吗?我是否错误地计算了FOV?当我在距离1f以下时,为什么我的物体会消失?

    感谢。

1 个答案:

答案 0 :(得分:2)

投影矩阵描述了从场景的3D点到视口的2D点的映射。它从眼睛空间转换到剪辑空间,并且通过用剪辑坐标的w分量进行划分,将剪辑空间中的坐标转换为规范化设备坐标(NDC)。 NDC在(-1,-1,-1)到(1,1,1)的范围内。
每个在NDC之外的几何体都被剪裁。

enter image description here

相机平截头体的近平面和远平面之间的物体被映射到NDC的范围(-1,1)。
(进一步查看How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader?

这意味着如果你想更接近 1.0 的对象,那么你必须设置到近平面的距离小于 1.0

注意,近平面和远平面应尽可能靠近场景,以提高计算精度并避免z-fighting,但它们必须包含您想要从场景中看到的所有内容< / strong>即可。