光线追踪算法—阴影绘制
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)