2016-11-05 3 views
1

메탈이 스위프트를 사용하고 macOS를 타겟팅하는 방식을 배우고 있습니다. 상황은 괜찮아 졌어.하지만 지금은 물건을 얻는 것에 가깝다. 내가 이해할 수없는 문제가 발생했다. 너희들이 나를 도와주기를 바란다. :)메탈 법선이 보간하지 않습니다.

OBJ 찻 주전자, 나는 ambiant + diffuse + specular light를 사용하여 조명하고있다. 조명 자체는 잘 작동하지만 문제는 조각 쉐이더로 갈 때 법선 벡터가 보간되지 않아 곡선 표면에 평평한 조명이 나타나는 것입니다 ... 좋지 않음 ...

정말 그렇지 않습니다. 사전에

감사합니다 :)

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

그래서 문제가 있습니다. OBJ-C를 사용하여 OBJ 파일에서 정점을 인덱싱 할 때 표면 사이의 공유 꼭지점에 대해서만 1 개의 정점을 생성 했으므로 1을 정상적으로 유지했습니다.

swift로 변환 할 때, 내가 정점이 이미있는 곳과 같은지 확인하기 위해 사용했던 해시 값이 잘못되어 공유 된 정점을 감지 할 수 없어서 모든 법선을 유지하게되었습니다. 각 표면은 편평하다.

내가 충분히 명확한 지 모르겠지만, 그게 무슨 일이 있었는지, 미래의 참고를 위해,이 질문은 Obj-C 인 "metalbyexample"책의 Swift 버전을 만드는 것에 관한 것이었다.

관련 문제