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" 到视图。
我这样设置正交矩阵:
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" 到视图。