Nam*_*los 5 camera fieldofview perspective libgdx
我有问题要理解libGDX中透视摄像机的视野(或者我的计算错误).
我想画一个盒子(例如800px宽,480px高和20px深).该框位于x轴和y轴之间(换句话说:x轴上的宽度和y轴上的高度).现在我想站在x轴(摄像机位置)的方框后面,朝一个方向看,我看到了我屏幕右侧的方框.我做了一些草图:



在最后一个草图上,该框位于视野的右侧.
而且,盒子的高度必须恰好适合屏幕.换句话说:盒子的顶部边缘必须位于我的屏幕顶部,盒子的底部边缘必须位于我的屏幕底部.以下是一些实现此目的的代码和计算:
public class Box implements ApplicationListener {
public PerspectiveCamera camera;
public float SCREEN_WIDTH;
public float SCREEN_HEIGHT;
@Override
public void create() {
SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px
// Create camera (90°) and set position
camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
camera.position.set(SCREEN_WIDTH + SCREEN_HEIGHT/2, SCREEN_HEIGHT/2, 0f);
camera.lookAt(0f, SCREEN_HEIGHT/2, 0f);
camera.near = 1;
camera.far = 2 * SCREEN_WIDTH;
camera.update();
}
@Override
public void render() {
Gdx.gl.glClearColor(Color.WHITE.r, Color.WHITE.g, Color.WHITE.b, Color.WHITE.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
// Build the box - width is screenwidth and height is screenheight - one corner in origin
ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
MeshPartBuilder mpb = modelBuilder.part("ID", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal,
new Material(ColorAttribute.createDiffuse(Color.GREEN)));
// bottom left corner of the box should be in (0,0,0)
mpb.box(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, -10f, SCREEN_WIDTH, SCREEN_HEIGHT, 20f);
Model model = modelBuilder.end();
ModelInstance instance = new ModelInstance(model);
// Build some light
Environment environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
// Draw the box
ModelBatch modelBatch = new ModelBatch();
modelBatch.begin(camera);
modelBatch.render(instance, environment);
modelBatch.end();
}
}
Run Code Online (Sandbox Code Playgroud)
为了适应屏幕中的盒子高度,我必须退后一步SCREEN_HEIGHT/2,因为x = SCREEN_HEIGHT/2/tan(45°)= SCREEN_HEIGHT/2/1 = SCREEN_HEIGHT/2,这就是我将这个长度添加到x-component的原因在位置设置中.
代码代表草图2并给我正确的截图:

为了实现草图3,我必须将我的视野向左旋转45°.但在这方面,我必须退一步,因为视野的两侧比中心线长.我做了两个手绘草图:

其中h = SCREEN_HEIGHT.首先,我必须计算x.x = h/2/sin(45°)= h/sqrt(2).现在我必须向后退一段x并向新方向看(距离方框45°).为了计算我要看的点,我在这个草图上计算长度y:

y = sin(45°)*h/2 = h*sqrt(2)/ 4.所以,关键是例如(SCREEN_WIDTH +(xy),SCREEN_HEIGHT/2,y).现在我改变了我的代码中的位置和观点:
public void create() {
SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px
// Create camera (90°) and set position
camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
float x = (float) (SCREEN_HEIGHT / Math.sqrt(2));
float y = (float) (SCREEN_HEIGHT * Math.sqrt(2)/4f);
camera.position.set(SCREEN_WIDTH + x, SCREEN_HEIGHT/2, 0f);
camera.lookAt(SCREEN_WIDTH + x - y, SCREEN_HEIGHT/2, y);
camera.near = 1;
camera.far = 2 * SCREEN_WIDTH;
camera.update();
}
Run Code Online (Sandbox Code Playgroud)
我得到这个屏幕:

但是盒子不是在右边:(
所以现在的问题是:出了什么问题?我对视野的看法是错误还是我的计算?
最好的祝福!
您对 的理解PerspectiveCamera有点偏差,特别是它对第二个(viewportWidth)和第三个(viewportHeight)参数的作用。
对它们所做的唯一事情PerspectiveCamera就是获取纵横比并用它来设置projectionMatrix. 对于它使用的具体代码,请参阅计算长宽比的这一行和设置.projectionMatrix
现在一切都很好,除了您还需要计算处理纵横比,并且执行两次会导致相机再次拉伸。解决方案很简单,要么重做数学,不调整纵横比,要么替换
camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
Run Code Online (Sandbox Code Playgroud)
和
camera = new PerspectiveCamera(90f, 1, 1);
Run Code Online (Sandbox Code Playgroud)
使 libgdx 计算的纵横比为1。
我不太擅长正弦和余弦,所以我无法提供第一个选项的解决方案,但你似乎没有遇到任何困难的数学问题。
| 归档时间: |
|
| 查看次数: |
2326 次 |
| 最近记录: |