MIT.6.837
MIT 6.837
Assignment0:
Hint:
- 依概率选择变换矩阵:
1 |
|
- 需要特判仿射变换后点坐标是否在图像内
- int atoi(const char *str); 将字符串数字变为int
Result:
- fern:
1 |
|
- dragon:
1 |
|
- giant X:
1 |
|
- triangle iters 30 times:
1 |
|
Assignment1:
原理:相机从每个像素发出射线,显示最早击中物体的贴图
Hint:
- Orthographic Camera:
- 在坐标运算时,最好在[0,1]标准化空间坐标进行,在遇到实际的屏幕时,可以用x = x’ widht; y = y’ height来换算
- Image类中颜色坐标范围是[0,1]
- 输出t在[depth_min, depth_max]之间的灰度,要在Clamp之后,作如下变换:
1 |
|
隐式表示的球体求交点:
- Ray: direction is an unit vector
如果d比球半径要大,说明Ray与Sphere不相交,反之Ray与Sphere相交
相交在参数t时刻,射线原点在球内:
射线原点在球外:
判断物体射线交点,如果得到t比hit的t小,那么同时更新t和Material
1 |
|
- 类Group中的ObjectList应该用Object3D**类型,因为ObjectList应当是存Object3D的指针的数组,赋予ObjectList内存空间:
1 |
|
- std::numeric_limits\
::max 返回float最大值 - 三个向量定义相机:Up, Right, LookAt,当Up和LookAt不垂直时要修正Up:
- Right = LookAt x Up: 通过叉乘得到Right向量
- Up = Right x LookAt: 通过上一步得到的Right向量和LookAt向量,修正Up向量
- 相机的三个向量需要标准化
Result:
1 |
|
1 |
|
1 |
|
Assignment2 Transformations & Additional Primitives
Task
- [x] Implement the new rendering mode, normal visualization:
读取射线击中点的法向量,取法向量分量的绝对值作为rgb分量的值
1 |
|
- [x] Add diffuse shading
任务要求加入diffuse(依赖光线与法线向量)与ambient,物体在该点最终的颜色为diffuse color + ambient color:
漫反射颜色计算:
- 光线在物体背面时n dot I 为负,这时我们diffuse设为0
- 作业要求加入shade back选项,故当光线在物体背面,并要求shade back时,diffuse = - n dot I
- 多束光线作用物体,diffuse为这些作用的总和
环境光计算:ambient color = ambient coefficient * material
1 |
|
- [x] Perspective Camera
通过up, direction, center三个向量可以确定一个透视投影相机
- 三个向量必须标准化
- up可能不与direction垂直,要利用horizontal向量使up和direction垂直
1
2
3
4
5
6
7
8PerspectiveCamera::PerspectiveCamera(Vec3f _center, Vec3f _direction, Vec3f _up, float _angle_radius):
center(_center), direction(_direction), up(_up), angle_randians(_angle_radius){
direction.Normalize(); //标准化方向向量
Vec3f::Cross3(horizontal, direction, up); //通过叉乘direction, up向量得horizontal向量
Vec3f::Cross3(up, horizontal, direction); //通过叉乘horizontal, direction向量使up与direction向量垂直
up.Normalize(); //标准化up向量
horizontal.Normalize(); //标准化horizontal向量
}透视投影相机如何打出射线?
1 |
|
- [x] Plane
通过平面一点和平面法向量可以确定平面方程,我们可以这样定义平面:P dot n = d,故通过normal和d可以唯一确定一个平面
- 射线相交判断:
- 射线方向向量与平面法向量垂直:射线与平面平行,不相交
- 将Ray的方程带入平面,得到t
- t >= tmin,相交;
- t < tmin,不相交;
1 |
|
- [x] Triangle
射线与三角形求交判断:
方法1:利用重心坐标 Barycentric
根据克拉默法则,若|A|=0,则方程无解,Ray不与三角形所在平面相交
- 若t<tmin,Ray与三角形不相交
- 若方程有解,且t>=tmin,0<α<1, 0<β<1, 0<γ<1,则Ray与三角形相交
方法2:先与三角形所在平面求交点,再判断交点是否在三角形内部
如何判断三角形平面上的点是否在三角形内部?
从这一点随机射出射线,与三角形有奇数个交点,则在内部,偶数个交点,在外部
- 需要特判顶点
通过重心坐标判断是否在三角形内部
[x] Derive a subclass
Transform
fromObject3D
对物体做变换后与Ray求交,可以通过对射线做变换实现
是否要标准化变换后的方向向量:
- Normalize: tOS ≠ tWS
- Don’t Normalize: tOS = tWS
纠正变换后物体的法向量:
纠正变换后的法向量需要用到法矩阵:
Hint
MIT提供的Transform相关的代码有点反人类,习惯上对向量做变换用矩阵M左乘向量v:Mv。例如对v先后做变换M1, M2, M3的M矩阵应为:
1 |
|
但scene_parser.C中解析变换矩阵时使用如下代码:
1 |
|
然后Matrix.C中的Transform(Vec4f)代码如下:
1 |
|
相当与Mv,还是左乘,相当于列表中的变换顺序与我们想要的变换顺序是相反的
对Ray进行变换时,若单位化了direction向量,则需要改变Object3D的intersect函数,以Plane为例:
1 |
|
- 变换到世界坐标的法向量必须标准化
Result
- scene 6:
maybe some bugs in normal shader?
1 |
|
- scene 7 shade back:
1 |
|
- scene 7 don’t shade back:
1 |
|
- bunny 200 triangles:
1 |
|
- bunny 1k triangles:
1 |
|
- scene 13:
1 |
|
- scene 14:
1 |
|
- scene 15:
1 |
|
- scene 16:
some bugs in green sphere and purple sphere?
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!