计算机图形学——光线追踪算法分析

1.求交

光线追踪主要的计算量来源于大量的求交计算。设O代表射线起点,D方向 ,P为圆上的点,C为圆心,r半径。球的方程为:(P - C)(P - C) = r * r ,直线的参数方程: p(t) = O + tD。

将直线方程代入后得D2t2+2(O-C)Dt+(O-C)2-r2=0,随后利用一元二次方程求根公式,判断有无解,有两个解时,选择>0且较小的t。

求交的基本原理就是将射线的参数方程代入到圆的函数中,求t的值。

  1. 将P(t) = O + tD 代入圆方程,会得到 t 的一元二次方程。
  2. 先求出Vec op,op是用球心p的坐标减去射线的起点 (O - C)。
  3. b = op.dot(r.d)指代 ” D * (O - C) ”
  4. 求det,这里要注意我们求的b和原理中的b差了两倍,所以可以直接用
    double det = b * b - op.dot(op) + rad * rad;
    如果det<0说明无解,直接return 0;
    否则求根号的det;
  5. 最终的解有一个或两个,可能在 t = b - det,或者t = b + det中,选择t大于0并且两个中较小的t。

2.绘制

  1. 用6个很大的球体当做平面(DIFF属性,只有漫反射),因为半径很大的话,你在近距离看起来,球面就很像一个平面。
    作者这样做应该是为了避免去写平面求交,平面类等函数。

  2. 用1个球表示光源,就是Lite,1个Mirr球(完全反射),1个Glass球(折射和反射都有)
    遍历所有的球,求交点

  3. 此光线射出去,在所有的球体中求交点。

  4. 求出距离camera最近的交点,这就是待会要绘制在屏幕上的主要的点。

3.主函数说明

  1. camera的位置是在(50, 52, 295.6), 往z轴的负方向看。

  2. 遍历每个像素点,用随机采样的方式求得要射出的光线的方向d。

4.光线追踪递归说明

_Vector radiance:实现了光线跟踪处理流程,该函数中进行了递归调用。光线跟踪递归过程终止条件是光线与环境中任何物体均不相交,或交于纯漫射面、被跟踪光线返回的光亮度值对像素颜色的贡献很小、已递归到给定深度。该函数传入两个参数,一个是射线的引用,一个是递归的深度;
设定好递归出口(depth的值),对每个球体与光线求交,并使得法向量与ray._direct呈钝角(法向量指向球体外。

  1. 判断是否相交,求交点,求表面法向

  2. 漫反射(DIFF)
    如果材质是漫反射,那么就随机生成一个方向进行漫反射。
    利用法线向量w与向量(0,1,0)或(1,0,0)进行叉乘运算得到向量u,随后w与u进行叉乘得到向量v,利用叉乘运算的方向得到了一组标准正交基w,u,v。利用随机函数drand48()得到两个随机数r1,r2,通过二者的运算得到3个坐标,进而得到在标准正交基w,u,v下的一个随机向量direct,即求得了一个随机的漫反射光线从而继续递归。

  3. 镜面反射(材质为SPEC)
    计算镜面反射的方向,然后继续递归
    由于漫反射和镜面反射都遵循反射规律,因此根据反射定律计算出反射光的方向,进而继续递归。

  4. 反射和折射(材质为REFR)
    玻璃材质,有一部分光进行反射,有一部分光进行折射。
    这里用到了轮盘赌方法。
    首先,计算出相对折射率,由公式n1sinn1 = n2 sinn2可以计算出折射角的正弦值,同时根据入射光线的方向,法线方向以及折射的角度可以计算出折射方向从而生成折射光线;根据菲涅尔近似等式,可计算出菲涅尔反射和折射所占的比例(Fr+Fe = 1),从而继续递归。
    Ray reflRay(x, r.d - n * 2 * n.dot(r.d)); // Ideal dielectric REFRACTION 由平行四边形的方法求得反射光的direction

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值