简单的逆向光线跟踪

        摘要:光线跟踪属于计算机图形学的经典理论,在高质量的场景渲染领域有着很广泛的应用,虽然读研没在图形所,但还是非常有幸的上了学校里大牛老师的课,俗话说,没吃过猪肉,还没见过猪跑么,呵呵,开玩笑,下面的文章以作者研一上课图形学大作业为背景,因为最近要增加博客的点击率,所以把陈年的谷子给翻了出 来,下面进入正题,呵呵。

 

        第一部分: 原理部分

光线跟踪是模拟从照相机(人眼)位置发射一条光线,穿过屏幕,和虚拟世界的物体相交与一点,光线跟踪的主要任务就是计算相交点的亮度值,相交点的亮度由两部分组成,一是直接光源的照射,二是其它物体表面的反射。如图所示:


 

图1 照相机发射光线穿越屏幕

图2 照相机发射光线与物体相交处的亮度计算

光线到达物体后有两部分运算:

  1. 光照计算(局部与全局)

一部分是局部光照计算,包括漫反射,镜面反射,环境光等。这部分主要采用phong模型来计算局部光照强度。

  1. 漫反射,从光源发出的光到达物体后沿着各个方向均匀反射,这里主要要计算物体交点的法向量及此点与光源的连线的夹角余弦值。然后可以算出亮度值。如下图所示:


图3漫反射效果图

  1. 镜面反射沿着出射光线方向偏离越远光线越暗,如下图所示,L为入射光线,R为反射光线,V为视点与交点连线,V看到的点亮度与V R的夹角余弦值成正比:

 

图4 镜面反射模型


 

     

另一部分是全局光照计算,包括反射,折射等。全局光照计算主要涉及到光线的递归,为了防止光线在物体上不停的折射反射,一般都设置一个递归深度,当达到递归深度后不再进行计算。

在计算过程中有三种情况会终止光线的跟踪,一种情况是光线被物体挡住,此时可以终止计算此点像素值,返回一个(0,0,0)的颜色值,另外一种情况是直接照射到光源,此时也会停止光线跟踪,返回光源颜色。第三种情况是到达递归深度时仍然没有达到上面两个条件,此时强行终止光线的计算。跟踪深度越大,效果越逼真,计算量也越大。

 


      2.相交测试

在跟踪过程中需要计算光线与物体是否有交点,在本例中只计算了与球体及平面的交点,

    1. 球:

c为球的中心,p为光线在屏幕的发出点,u为光线的方向,r为圆的半径,qpq cq垂直的交点,得到一公式,alpha = -1 * (p - c) * u,此处有p + alpha * u = q. 然后计算qc的距离b. a * a = r * r – b * b, 求出aalpha = alpha – a;此处p + alpha * u即为射线与球的交点。

    1. 平面:

起点为pu为方向,q = p + alpha * u;

Alpha = (d – p * n) / (u * n), d为平面的常量 其中x * n = dn为法向。

 

 

 第2部分:程序设计

 

        程序的设计分为三部分:

        第一部分设计了常用的一个类Vector3,并作了常用的运算符重载。类部分代码如下

 

Code

         第二部分设计了一个虚基类用于被各种物体继承,这样设计主要是为了光线跟踪时对物体的遍历方便,同时设计了材质属性类,球体类,平面类等。

 

Code

 

 
        第三部分渲染引擎的设计

 

Code

 

        最终效果图如下:

 

 

 

posted @ 2009-06-22 18:41  超大狗  阅读(1151)  评论(0)    收藏  举报