序
题目写的比较吸引眼球,实际上这个光线追踪渲染器十分简陋,只能渲染最简单的几何体----球体,效果也很简陋。但是十分简单,核心代码只有200-300行。很适合初学者学习计算机图形学的一些基本概念。 以下我会通过介绍一些基本算法,逐步构建这个“光线追踪渲染器”。
什么是光线追踪?
光线跟踪或 称光迹追踪是计算机图形学的核心算法之一。在算法中,光线从光源被抛射出来,当他们经过物体表面的时候,对他们应用种种符合物理光学定律的变换。最终,光线进入虚拟的摄像机底片中,图片被生成出来。在当今的电影特效渲染中被广泛运用,比如阿凡达等,由于光线被赋予了真实的物理特性,使得物体的光影效果十分真实。
光线追踪是一种全局光照算法,相较于局部光照,全局光照可以模拟出光线在物体之间的传递、反射。 大概就是下面这个意思。
光线追踪渲染器的算法大致框架:
光线投射部分:
Ray_cast( view_point ){
For( 遍历视窗上的像素 ){
产生视线sightLine
For( 遍历object_group){
判断视线和哪个object相交,并且得到离视窗最近的相交点closed_point
Shader = ray_tracing( closed_point, sightLine, 3 )
用shander 给当前像素着色。
}
}
}
光线追踪部分
Int Ray_tracing(closed_Point, sightLine, deep){
If( deep > 0 ){
计算出镜面反射光线reflectLight
For( 遍历除当前object以外的object )
求得reflectLight与之最近交点rflPoint
计算出折射光线RefringenceLight
For( 遍历除当前object以外的object )
求得RefringenceLight与之最近交点rfrPoint
If( rfrPoint 存在 )
Refringence = Ray_tracing(rflPoint, RefringenceLight, deep-1);
If( rflPoint存在 )
Reflection = Ray_tracing(rfrPoint, reflectLight, deep-1);
Return phong( closed_point, sightLine ) + k1*Refringence + k2*Reflection;( 0<k1, k2 < 1 )
} else{
Retrun phong( closed_point )
}
}
局部光照模型部分(phong模型)
Int Phong( closed_point, sightLine ){
先计算点光源逆向射线closed_point->point_light lightLine之间有无遮蔽
If( 没有遮蔽 ){
Cos a = closed_point点法向量与lightLine之间夹角余弦
Cos b = lightLine反射光 和sightLine的夹角余弦
Diffuse = Point_light.range * cos a
Reflection = Point_light.range * (cos b)^5
Return Diffuse + Reflection;
}
}
下一节详细介绍每一个模块的作用以及使用到的算法。