smallpt: Global Illumination in 99 lines of C++讲解

smallpt: Global Illumination in 99 lines of C++

光线追踪

正向光线追踪

正向光线追踪符合常识:光线从发光物体出发出,“撞击”到被观察物体上,经过一系列光线传输进入人眼。
正向光线追踪

因此正向光线追踪的基本流程可以简述为:

  1. 追踪从发光体发射的所有光线
  2. 检测光线是否“撞击”物体
    • 如果没有“撞击”物体,直接抛弃
  3. 如果撞击到物体。看反射光线是否直接射入人眼
    -如果没有直接射入人眼,则其可能经过一系列传输才射入人眼(间接射入人眼),需要进步判断
    -如果直接射入人眼,则计算当前反射光线的颜色,作为该撞击点的颜色

从上述流程不难可以看出,正向光线追踪需要追所有光线。而在这所有光线中,只有一部分光线会“撞击”到观察体,“撞击”到观察体的光线也只有部分会射入人眼。因此追踪所有光线,计算量大且做无用功较多。

逆向光线追踪介绍

追踪光线的方向与正向相反:从眼睛处射出光线,追踪光线射击到物体后,是否能回到光源。如果能则说明该点被光源照亮,否则物体上该点可能被间接照亮,需要进一步判断。
在这里插入图片描述
逆向光线追踪为什么比正向光线追踪号好呢?
因为从图形学的角度来看

人眼发射出的光线是有限的,而光源发射出的光线是无限的:人眼接收图像是二维的像素组成的。每个像素记录着该点的颜色。也即对于每个像素计算其颜色, 代表着该像素上一次光线追踪的结果。
在这里插入图片描述
因此逆向光线追踪的基本流程可以简述为:

FOR 每个像素点 :
	构造人眼入射光线Ray
	光线追踪Ray :
		计算与光线Ray相交的最近的物体Obj
		IF obj == null :
			该像素点颜色为缺省值:全局环境光AmbientColor
			Continue
		ELSE 
			看反射光Reflection是否能直接与光源相连(未被其他物体遮挡)
			IF 没有被遮挡
				该像素点颜色为光源颜色在该材质上的作用
			ELSE IF 被遮挡 
				该像素点颜色根据反射光的光线追踪结果得到。

蒙特卡罗光线追踪算法

个人理解,不对欢迎指正
蒙特卡洛思想介绍

蒙特卡罗光线追踪对逆向光线追踪模型进行改进,其中最大的区别在于把概率模型引入光线追踪。

  • 逆向光线追踪中物体的表面材质很单一。引入俄罗斯赌盘轮,可以设定漫反射、镜面反射、甚至折射的概率。丰富表面材质的显示
  • 每个像素点只采样一条光线计算出的颜色,正确率不高。引入蒙特卡罗可以多次采样求平均,优化渲染结果。
    在这里插入图片描述

根据上述分析光线追踪算法中最重要的步骤可以分解成两个:

  1. 射线与多边形物体的求交判断(空间划分kdTree)
  2. 光线追踪这个递归子算法(包括对各种材质的处理)

下面由于准备材料不够,我先只主要介绍方面2:

非透明材质

漫反射材质

漫反射材质表现为表面不规则,因此反射光线的方向无法确定判断。它朝可能的任意方向反射。
在这里插入图片描述
我们假定对于漫反射材质,反射光线的方向范围可以限定在以撞击点为圆心,撞击点法相为中心的半圆内。
在这里插入图片描述
假设:
入射光线为Ray(x0, d0)。其中x0表示光线起点 d代表光线方向
入射光线与物体表面的相交点为x
入射光线与物体表面相交点x出的法向为n
目标:求反射光线Reflection Ray(x, d1).

1.构建以x点为中心,n为一个坐标轴的笛卡尔直角坐标系
w = n
u=((fabs(w.x)>.1?Vec(0,1,0):Vec(1,0,0)) * w).norm()
v=w * u
u/v/w即组成一个笛卡尔直角坐标系

2.将反射光线方向d1分解为u/v/w表示形式
如下图所示
d1 = |d1| * cosα * cosθ * u + |d1| * sinα * w + |d1| * cosα * sinθ * v
其中α为 [0, PI/2]中的随机数;θ为[0,2*PI]中的随机数

这两个步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段56-60

 if (obj.refl == DIFF){
                     // Ideal DIFFUSE reflection 
     double<
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值