我认为这些应该是循环的。我认为我的法线有问题,但我没有发现它们有任何问题。然后,找到一个很好的法线测试很困难。
这是每个灯光的阴影代码,省略了反射的递归部分:
lighting = ( hit.obj.ambient + hit.obj.emission );
const glm::vec3 view_direction = glm::normalize(eye - hit.pos);
const glm::vec3 reflection = glm::normalize(( static_cast<float>(2) * ( glm::dot(view_direction, hit.normal) * hit.normal ) ) - view_direction);
for(int i = 0; i < numused; ++i)
{
glm::vec3 hit_to_light = (lights[i].pos - hit.pos);
float dist = glm::length(hit_to_light);
glm::vec3 light_direction = glm::normalize(hit_to_light);
Ray lightray(hit.pos, light_direction);
Intersection blocked = Intersect(lightray, scene, verbose ? verbose : false);
if( blocked.dist >= dist)
{
glm::vec3 halfangle = glm::normalize(view_direction + light_direction);
float specular_multiplier = pow(std::max(glm::dot(halfangle,hit.normal), 0.f), shininess);
glm::vec3 attenuation_term = lights[i].rgb * (1.0f / (attenuation + dist * linear + dist*dist * quad));
glm::vec3 diffuse_term = hit.obj.diffuse * ( std::max(glm::dot(light_direction,hit.normal) , 0.f) );
glm::vec3 specular_term = hit.obj.specular * specular_multiplier;
}
}
这里是我将对象空间法线转换为世界空间的行:
*norm = glm::normalize(transinv * glm::vec4(glm::normalize(p - sphere_center), 0));
使用完整的phong模型,而不是blinn-phong,我得到泪珠亮点:
答案 0 :(得分:0)
我已经解决了这个问题。事实证明,法线只是略微偏离,但不足以使法线着色的图像能够描绘它。
我通过计算具有统一比例和平移的球体上的法线来发现这一点。
问题出现在我将法线转换为世界空间的行中:
*norm = glm::normalize(transinv * glm::vec4(glm::normalize(p - sphere_center), 0));
我假设变换后齐次坐标为0,因为事先为零(旋转和刻度不影响它,因为它是0,也不能翻译)。但是,它不是0,因为矩阵是转置的,所以底行填充了反向平移,导致齐次坐标非零。
然后将4矢量归一化,并将结果分配给3矢量。 3向量的构造函数只删除最后一个条目,因此法线保持非标准化。