为什么我的镜面高光是椭圆形的?

时间:2017-07-26 19:26:19

标签: raytracing

我认为这些应该是循环的。我认为我的法线有问题,但我没有发现它们有任何问题。然后,找到一个很好的法线测试很困难。

以下是图片:enter image description here

这是每个灯光的阴影代码,省略了反射的递归部分:

  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,我得到泪珠亮点:

enter image description here

如果我根据交点处的(绝对值)法线对像素进行着色,我得到下面的图像(r = x,g = y,b = z): enter image description here

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。事实证明,法线只是略微偏离,但不足以使法线着色的图像能够描绘它。

我通过计算具有统一比例和平移的球体上的法线来发现这一点。

问题出现在我将法线转换为世界空间的行中:

*norm = glm::normalize(transinv * glm::vec4(glm::normalize(p - sphere_center), 0));

我假设变换后齐次坐标为0,因为事先为零(旋转和刻度不影响它,因为它是0,也不能翻译)。但是,它不是0,因为矩阵是转置的,所以底行填充了反向平移,导致齐次坐标非零。

然后将4矢量归一化,并将结果分配给3矢量。 3向量的构造函数只删除最后一个条目,因此法线保持非标准化。

以下是最终图片: enter image description here