OpenGL ES 2.0:从正交到透视(卡片翻转效果)

OpenGL ES 2.0: From orthogonal to perspective (card flip effect)

我这样设置正交矩阵:

ratio = (float) width / height;
left = -ratio;
right = ratio;
bottom = -1f;
top = 1f;
Matrix.orthoM(projectionMatrix, 0, left, right, bottom, top, -1f, 1f);
viewProjMatrix = projectionMatrix;

创建一些图块是这样完成的:

float widthF = (right - left) / numColumns; // left to right
float heightF = (bottom - top) / numRows; // top to bottom
for (int row = 0; row < numRows; ++row) {
    for (int col = 0; col < numColumns; ++col) {
        float x1 = left + col * widthF;
        float y1 = top + row * heightF;
        float x2 = left + (col + 1) * widthF;
        float y2 = top + (row + 1) * heightF;
        float z = 0f;
        // and so on, add to vertex buffer
    }
}

结果是:

如果我使用透视矩阵而不是正交矩阵,这看起来会更好:

Matrix.frustumM(projectionMatrix, 0, left, right, bottom, top, 1f, 10f);
Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 2f, 0f, 0f, 0f, 0f, 1f, 0f);
Matrix.multiplyMM(viewProjMatrix, 0, projectionMatrix, 0, viewMatrix, 0);

结果是:

但是,如何让图像显示在"full screen",即填满视口?正交矩阵填充视口的方式,但这次是透视。

(此卡片翻转效果灵感来自 Flux Slider 的 Tiles3D 过渡)

投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。投影矩阵从视图space转换为剪辑space,剪辑space中的坐标转换为范围为(-1, -1)的归一化设备坐标(NDC) , -1) 到 (1, 1, 1) 除以剪辑坐标的 w 分量。

在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口的 2D 点的映射。
相机视锥体(截棱锥)中的眼睛 space 坐标映射到立方体(归一化设备坐标)。

视图中的投影区域 space 与视图的 Z 坐标 space 之间的关系是线性的。视场角和长宽比而定。

您必须根据图像调整视野。为此,您必须知道图像到相机位置的距离。

float distZ = ....; // distance of the camera to the image
float sizeX = ....; // width of the rectangle where the image is placed in
float sizeY = ....; // height of the rectangle where the image is placed in

float near = 1f;
float far  = 10f;

float left   = -0.5 * sizeX * near / distZ;
float right  =  0.5 * sizeX * near / distZ;
float bottom = -0.5 * sizeY * near / distZ;
float top    =  0.5 * sizeY * near / distZ;

Matrix.frustumM(projectionMatrix, 0, left, right, bottom, top, near, far);

注意,当然图像必须 "centered" 到视图。