ios - 从 OpenGL 移植到 MetalKit - 投影矩阵(?)问题

标签 ios opengl metal metalkit projection-matrix

问题

我正在致力于在 iOS 上从 OpenGL (OGL) 移植到 MetalKit (MTK)。我无法在应用程序的 MetalKit 版本中获得相同的显示。我修改了投影矩阵以解决两个框架之间标准化设备坐标的差异,但不知道还需要更改哪些内容才能获得相同的显示。您知道还需要更改哪些内容才能从 OpenGL 移植到 MetalKit 吗?

到目前为止投影矩阵的变化...

据我所知,OGL 与 MTK 中的标准化设备坐标 (NDC) 不同:

  • OGL NDC:-1 < z < 1
  • MTK NDC:0 < z < 1

我修改了投影矩阵以解决 NDC 差异,如 here 所示。不幸的是,对投影矩阵的这种修改不会导致与旧 OGL 代码相同的显示。

我什至不知道还能尝试什么。

背景

以下是一些其他背景信息,供引用:

  • View 矩阵非常简单(单位矩阵);即相机位于 (0, 0, 0)并展望(0, 0, -1)
  • 在旧版 OpenGL 代码中,我使用 GLKMatrix4MakeFrustum使用 left 的屏幕边界生成投影矩阵, right , top , bottom ,和near=1 , far=1000

我在调试时将场景精简到只剩下骨架,下面是 2 个图像,第一个来自旧版 OGL 代码,第二个来自 MTK,两者都只显示带有调试纹理和黑色背景的“地面”平面。

如果您有任何关于可能需要更改哪些内容才能在 MetalKit 中获得相同显示的想法,我们将不胜感激。

屏幕截图

OpenGL(旧版)

OpenGL Scene

Metal 套件

MetalKit Scene

编辑 1

我尝试提取与投影矩阵的计算和使用相关的代码:

float aspectRatio = 1.777; // iPhone 8 device
float top = 1;
float bottom = -1;
float left = -aspectRatio;
float right = aspectRatio;
float RmL = right - left;
float TmB = top - bottom;
float nearZ = 1;
float farZ = 1000;

GLKMatrix4 projMatrix = {   2 * nearZ / RmL,     0,                      0,                               0,
                            0,                   2 * nearZ / TmB,        0,                               0,
                            0,                   0,                      -farZ / (farZ - nearZ),          -1,
                            0,                   0,                      -farZ * nearZ / (farZ - nearZ),  0 };

GLKMatrix4 viewMatrix = ...; // Identity matrix: camera at origin, looking at (0, 0, -1), yUp=(0, 1, 0);
GLKMatrix4 modelMatrix = ...; // Different for various models, but even when this is the identity matrix in old/new code the visual output is different
GLKMatrix4 mvpMatrix = GLKMatrix4Multiply(projMatrix, GLKMatrix4Multiply(viewMatrix, modelMatrix));

...

GLKMatrix4 x = mvpMatrix; // rename for brevity below
float mvpMatrixArray[16] = {x.m00, x.m01, x.m02, x.m03, x.m10, x.m11, x.m12, x.m13, x.m20, x.m21, x.m22, x.m23, x.m30, x.m31, x.m32, x.m33};

// making MVP matrix available to vertex shader
[renderCommandEncoder setVertexBytes:&mvpMatrixArray
                              length:16 * sizeof(float)
                             atIndex:1]; // vertex data is at "0"

[renderCommandEncoder setVertexBuffer:vertexBuffer
                               offset:0
                              atIndex:0];

...

[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
                         vertexStart:0
                         vertexCount:4];

最佳答案

遗憾的是,这个问题最终是由于顶点着色器中的错误导致 Z 轴上的所有几何体 +1,从而导致视觉差异。

对于任何 future 的 OpenGL-to-Metal 移植者:考虑到标准化设备坐标的差异,上面的投影矩阵变化就足够了。

关于ios - 从 OpenGL 移植到 MetalKit - 投影矩阵(?)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58573636/

相关文章:

ios - 在没有 xib 文件的情况下更改我的标签栏颜色

c++ - 从过剩教程中了解宏测量数组计数

c++ - 获取 "undefined reference to ` glBegin'“到以前的工作项目,make 文件中需要更新什么?

python - Python 写的 3D OpenGL 游戏能不能好看跑得快?

ios - 为 iOS Metal 中的 MTLBuffer 使用的数据分配内存

ios - Flutter iOS-在模拟器上运行的应用无法部署到iphone-未找到-lFirebaseCore的库

iphone - iOS 支持佳能 RAW 格式吗?

android - 在 iOS 中,我们在 Android 上是否有类似 Gradle Build Flavors 的东西

swift - Metal block 渲染

ios - Metal :iPhone 5/iOS 8 上为 "Failed creating a default system device!"