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

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

作者: 七火 | 来源:发表于2017-10-14 22:08 被阅读0次

    本篇内容来自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个球的不同变幻及位移)

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/hyspjxtx.html