本篇内容来自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有的哪些东西,这里基本都会有。
在这次作业中,我们主要需要实现的任务有以下这些:
- 一个通用的纯虚Object3D类,并从这个类派生出Sphere类,实现相应的bool Intersect(const Ray &r, Hit &h, float tmin);接口,用于与射线的相交计算。ps:射线Ray,碰撞点Hit类已经实现并给出,直接使用。最后tmin则是碰撞点到相机的距离(深度)
- 再由Object3D派生出一个Group类,有一个Object3D的数组(由一些基础的图形组成图形组),依然需要实现Intersect接口。
- 一个通用的纯虚Camera类,并派生出OrthographicCamera,并实现virtual Ray generateRay(Vec2f point) = 0;virtual float getTMin() const = 0;两个接口。Vec2f point 是来自屏幕上的像素点。
- 使用提供的输入文件解析代码来加载Camera,Background Color,及场景中的物体等信息
- 实现一个主函数来读取场景,循环遍历屏幕(图片)上的像素点,并根据当前相机生成一个个射线,射线与场景中的物体相交得到相交点的颜色和深度,把颜色和深度显示到对应的屏幕(图片)上。
从上面内容看,是不是比较怪异,更简单总结一下就是:场景中有一系列物体,从屏幕上的每一个像素出发,根据当前相机类型生成一条射线,求这条射线与场景中的物体最近交点,改交点的颜色和深度就是最终屏幕上该像素的颜色及深度,如果不相交则为背景颜色和最大深度,最后把颜色和深度写入到对应的图片中。
其实这样的显示方式跟当前的渲染流程是完全不一样的。因为这样的渲染方式需要大量复杂的相交运算及场景空间管理,且也不太适合硬件流程化批量处理等等。也就是这样的流程比较适合软渲染(就是使用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个球的不同变幻及位移)
网友评论