我目前正在为一个学校项目开发光线追踪器,在本课程的这一步中,我们需要使用灯光系统和Blinn-Phong算法来实现对象着色。

如果正确完成,下面是最终图像...



在这一点上,我还没有想到反射和阴影,只是想先使阴影起作用,然后继续获得最终的图像...



显而易见,应该具有最高镜面反射率的区域正在变成绿色,并且在茶壶周围的某些地方出现了奇怪的黑色伪影。我已经阅读和测试了几个小时,无法找出原因!我90%确信我正确地实现了算法。

这是我与此问题相关的代码...

void shade(RGB& shading, std::vector<Light> lights, Triangle t, Ray& r, Vector3 loc) {
  float intensity = 1 / std::sqrt(lights.size());

  for (std::size_t i = 0; i < lights.size(); ++i) {
    Vector3 n = t.get_normal();
    n.normalize();
    Vector3 v = r.dir * -1;
    v.normalize();
    Vector3 l = lights[i].position - loc;
    l.normalize();
    Vector3 h = v + l;
    h.normalize();

    float diffuse = MAX(0, n.dot(l));
    float spec = std::pow(MAX(0, n.dot(h)), t.fill.shine);

    shading.r += (t.fill.kd * diffuse * t.fill.rgb.r + t.fill.ks * spec) * intensity;
    shading.g += (t.fill.kd * diffuse * t.fill.rgb.g + t.fill.ks * spec) * intensity;
    shading.b += (t.fill.kd * diffuse * t.fill.rgb.b + t.fill.ks * spec) * intensity;
  }
}

// Main function
int main(int argc, char* argv[]) {

  // Set input and output file names
  std::string in_file = (argc > 1) ? argv[1] : "teapot-3.nff";
  std::string out_file = (argc > 2) ? argv[2] : "output.ppm";

  // Parse the NFF file and get the Viewpoint and Background data
  NFFParser parser(in_file);
  parser.read_file();

  Viewpoint view = parser.getViewpoint();
  Background background = parser.getBackground();

  // Camera creation
  Camera camera(view);

  // Allocate array of pixels and create camera instance
  Pixel* pixels = new Pixel[camera.x_res * camera.y_res];

  // Collect object data to iterate over
  std::vector<Polygon> polygons = parser.getPolygons();
  std::vector<Patch> patches = parser.getPatches();
  std::vector<Light> lights = parser.getLights();
  std::vector<Triangle> triangles;

  // Convert all polygons and patches to trianlges and
  // build a vector of triangles to iterator over
  for (std::size_t i = 0; i < polygons.size(); ++i) {
    std::vector<Triangle> v = polygons[i].fan_to_triangles();
    triangles.insert(triangles.end(), v.begin(), v.end());
  }

  for (std::size_t i = 0; i < patches.size(); ++i) {
    std::vector<Triangle> v = patches[i].fan_to_triangles();
    triangles.insert(triangles.end(), v.begin(), v.end());
  }

  std::cout << "Testing for intersections among objects..." << std::endl
            << "...this may take a moment..." << std::endl
            << "==========================================" << std::endl;


  // Iterator over all pixels in the array
  for (int y = 0; y < camera.y_res; ++y) {
    for (int x = 0; x < camera.x_res; ++x) {

      float t = INF;
      Triangle closest;

      // Map pixel to image plane coordinates
      Vector3 image_location = camera.map_to_image(x, y);
      Ray r(camera.e, image_location - camera.e);

      // Iteration over Polygons
      for (std::vector<Triangle>::iterator it = triangles.begin(); it != triangles.end(); ++it) {
        if (it->intersects(&r, t) && t < r.t_min) {
          closest = *it;
          r.t_min = t;
        }
      }

      if (r.t_min == INF) {
        set_pixel(pixels, y, x, camera.y_res, background.rgb);
        continue;
      }

      RGB shading;

      shade(shading, lights, closest, r, image_location);
      set_pixel(pixels, y, x, camera.y_res, shading);

    }
  }


  // Write the array of pixels to the output PPM file
  PPMWriter writer(out_file);
  writer.write_pixels(pixels, camera.x_res, camera.y_res);

  // Deallocate pixels array to avoid memory leaks
  delete [] pixels;

  return 0;
}


任何指导或帮助将不胜感激!



编辑

绿色是固定的,但是RGB分量有上限,但是黑色伪影仍然是一个问题。

最佳答案

对于绿色位,在颜色计算中,您正在溢出适合像素红色部分的内容。如果查看绿色附近的铜色RGB(0xFE9E4E)与绿色区域中的RGB(0x019D4F),则可以看到这一点。

您需要在计算中包括一些溢出检查。

关于c++ - 光线追踪阴影中的伪影和错误代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42601194/

10-09 19:34