计算 PerspectiveCamera 的视锥体 FOV [英] Calculating frustum FOV for a PerspectiveCamera

查看:19
本文介绍了计算 PerspectiveCamera 的视锥体 FOV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

(此特定示例的值只是假定的,当然可能会因屏幕而异).

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

  1. 游戏区.可以放大.尺寸为 1080x1277 像素(宽x高),位于顶部.
  2. HUD(此处的仅供参考的对象可以移动到区域 (1).不可缩放.尺寸为 1080x154(宽x高).

两者都有自己的相机.

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

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

浮点数 = 1f;浮动 halfHeight = 大小 * 0.5f;halfHeight *= (float) 154/(float) 1080;浮动全高 = 2 * 半高;浮动 halfFovRadians = MathUtils.degreesToRadians * camera.fieldOfView * 0.5f;浮动距离 = halfHeight/(float) Math.tan(halfFovRadians);相机.viewportWidth = 1080;相机.viewportHeight = 154;camera.position.set(0f, 0, 距离);camera.lookAt(0, 0, 0);相机.更新();

然后我创建了一个对象:

ModelBuilder builder = new ModelBuilder();builder.begin();builder.node();MeshPartBuilder meshBuilder = builder.part("格子", GL20.GL_TRIANGLES,VertexAttributes.Usage.Position,新材料(ColorAttribute.createDiffuse(Color.GRAY)));BoxShapeBuilder.build(meshBuilder, 0f, 0f, 0f, 7f, 1f, 0f);模型模型 = builder.end();mHudModel = new ModelInstance(model);

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

我正在尝试使用与

相机平截头体的近平面和远平面之间的对象映射到 NDC 的范围 (-1, 1).
(进一步查看 如何在现代 OpenGL 中使用片段着色器中的 gl_FragCoord.z 线性渲染深度?)

这意味着如果你想看到1.0更近的物体,那么你必须将到近平面的距离设置为小于1.0.

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

I currently have a screen consisting of two areas:

(Values are just assumed for this particular example and may of course vary depending on screen).

The screen in total is 1080x1432px (WxH) and consists of two areas, each clipped using glViewPort. This because I want area (1) not to fill the screen when zooming.

  1. Game area. Can be zoomed. The size is 1080x1277px (WxH) and located at the top.
  2. The HUD (FYI objects from here can be moved to area (1). Non zoomable. The size is 1080x154 (WxH).

Both have their own cameras.

Area (1) width is 15f and the height is more than 15f (does not matter as long as it's at least 15f).

I want area (2) to be 7f in width and 1f in height (for convenience). Thus I want to set the camera accordingly. I've tried to do this by calculating the 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();

And I create a object:

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

If I manually try to set distance to 1f I can still view the box, but if I go below 1.0f the box won't display. And the distance being calculcated is approx 0.76f.

I am trying to use the same concept as https://xoppa.github.io/blog/a-simple-card-game/ to calculate the FOV. It works fine for area (1).

Can I not use the camera like this? Do I calculate the FOV incorrectly? Why would my object disappear when I go below 1f in distance?

Thanks.

解决方案

The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. It transforms from eye space to the clip space, and the coordinates in the clip space are transformed to the normalized device coordinates (NDC) by dividing with the w component of the clip coordinates. The NDC are in range (-1,-1,-1) to (1,1,1).
Every geometry which is out of the NDC is clipped.

The objects between the near plane and the far plane of the camera frustum are mapped to the range (-1, 1) of the NDC.
(See further How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader?)

This means if you want to see objects that are nearer then 1.0, then you have to set the distance to the near plane less than 1.0.

Note, the near plane and the far plane should be as close as possible to the scene, to increase the computational accuracy and to avoid z-fighting, but they must include everything you want to see from the scene.

这篇关于计算 PerspectiveCamera 的视锥体 FOV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