课程追忆之《计算机图形学》【光线投射篇】

本篇内容来自MIT大学的《计算机图形学》的光线投射的课后作业,地址如下:
http://groups.csail.mit.edu/graphics/classes/6.837/F04/assignments/assignment1/
http://groups.csail.mit.edu/graphics/classes/6.837/F04/assignments/assignment2/
课程PPT及其他内容,可在下面地址里找到:
http://groups.csail.mit.edu/graphics/classes/6.837/F04/calendar.html
感兴趣的可以看看。

在上一篇博文中,我们使用OpenGL来绘制曲线曲面,认识了曲线曲面、也学习了部分OpenGL的API,而这次我们直接抛弃OpenGL,我们自己造一个。
其实是夸大啦,哈哈!这一节,我们脱离OpenGL,完全使用代码来模拟OpenGL的渲染过程,或者说我们自己实现一个基础的软渲染器,当然其实也只是一个非常简单的光线投射器。而对于OpenGL有的哪些东西,这里基本都会有。

在这次作业中,我们主要需要实现的任务有以下这些:

  1. 一个通用的纯虚Object3D类,并从这个类派生出Sphere类,实现相应的bool Intersect(const Ray &r, Hit &h, float tmin);接口,用于与射线的相交计算。ps:射线Ray,碰撞点Hit类已经实现并给出,直接使用。最后tmin则是碰撞点到相机的距离(深度)
  2. 再由Object3D派生出一个Group类,有一个Object3D的数组(由一些基础的图形组成图形组),依然需要实现Intersect接口。
  3. 一个通用的纯虚Camera类,并派生出OrthographicCamera,并实现virtual Ray generateRay(Vec2f point) = 0;virtual float getTMin() const = 0;两个接口。Vec2f point 是来自屏幕上的像素点。
  4. 使用提供的输入文件解析代码来加载Camera,Background Color,及场景中的物体等信息
  5. 实现一个主函数来读取场景,循环遍历屏幕(图片)上的像素点,并根据当前相机生成一个个射线,射线与场景中的物体相交得到相交点的颜色和深度,把颜色和深度显示到对应的屏幕(图片)上。

从上面内容看,是不是比较怪异,更简单总结一下就是:场景中有一系列物体,从屏幕上的每一个像素出发,根据当前相机类型生成一条射线,求这条射线与场景中的物体最近交点,改交点的颜色和深度就是最终屏幕上该像素的颜色及深度,如果不相交则为背景颜色和最大深度,最后把颜色和深度写入到对应的图片中。

其实这样的显示方式跟当前的渲染流程是完全不一样的。因为这样的渲染方式需要大量复杂的相交运算及场景空间管理,且也不太适合硬件流程化批量处理等等。也就是这样的流程比较适合软渲染(就是使用CPU计算等依赖软件算法的渲染),并且这样的渲染是最理想的渲染方式,完全没有现在的硬渲染的BUG(无法正确绘制互相穿插的半透明物体),也因此该渲染方法会比较多的应用到电影后期及动画中等等。

虽然渲染的流程不一样,但是基础的三维知识确实通用的,比如正交、透视相机,模型变幻等等。
下面继续说这次的作业内容:

1、首先看看一个场景的输入文件,如下所示:

OrthographicCamera {
    center 0 0 10
    direction 0 0 -1
    up 0 1 0
    size 5
}
Lights {
    numLights 1
    DirectionalLight {
        direction -0.2 -0.2 -0.8
        color 0.9 0.9 0.9
    }
}
Background {
    color 0.1 0.5 0.1
    ambientLight 0.1 0.1 0.1
}
Materials {
    numMaterials 2
    Material { diffuseColor 1 0 0 }
    Material { diffuseColor 0 0 1 }
}
Group {
    numObjects 1
    Transform {
        UniformScale  0.5
        XRotate  20
        Translate  -3 0 0
        Group {
            numObjects 2     
            MaterialIndex 0
            Transform {
                Translate  1 0 0
                Transform {
                    ZRotate  45
                    Scale  1 2 1
                    TriangleMesh {
                        obj_file cube.obj
                    }
                }
            }
            MaterialIndex 1
            Transform {
                Translate  6 0 0
                Transform {
                    Scale  1 2 1
                    ZRotate  45
                    TriangleMesh {
                        obj_file cube.obj
                    }
                }
            }
        }
    }
}

