2016-01-20 86 views
3

我已經設置了一個測試項目來學習iOS上的Metal來做一些渲染,但是我對如何使棱鏡正確地圍繞其y軸旋轉有點困難。爲什麼在iOS Metal中旋轉這個棱鏡不能正確渲染?

這裏是沒有深度的測試渲染棱鏡使各方可以看到,所以它看起來像這部分至少是正確的:

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; 

transformlookAtrotate,和perspective_fov功能直接從我用作參考蘋果示例代碼解除。

這裏是着色器:

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; 
} 

任何幫助/提示將不勝感激。

回答

2

感嘆.. 問題在於MVP矩陣與着色器中頂點的乘法順序。

所以這個:

out.pos = v * mvp_matrix; 

應該是:

out.pos = mvp_matrix * v; 

無論出於何種原因,我已經習慣了行向量而不是列向量,並有自己相信我誤解的東西有關剪輯區域和/或矩陣本身。

相關問題