为什么在iOS Metal中旋转此棱镜无法正确渲染?

时间:2016-01-20 22:26:20

标签: ios rotation shader metal

我已经设置了一个测试项目,用于在iOS上学习Metal来做一些渲染,但我对如何让棱镜绕y轴正确旋转感到有些困惑。

这是在没有深度测试的情况下渲染的棱镜所以可以看到所有方面,所以看起来这部分至少是正确的:

enter image description here

这些是顶点:

static const float vertexData[] = {
     0.f,  1.f,  0.5f,
     1.f, -1.f,  0.f,
    -1.f, -1.f,  0.f,

     0.f,  1.f,  0.5f,
     1.f, -1.f,  1.f,
     1.f, -1.f,  0.f,

     0.f,  1.f,  0.5f,
    -1.f, -1.f,  1.f,
     1.f, -1.f,  1.f,

     0.f,  1.f,  0.5f,
    -1.f, -1.f,  0.f,
    -1.f, -1.f,  1.f
};

但是,当我打开旋转时,会发生以下情况:https://www.dropbox.com/s/esg41j3ibncofox/prism_rotate.mov?dl=0

(该视频已开启深度测试)。为什么棱镜剪裁那样(和/或它是什么剪裁)?它并没有围绕它的中心旋转。

以下是MVP矩阵的计算方法:

static simd::float3 viewEye = {0.f, 0.f, -2.f};
static simd::float3 viewCenter = {0.f, 0.f, 1.f};
static simd::float3 viewUp = {0.f, 1.f, 0.f};
static float fov = 45.f;

CGSize size = self.view.bounds.size;
Uniforms *uniforms = (Uniforms *)[uniformBuffer contents];
uniforms->view = AAPL::lookAt(viewEye, viewCenter, viewUp);
uniforms->projection = AAPL::perspective_fov(fov, size.width, size.height, 0.1f, 100.f);

uniforms->model = AAPL::translate(0.f, 0.f, 12.f) * AAPL::rotate(tAngle, 0.f, 1.f, 0.f);
tAngle += 0.5f;

transformlookAtrotateperspective_fov函数直接取自我用作参考的Apple示例代码。

以下是着色器:

typedef struct {
    float4 pos [[ position ]];
    half4 color;
    float mod;
} VertexOut;

vertex VertexOut basic_vertex(const device packed_float3* vertex_array [[ buffer(0) ]],
                              const device packed_float3* colors [[ buffer(1) ]],
                              constant Uniforms& uniform [[ buffer(2) ]],
                              uint vid [[ vertex_id ]],
                              uint iid [[ instance_id ]])
{
    float4 v = float4(vertex_array[vid], 1.f);
    float4x4 mvp_matrix = uniform.projection * uniform.view * uniform.model;

    VertexOut out;
    out.pos = v * mvp_matrix;
    uint colorIndex = vid / 3;
    out.color = half4(half3(colors[colorIndex]), 1.f);
    return out;
}

fragment half4 basic_fragment(VertexOut f [[ stage_in ]]) {
    return f.color;
}

非常感谢任何帮助/提示。

1 个答案:

答案 0 :(得分:2)

叹息.. 问题在于MVP矩阵与着色器中顶点的乘法顺序。

所以这个:

out.pos = v * mvp_matrix;

应该是:

out.pos = mvp_matrix * v;

无论出于何种原因,我习惯于向量行而不是列向量,并且我自己确信我对剪辑区域和/或矩阵本身有些误解。