在一个场景文件里面会有Camera、Lights、Background、Materials、Group,共计5中类型的定义。

接下来是具体每一个命令的运行结果:

1、raytracer -input scene1_01.txt -size 200 200 -output output1_01.tga -depth 9 10 depth1_01.tga
正交相机、只有背景色(0 0 0)、1个材质(红色)、一个球体,运行结果如下所示:


01.左边为颜色,右边为深度

该命令主要用来检测基础的相机、背景色、材质颜色和场景物件是否能正确显示(输出对应的颜色和深度)

2、raytracer -input scene1_02.txt -size 200 200 -output output1_02.tga -depth 8 12 depth1_02.tga
正交相机、背景色(0.1 0.1 0.1),三个颜色(红、绿、蓝),五个球体


02.左边为五个球体的颜色,右边为深度

该命令主要检测多个球体、材质引用、多物体相交计算是否有误

3、raytracer -input scene1_03.txt -size 200 200 -output output1_03.tga -depth 8 12 depth1_03.tga
在2的基础上改变了相机的up方向的朝向


03.左边为颜色,右边为深度

该命令主要用来测试相机参数及实现是否有误

4、raytracer -input scene1_04.txt -size 200 200 -output output1_04.tga -depth 12 17 depth1_04.tga
在2的基础上修改相机的正方向direction朝向


04.左边为颜色,右边为深度

主要用来测试相机direction参数读取和实现是否有误

5、raytracer -input scene1_05.txt -size 200 200 -output output1_05.tga -depth 14.5 19.5 depth1_05.tga
修改了相机的位置及朝向


05.左边为颜色,右边为深度

也是主要检测相机实现是否有误

6、raytracer -input scene1_06.txt -size 200 200 -output output1_06.tga -depth 3 7 depth1_06.tga
改变球的数量


06.左边为颜色,右边为深度

7、raytracer -input scene1_07.txt -size 200 200 -output output1_07.tga -depth -2 2 depth1_07.tga
在6的基础上改变球的颜色


07.左边为颜色,右边为深度

在完成上面的基础设施(相机、射线、碰撞点、颜色、深度等等),下面我们就需要扩展更多的图元和基础设施了。

上面完成了基本的相机实现、背景色、场景物件、材质索引等等,下面我们来玩玩变幻、法线、背面剔除等。

1、raytracer -input scene2_01_diffuse.txt -size 200 200 -output output2_01.tga
1盏平行光(direction -0.5 -0.5 -1 color 1 1 1),背景(color 0.2 0 0.6 ambientLight 0 0 0)


01.颜色信息

考研平行光的基础计算

2、raytracer -input scene2_02_ambient.txt -size 200 200 -output output2_02.tga
1盏平行光(direction -0.5 -0.5 -1 color 0.5 0.5 0.5 ),背景(color 0.2 0 0.6 ambientLight 0.5 0.5 0.5)


02.颜色信息

3、raytracer -input scene2_03_colored_lights.txt -size 200 200 -output output2_03.tga -normals normals2_03.tga
3盏灯光(direction 0.5 -1 0 color 0.8 0 0 direction -0.5 -1 0 color 0 0 0.8 direction 0 -1 -0.5 color 0 0.8 0)
3盏灯光,分别为红绿蓝,同时输出法线,球为白色,得到如下效果(下图上边的效果):


03.左边为颜色,右边为法线

左边为得到的颜色,右边为法线(x红 y绿 z蓝)ps:相机是倾斜的(OrthographicCamera { center 0 5 5 direction 0 -1 -1 up 0 1 0 size 2.5}),所以能够看到红绿蓝的交汇处

