从0开始用javascript和HTML5的canvas编写光线追踪渲染器

题目写的比较吸引眼球,实际上这个光线追踪渲染器十分简陋,只能渲染最简单的几何体----球体,效果也很简陋。但是十分简单,核心代码只有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;
    }
}

下一节详细介绍每一个模块的作用以及使用到的算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章