金属:使用正交投影矩阵时不会渲染任何内容



我正在使用以下代码创建正交矩阵:

Matrix4D Matrix4D::fromOrtho(double left, double right, double bottom, double top, double nearZ, double farZ)
{
    double ral = right + left;
    double rsl = right - left;
    double tab = top + bottom;
    double tsb = top - bottom;
    double fan = farZ + nearZ;
    double fsn = farZ - nearZ;
    return Matrix4D ( 2.0f / rsl, 0.0f, 0.0f, 0.0f,
                     0.0f, 2.0f / tsb, 0.0f, 0.0f,
                     0.0f, 0.0f, -2.0f / fsn, 0.0f,
                     -ral / rsl, -tab / tsb, -fan / fsn, 1.0f);
}

并使用以下参数:

double widthToHeightRatio = screenWidth / screenHeight;
Matrix4D::fromOrtho(-10, 10, -7, 7 ,0.1, 5000);

左侧、右侧、底部和顶部参数实际上是作为相机眼睛和中心坐标的函数计算的,但这是结果参数的一个示例。

同样的矩阵可以很好地与OpenGL配合使用,但不能与Metal配合使用。当矩阵是透视矩阵时,在Metal中一切都很好。

可能是什么问题?

GL的透视矩阵和正交投影矩阵在Metal中都无效,因为z范围不同。有些矩阵可能仍然有效,因为OpenGL中的z剪辑范围太深,所以它恰好足够深,可以让碎片在Metal中通过,但这是一件不好的事情。

来自《金属编程指南》,第51页"使用视口和像素空间坐标":

Metal将其标准化设备坐标(NDC)系统定义为2x2x1立方体,其中心位于(0,0,0.5)。x的左侧和底部NDC系统的x和y分别被指定为-1。权利NDC系统的x和y的顶部分别指定为+1.

这与OpenGL不同,OpenGL在2x2x2立方体中的z从-1到1。

有关更多详细信息,请参阅此博客文章:http://blog.athenstean.com/post/135771439196/from-opengl-to-metal-the-projection-matrix

更新--用户da1发现了另一篇博客文章,上面的内容当前已关闭:http://metashapes.com/blog/opengl-metal-projection-matrix-problem

来自AAPLTransfer。mm这对我有效(金属样品项目)

simd::float4x4 AAPL::ortho2d(const float& left,
                             const float& right,
                             const float& bottom,
                             const float& top,
                             const float& near,
                             const float& far)
{
    float sLength = 1.0f / (right - left);
    float sHeight = 1.0f / (top   - bottom);
    float sDepth  = 1.0f / (far   - near);
    simd::float4 P;
    simd::float4 Q;
    simd::float4 R;
    simd::float4 S;
    P.x = 2.0f * sLength;
    P.y = 0.0f;
    P.z = 0.0f;
    P.w = 0.0f;
    Q.x = 0.0f;
    Q.y = 2.0f * sHeight;
    Q.z = 0.0f;
    Q.w = 0.0f;
    R.x = 0.0f;
    R.y = 0.0f;
    R.z = sDepth;
    R.w = 0.0f;
    S.x =  0.0f;
    S.y =  0.0f;
    S.z = -near  * sDepth;
    S.w =  1.0f;
    return simd::float4x4(P, Q, R, S);
} // ortho2d

并通过传递到中的着色器来实现

constant_buffer[i].modelview_ortho_matrix = ortho2d(-2.0f, 2.0f, -2.0f, 2.0f, 0, 2); //_projectionMatrix * modelViewMatrix;

然后可能在你的顶点着色器中

float4 in_position = float4(float3(vertex_array[vid].position), 1.0);
out.position = constants.modelview_ortho_matrix * in_position;

相关内容

  • 没有找到相关文章

最新更新