2016-11-05 10 views
1

私はメタルがスウィフトを使ってどのように動作し、macOSをターゲットにしているかを学んできました。事は大丈夫ですが、今は、物事を終わらせることに近い、私は理解できない問題を打ちました...皆さんが私を助けてくれることを願っています:メタルノーマルは補間されません

私はロードしていますOBJティーポット。私は、光る+拡散+鏡面光を使って照明しています。照明自体はうまくいきますが、問題は:フラグメントシェーダーに行くときに法線ベクトルが補間されないため、曲面上にフラットな照明ができます...いいえ...

私は本当にありません事前に

感謝:)

struct Vertex 
{ 
    float4 position; 
    float4 normal; 
}; 

struct ProjectedVertex 
{ 
    float4 position [[position]]; 
    float3 eye; 
    float3 normal; 
}; 

vertex ProjectedVertex vertex_project(device Vertex *vertices [[buffer(0)]], 
             constant Uniforms &uniforms [[buffer(1)]], 
             uint vid [[vertex_id]]) 
{ 
    ProjectedVertex outVert; 
    outVert.position = uniforms.modelViewProjectionMatrix * vertices[vid].position; 
    outVert.eye = -(uniforms.modelViewProjectionMatrix * vertices[vid].position).xyz; 
    outVert.normal = (uniforms.modelViewProjectionMatrix * float4(vertices[vid].normal)).xyz; 

    return outVert; 
} 

fragment float4 fragment_light(ProjectedVertex vert [[stage_in]], 
           constant Uniforms &uniforms [[buffer(0)]]) 
{ 
    float3 ambientTerm = light.ambientColor * material.ambientColor; 

    float3 normal = normalize(vert.normal); 
    float diffuseIntensity = saturate(dot(normal, light.direction)); 
    float3 diffuseTerm = light.diffuseColor * material.diffuseColor * diffuseIntensity; 

    float3 specularTerm(0); 
    if (diffuseIntensity > 0) 
    { 
     float3 eyeDirection = normalize(vert.eye); 
     float3 halfway = normalize(light.direction + eyeDirection); 
     float specularFactor = pow(saturate(dot(normal, halfway)), material.specularPower); 
     specularTerm = light.specularColor * material.specularColor * specularFactor; 
    } 

    return float4(ambientTerm + diffuseTerm + specularTerm, 1); 
} 

screenshot

:ここで結果を表示するために、私のシェーダや画像です...他の値(位置+眼が)している間に補間されていない理由を、通常の理解
+0

データの外観によって多少異なります。法線はどのように計算されますか?頂点が共有されているのではなく複製されている場合、このような外観が期待されます(法線は各面で一定です)。 – warrenm

+0

実際、問題は、OBJローダの法線を各三角形の法線に従って生成し、各頂点が同じ法線を持ち、隣接する三角形が法線を共有していないことです。変わったことは、同じコードがObj-Cを使って動作するので、同じ結果が得られない理由がわからない...私は両方とものそれぞれの法線を監視し、理由を理解しようとするだろう。ありがとう助けのために:) –

答えて

0

So problem wa OBJ-Cを使って、OBJファイルから頂点を索引付けしたとき、面間の共有頂点に対して1つの頂点しか生成しなかったので、私は1つだけ正常に保ちました。

これをswiftに変換すると、頂点が私が既に持っているものと同じ場所にあるかどうかをチェックするために使用したハッシュ値が間違っていて共有頂点を検出できず、結果としてすべての法線各面は平坦である。

私は十分にはっきりしているかどうかは分かりませんが、それは起こったことです。将来の参照のために、Obj-Cのみの「metalbyexample」ブックのSwift版を作成することでした。

関連する問題