4、raytracer -input scene2_04_perspective.txt -size 200 200 -output output2_04.tga -normals normals2_04.tga
透视相机,给出5个球、一盏灯,输出颜色及法线,效果如下:


04.左边为颜色,右边为法线

左边为颜色、右边为法线(相机是正摆放,所以左右为红,上下为绿,前后为蓝)

5、raytracer -input scene2_05_inside_sphere.txt -size 200 200 -output output2_05.tga -depth 9 11 depth2_05.tga -normals normals2_05.tga -shade_back
raytracer -input scene2_05_inside_sphere.txt -size 200 200 -output output2_05_no_back.tga
透视相机、一个大球包裹一个小球,输出基础颜色、深度图、法线、开启背面剔除


05.左至右分别为:颜色(开启背面渲染)、深度、法线、颜色(关闭背面渲染/开启背面剔除)

6、raytracer -input scene2_06_plane.txt -size 200 200 -output output2_06.tga -depth 8 20 depth2_06.tga -normals normals2_06.tga
透视相机(有旋转),一个灯光,5个球,1个平面,输出颜色、深度、法线图


06.左至右分别为:颜色、深度、法线

7、
raytracer -input scene2_07_sphere_triangles.txt -size 200 200 -output output2_07.tga -depth 9 11 depth2_07.tga -normals normals2_07.tga -shade_back
raytracer -input scene2_07_sphere_triangles.txt -size 200 200 -output output2_07_no_back.tga
透视相机(带旋转)、一个灯光、1个球、2个三角形,输出颜色、深度、法线、开启背面剔除


07.左至右分别为:颜色(开启背面渲染)、深度、法线、颜色(关闭背面渲染)

8、raytracer -input scene2_08_cube.txt -size 200 200 -output output2_08.tga
透视相机、1盏灯光、一个Obj模型(正方形)


08.颜色(立方体)

显示由三角形组成的立方体(obj)

9、raytracer -input scene2_09_bunny_200.txt -size 200 200 -output output2_09.tga
透视相机、1盏灯光、200面的兔子模型且放大5倍


09.颜色(200面的兔子)

10、raytracer -input scene2_10_bunny_1k.txt -size 200 200 -output output2_10.tga
透视相机、1盏灯光、1000面的兔子模型且放大5倍


10.颜色(1000面的兔子)

11、raytracer -input scene2_11_squashed_sphere.txt -size 200 200 -output output2_11.tga -normals normals2_11.tga
正交相机、1盏灯光、1个球带不规则缩放(Scale 1 0.2 1 )


11.左边为颜色、右边为法线

12、raytracer -input scene2_12_rotated_sphere.txt -size 200 200 -output output2_12.tga -normals normals2_12.tga
正交相机、1盏灯光、1个球带旋转(ZRotate 45 )


12.左边为颜色、右边为法线

13、raytracer -input scene2_13_rotated_squashed_sphere.txt -size 200 200 -output output2_13.tga -normals normals2_13.tga
正交相机、1盏灯光、1个球带旋转和缩放(ZRotate 45 Scale 1 0.2 1)


13.左边为颜色、右边为法线

14、raytracer -input scene2_14_axes_cube.txt -size 200 200 -output output2_14.tga
正交相机、1盏灯光、背景黑色、2组物体(3个正方体经过缩放和旋转组成的坐标轴、一个缩放和旋转的正方体)


14.颜色(4个立方体的变幻)

15、raytracer -input scene2_15_crazy_transforms.txt -size 200 200 -output output2_15.tga
正交相机、1盏灯光、背景黑灰色、2个不同缩放、位移、旋转的物体


15.颜色(2个立方体的变幻及位移)

16、raytracer -input scene2_16_t_scale.txt -size 200 200 -output output2_16.tga -depth 2 7 depth2_16.tga
正交相机、1盏灯光、环境光灰色、6个不同位移、缩放的球体,输出颜色和深度图


16.颜色(6个球的不同变幻及位移)

你可能感兴趣的:(课程追忆之《计算机图形学》【光线投射篇】)