在前面将框架都搭建好后,我们终于可以开始进行场景的渲染了。

3.1 光线追踪理论

3.1.1 几何光学

几何光学认为光线沿着直线传输。是计算机图形学里面广泛采用的模型。

计算机图形学虽然采用的是几何光学模型,但是其模型的复杂度依然不使用于实时渲染情景,也因此有了一些简化后的假设:

3.1.2 光线追踪

image.png

光线追踪的假设即于光线沿直线传播光路可逆,我们假设眼睛是一个点,其可以接收到光线带来的色彩信息。那么通过从眼睛向各个方向射出射线并追踪这些射线求出其交点就可以知道眼睛所能看到的最近的物体颜色,再从交点处反射光线,如果反射到了物体则重复这一步骤(直到设置的光线最大反射上限为止),如果反射到了光源上则说明这一点被照亮了。

3.2 重构

便于我们下一步的开发,我们将对目前不多的代码进行重构并规划和后面的类之间的关系。因为笔者在书写本文的过程中与书写代码进程同步,因此很多地方都需要在面临需求后重新考虑。

image.png

3.2.1 改写Canvas

Canvas 目前有个自维护的Color数组,而从逻辑上来说,Canvas 只需要知道需要渲染的内容是什么,因此维护m_tex 这个变量即可。我们将维护贴图数据的职责转移到PathTracer 类中,Canvas 仅需要暴露UpdateTexRender 两个方法。

3.2.1.1 改写后的canvas.hpp

#ifndef REALTIME_RAYTRACER_CANVAS_HPP
#define REALTIME_RAYTRACER_CANVAS_HPP

#include "color.hpp"

class Canvas {
private:
    ~~Color *m_pixels;~~
    ~~unsigned char *m_texData;~~
    int m_width, m_height;
    unsigned int m_tex;

public:
    ~~Canvas(int width, int height);~~
    Canvas();
    ~Canvas();

    ~~void WriteInPixel(const Color &color, int x, int y);~~
    ~~void UpdateTex();~~
		void UpdateTex(unsigned char* pixels, int w, int h);

    void Render() const;
};

#endif //REALTIME_RAYTRACER_CANVAS_HPP

3.2.1.2 重新实现UpdateTex方法