我一直在学习Metal如何使用Swift并定位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);
}
答案 0 :(得分:0)
问题是使用OBJ-C,当我从OBJ文件索引顶点时,我只为表面之间的共享顶点生成了1个顶点,所以我只保持1个正常。
当它转换为swift时,我用来检查顶点是否与我已经存在的位置相同的哈希值是错误的并且无法检测共享顶点,这导致保留所有法线,因此每个表面平坦。
我不知道我是否足够清楚,但事情就是这样,为了将来的参考,这个问题是关于制作Swift版本的“metalbyexample”一书,它只是Obj-C。