本次作业完成的是通过正交相机投影+ray casting方式渲染,得到一个场景中有若干个球形的图片,并以深度测试后直接显示色彩和简单限制深度后显示两种方式来显示。
目录
原理
结果
github连接
原理
在不考虑二次反射和多次反射的情况下,Ray casting只需要从相机到当前画布的各个像素投射出一条光线,判断光线是否和场景中的各个物体相交,如果相交,比较出距离相机最近的那个物体予以显示即可;如果不相交,则不做任何其他处理。
首先给出场景中包含的各项数据,然后我再一一说明如何处理。
OrthographicCamera {
center 0 0 10
direction 0 0 -1
up 0.5 1 0
size 5
}Background { color 0.2 0.2 0.2 }
Materials {
numMaterials 3
PhongMaterial {
diffuseColor 1 0 0
}
PhongMaterial {
diffuseColor 0 1 0
}
PhongMaterial {
diffuseColor 0 0 1
}
}Group {
numObjects 5MaterialIndex 0
Sphere {
center 0 0 0
radius 1
}MaterialIndex 1
Sphere {
center 1 1 1
radius 0.75
}
Sphere {
center -1 -1 1
radius 0.75
}MaterialIndex 2
Sphere {
center -1 1 -1
radius 0.75
}
Sphere {
center 1 -1 -1
radius 0.75
}
}
按照伪代码的顺序,我们首先看如何创建一条从相机(或眼睛)出发的光线。
这里需要区分一个点,相机的size和最终显示图片的尺寸并不相等,二者之间的关系可以理解为原本相机的size经过等比放大可变为最终图片。“For every pixel”是针对照片而言的,但具体发射光线是从相机出发的,从照片的尺寸到相机的尺寸是需要压缩的,故先将此时的坐标(x0,y0)归一化得到(x,y)。又因为camera通过中心坐标以代表相机位置,而(x,y)坐标的起始点(0,0)并不是中心,如下图所示。故,要将归一化的(x,y)变为相机size的“成像面”上的某点,则需要进行下图公式所示的变换:
再来说明一下如何判断光线是否和场景中的物体有交点。这里需要说明一下,此次我仅完成了场景中只有球体的类型,如果要考虑其他几何体,只需根据各自几何体的特征,列出代数式子判断是否相交以及相交需要的时间即可,也可通过几何方式来计算。
这一步的任务其实就是求光线和物体是否能在有效时间相遇,这里只讲代数方法。相遇即代表光线的方程和物体的方程相等有解,那么需要先把这二者表示出来,如下:
令二者相等再求解即可,需要注意的是上图示意的球体的球心在坐标原点,实际上的球体可能在任意位置,则,在实际处理时,我直接将Ro减去了球体的球心。
最终求出来的时间,需大于tmin(tmin是由相机属性决定的,对于正交相机认为光线起源于无限远的地方,故tmin最开始为-inf),若有两个物体都相交,则要选择距离相机更近的,即t更小的那个。
对于深度图可以将其颜色按照灰度图来理解,颜色分布在[0,1],大于depth_max的深度限制为depth_max,小于depth_min的限制为depth_min,最终深度为
结果
github连接
Graphics-6.837/assignment 1 at main · A-pril/Graphics-6.837 · GitHub