1.鏡面-鏡面光線傳輸計算
只涉及主光線計算而渲染出來的圖像無法真實表現現實中的光線照射,通過增加能夠反射光線的材質,進行空間中具有反射材質的對象之間的反射光線的追蹤,可以更好地體現真實感。
2.光線鏡面反射的計算
當光線與包含反射材質的物體進行碰撞后,計算反射方向,追蹤計算得到的反射光線即可,因為光線可能在空間中無限的反射下去,為了避免這種情況,一般定義一個最大的追蹤深度。根據反射光線與空間的交互可能存在的四種情況,分別返回相應的結果:
- 反射光線沒有碰撞到任何物體,直接返回背景顏色
- 反射光線碰撞到漫反射材質對象,則返回漫反射材質對象上該點處的顏色
- 反射光線碰撞到鏡面反射材質對象,則繼續追蹤碰撞點產生的光線,將追蹤的結果返回
- 光線與光源碰撞,直接返回光源的顏色
3.一個典型的渲染結果
在場景中,一個水平面上放置兩個球體,紅色球體擁有鏡面反射材質,另一個則為漫反射材質,渲染結果如圖所示:
#####鏡面反射着色代碼: ```c++ Color Reflective::Shade(const ShadeRecord& shade_rec) const { Color color(Phong::Shade(shade_rec));
Vector3f in_dir;
Vector3f out_dir = -shade_rec.ray_.dir_;
HitRecord hit_rec = shade_rec.hit_rec_;
Color refl_color = refl_func_.SampleF(shade_rec.hit_rec_, in_dir, out_dir);
Ray refl_ray(shade_rec.hit_rec_.p_hit_, in_dir);
color += refl_color * shade_rec.world_.tracer_->TraceRay(shade_rec.world_, refl_ray, hit_rec.depth_ + 1)
* Dot(in_dir, shade_rec.hit_rec_.n_hit_);
return color;
}
</br>
#####場景設置代碼:
```c++
std::shared_ptr<World> Build()
{
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<Reflective>(Color(256.0 / 256.0, 20.0 / 256.0, 20.0 / 256.0),
0.4, 0.6, 20, 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;
}