光线追踪算法—阴影绘制

1.阴影的作用

阴影效果在真实感图像生成中提供给图像更多的真实感,并且能够为场景提供某些定性分析,如光照的位置、光照的范围等信息。

阴影可以看为光源看不到的地方,即从光源往各个方向发送光线,则光线无法照射到的区域则为阴影。
在光线追踪中,从观察光线与物体的碰撞点向光源引一条光线,光线方向指向光源,若该光线在到达光源之前碰撞到某些物体,则该点位于阴影中。

2.阴影的生成实现

阴影的生成如同上述所讲一样,只需在碰撞点往光源方向引一条光线,然后判断光线是否与物体相交,然后根据相交与否产生相应的颜色。

具体的代码如下(c++实现):

Color Phong::Shade(const ShadeRecord& shade_rec) const
{
  Vector3f out_dir = -shade_rec.ray_.dir_;
  const std::vector<LightPtr>& lights = shade_rec.world_.lights_;
  Color out_color = ambient_func_.rho(shade_rec, out_dir) * shade_rec.world_.ambient_light_->light();

  for (int i = 0; i < lights.size(); ++i) {
    Vector3f in_dir = lights[i]->GetShadowRayDir(shade_rec);
    Float n_dot_in = Dot(shade_rec.n_hit_, in_dir);

    if (n_dot_in > 0.0) {
      if (lights[i]->CastShadows() && !lights[i]->InShadow(shade_rec.p_hit_, shade_rec.world_.objects_)) {
        out_color += (diffuse_func_.f(shade_rec, out_dir, in_dir)
                      + specular_func_.f(shade_rec, out_dir, in_dir)) *
          shade_rec.world_.lights_[i]->light() * n_dot_in;
      }
    }
  }
  return out_color;
}


3.一个实际的渲染图

给出一个实际的阴影生成效果图,渲染图的场景设置代码如下:

std::shared_ptr<World> BuildShadow()
{
  std::shared_ptr<World> world = std::make_shared<World>(std::make_shared<RayCast>());

  world->AddLight(std::make_shared<PointLight>(Point3f(400, 400, -200), 3.0));
  world->AddSurface(std::make_shared<Sphere>(Point3f(50, 0, -500), 50,
                                             std::make_shared<Phong>(Color(198.0 / 256.0, 113.0 / 256.0, 113.0 / 256.0), 0.2, 0.6, 5, 0.2)));
  world->AddSurface(std::make_shared<Sphere>(Point3f(0, -20, -400), 30, Color(25.0 / 256.0, 25.0 / 256.0, 112.0 / 256.0)));
  world->AddSurface(std::make_shared<Plane>(Point3f(0, -50, 0), Normal3f(0, 1, 0), Color(0.3, 0.3, 0.3)));

  return world;
}

#####渲染效果: ![](http://images2015.cnblogs.com/blog/674364/201604/674364-20160428230247533-287088809.png)
posted @ 2016-04-28 23:27  Leptus  阅读(1582)  评论(0编辑  收藏  举报