13 Ray Tracing 01#
Why Ray Tracing#
Rasterization couldn’t handle global effects well
- soft shadows
- glossy 类似古代铜镜的效果, 不够光滑, 有反射效果, 但有一定粗糙性
- 间接光照
光线追踪的问题
- 非常慢, 更多用在离线渲染而不是实时渲染
LightRays 光线是什么#
- 光线沿直线传播
- 光线之间不会发生碰撞(交叉不会有影响)
- 光线从光源出发, 在场景不断反射后进入人眼(可逆性, 可以反之眼睛通过这个光路返回到光源)
RayCasting 光线投射#
假设摄像机成像平面的像素射出光线, 光线一定打到某一物体, 再把接触点和光源做连接, 如果光源也能看到这个点, 意味着不在阴影里, 就可以计算能量, 进行着色
Generating Eye Rays#
Eye Rays 相机投射出来的光线
考虑场景里最近的交点, 再从交点往光源方向连线(ShadowRays), 判断交点是否在阴影内. 可同时通过交点求出法线, 进一步算出着色, 写入像素
Whitted-Style Ray Tracing#
假设最近交点是在一个玻璃球上, 一部分能量会被反射到其他物体上, 一部分会折射进玻璃内部再从其他地方出来
整个过程的所有交点和光源做连线, 这些交点的着色会被记录到同一个像素.
Primary ray 弹射前的光线 Secondary rays 弹射后的光线 Shadow rays 交点和光源的连线
Ray-Surface Intersection#
交点怎么求
Ray Equation#
光线被定义为有起点和方向的向量
r(t) = o + td 0<=t<∞
o起始点 d归一化方向 t时间 r光线
Sphere: p : (p-c)^2 - R^2 = 0
球上任意点到球心距离都等于半径, 交点则意味着这个点即在光线上又在球上, 意味着:
(o+td-c)^2 - R^2 = 0 意味着交点同时满足两个函数
t的计算方式
Ray Intersection的隐式表达 t要实数, 且是正的 Ray: r(t) = o + td 0<=t<∞ General Implicit Surface: p : f(p) = 0 Substitute ray equation: f(o+td) = 0 这意味着任何隐式几何表达都可以和Ray公式求交点
和三角形进行光线求交
如果得到的交点是奇数, 那么交点在物体内, 如果是偶数, 就在物体外(物体是封闭的)
三角形多的时候, 需要对每个三角形都求交, 找出t最小的点. 这里只考虑0个或1个交点的情况
三角形必定在一个平面内, 定义平面, 光线和平面求交, 再判定交点是否在三角形内
定义平面: 定义法线和一个点, 且这个点满足 p : (p-p’) · N = 0 因为法线和平面任意点垂直, 那么再定义一个平面内的点p’, 向量pp’必定和法线垂直
平面光线求交: (p-p’)·N = (o+td-p’)·N = 0, t = ((p’-o)·N)/d·N 0<=t<∞
Moller Trumbore Algorithm 直接解出光线和平面交点同时判断是否交点是否在三角形内#
通过重心坐标来计算交点是否在三角形内: o+td = (1-b1-b2)p0+b1p1+b2p2 t, (1-b1-b2),b1,b2非负
Ray Tracing Problem: Naive algorithm = #pixels x #objects(三角形数量) (x #bounces(光线弹射次数)) 非常慢
Bounding Volumes 包围盒#
把复杂物体简化成简单形状, 保证物体在简单形状内. 先判定是否和包围盒相交, 再判定和包围盒内的物体相交
轴对齐包围盒AABB(Axis-Aligned-Bounding-Box)视为三个对面的交集
判断包围盒和光线求交#
从二维平面来看, 是先判定和x轴相交时的t, 以及和y轴相交时的t(不分正负), 此时获得两个线段, 求这两个线段的交集部分, 就是光线在box内的部分
注: 如果光线没有进入盒子, 则与xy轴相交的两个线段不会有交集部分
从三维角度来看, 要满足求交, 就需要满足下面的点:
- 光线进入所有对面
- 光线离开任意对面, 这个光线就离开盒子
取tmin,tmax, tenter = max{tmin}, 取三组对面中t最小值中的最大值, 判断进入时间, texit = min{tmax}取三组对面中t最大值中的最小值 如果 tenter < texit, 意味着光线在盒子内停留了一会
如果texit < 0, 意味着盒子在光线背后, 不可能有交点 如果texit >= 0 and tenter < 0, 光线起点在盒子内部, 有交点
iff tenter < texit && texit >= 0, ray和AABB相交
为何用AABB的概念, 是因为计算单轴向是计算量小, 判断平面的t远比判断一个轴向的t要麻烦, 只从二维视角考虑的话, 只需要知道o和p的x轴坐标, ox+t·dx = p’x, 两者x坐标相等, 等式成立, 最后t = p’x-ox/dx
14 Ray Tracing 02#
Uniform Grids#
画一个包围盒, 包含整个场景. 把包围盒划分成多个小格子, 判断和物体相交的小格子, 完成预处理.
光线进入这些区域时, 和物体没相交的格子会略过, 有相交的各自再判定是否有交点
假设光线方向是右上方, 判定时只判定临近的右边和右上边的格子即可
光栅化一条线和在二维空间判定格子的道理一致
加速效果: 格子稀疏速度不变, 密集计算量过多, 因此需要一个合适的采样数
“Teapot in a stadium” problem 大规模空白的场景不适合这么做
Spatial Partitions 空间划分#
mesh密集的地方使用密集的格子, 反之采用稀疏的格子
划分法: Oct-Tree 一直分割到格子内部物体数量合适为止, 但这个方法维度越高开销越大 KD-Tree 在Oct-Tree的基础上, 每次分割只对格子某一轴进行划分, 以xyxy的轴向顺序循环分割 BSP-Tree 空间二分法, 每次选一个方向对空间分割, 由于不是横平竖直的划分, 不方便计算, 维度高了会更复杂
KD-Tree#
对于任何节点要知道:(Internal nodes store)
- 当前节点的划分方向
- 划分位置
- 中间节点要有子节点
- 实际物体只存在于叶节点上 Leaf nodes store
- list of objects
光线和中间节点有交点, 就对中间节点下的子节点进行求交, 一直到光线和叶子节点是否有交点来判断最后是否求交
KD-Tree问题
- 不方便计算三角形和格子求交
- 一个物体可能出现在多个叶子节点里
object partitions & bounding volume hierarchy (BVH)#
物体划分法
用盒子把场景包起来, 把三角形分成两部分. 对两个部分重新求新的包围盒, 形成两个几点, 以这个方法持续划分下去, 一直到包围盒内的三角形数量达到要求
- 一个物体只可能出现在一个格子里
- 不涉及到三角形求交, 只用计算包围盒
要避免包围盒重叠, 划分方法要有讲究
具体方法:
- 找到包围盒
- 递归地拆分物体到两个部分
- 重新计算各个部分的包围盒
- 满足要求时停止
- 物体都要在叶子节点里
BVHs划分法
- 选择一个维度划分, 可以像KD-Tree那样选择维度
- 总是选择最长的轴划分
- 取中间的物体来划分, 保证划分后两个部分的三角形数量几乎相等. 取三角形重心, 沿某个轴进行排序. 还有一种算法, 给一组无序数, 找到其中最大的数n, 找中间数i = n/2. 这个方法更快(快速划分算法)
一直划分到包围盒内三角形数量达到一定数
Internal nodes store
- Bounding box
- Children: pointers to child nodes
Leaf nodes store
- Bounding box
- List of objects
Nodes represent subset of primitives in scene -All objects in subtree
BVHs 代码
两种划分对比#
Basic radiometry#
辐射度量学的结果比Whitted style ray tracing结果更准确
术语:
- Radiant flux
- intensity
- irradiance
- radiance
学习思路: Why, What, then How
RadiantEnergy and Flux(Power)#
Radiant energy 电磁辐射的能量, in units of joules焦耳, 光源辐射出来的能量
Q[J = Joule] 光的能量
radient flux(power) 单位时间里表现出来的能量
$$ \Phi \equiv \frac{\mathrm{d} Q}{\mathrm{d} t} $$
能量 per unit time, 单位时间内的能量, 功率W, 描述一个物体功率还有另一个单位lm = lumen, 表示一个物体有多亮
另一个定义: 假设一个平面, 给一个单位时间, 这个时间内平面接受到的光子数量, 叫做flux
radiant intensity 光源辐射出来的能量
Irradiance 任何物体表面接受的能量
Radiance 光源传播过程中的能量
Radiant Intensity#
I(w) = dPhi/dw
power per unit solid angle (立体角)
立体角:#
圆的角度为θ, 角度对应的弧长l, 圆半径为r θ = l/r, circle = 2Πradians
三维空间中, 定义一个球, 内部定义一个锥体, 这个锥体在球上面积除以半角平方, 得到的就是立体角, Sphere = 4Π, 如果是球体, 它的立体角就是 4Π/r^2
单位立体角 方形面积定义
先定义方向, θ代表立体角方向和z轴夹角. \Phi 代表立体角绕着z轴旋转形成的角, 旋转θ产生的距离为r dθ, 满足弧长公式, 绕着z轴旋转的距离为rsinθd\Phi, rsinθ = 立体角在xy轴平面的圆的投影的r长度, 之所以这么做, 是因为纬线是垂直于z轴的平面截球体形成的圆形轨迹, 每个纬线是一个水平圆, 半径由θ决定, sinθ = 对边/斜边 = 投影/r
因此方形面积为dA = (r dθ)(r sinθ d \Phi) = r^2 sinθ dθ d\Phi, 所有单位立体角的积分就是4Π(球)
omega 定义三维空间中的方向(辐射度两学内)
intensity是光源在任何方向上的亮度, 这意味着所有方向上的intensity加起来就是power, 同时intensity = power/4Π 代表任何方向上的能量
dA = (r dθ)(r sinθ dPhi) = r^2sinθdθdPhi
dw = dA/r^2 = sinθdθdPhi
15 Ray Tracing 03#
公式前缀有d代表微分形式, 即物理量的无限小变化量, 积分运算中的微分元, 方向相关量的增量描述
Irradiance#
power per(perpendicular/projected) unit area 每一个面积上的能量
入射光线和平面垂直才算, 如果不垂直则需要通过投影成垂直方向来计算
平面和光线垂直时, E = Phi/A, 有倾斜角时, E = Phi/A cosθ
Irradiance衰减, Irradiance有距离越远越衰减的性质 E=Phi/4Π E’=Phi/4Πr^2,意味着点光源的辐射球形增大, irradiance会跟着衰减, intensity不会随距离增加而衰减
Radiance#
radiance是为了用来描述光线这个属性, 光在一条线上的传播过程中有什么样的属性
power per unit solid angle, per projected unity area
某个面, 往某个确定的方向, 即立体角, 辐射一定的能量, 就是radiance
根据前两者定义, radiance可以理解成irradiance per solid angle & intensity per projected unity area
L(p,w) = d^2Phi(p,w)/dwdAcosθ
incident Radiance#
the irradiance per unit solid angle arriving art the surface
L(p,w) = dE(p)/dwcosθ
Exiting Radiance#
L(p,w)=dI(p,w)/dAcosθ
Irradiance vs Radiance#
irradiance是平面接受的能量中来自某一特定方向的能量, 这意味着dE(p,w) = Li(p,w) cosθdw这个公式可以写成积分的形式, 积分就是求和, 也就是所有方向的irradiance之和等于radiance
###BRDF 双向反射增幅函数
BRDF定义能量从某个方向进来, 从不同的反射方向分布多少能量
radiance被吸收后反射, 反射分布由BRDF定义, 根据最终要的结果是漫反射还是镜面反射, 其分布规律会有不同
radiance被吸收后转换成能量irradiance再发射成radiance出去. 这里的irradiance不是total irradiance, 而是单指入射方向的能量irradiance
为什么要把radiance转换成irradiance, 而不能直接用radiance
因为那样公式会变成f = dLr/Li, cosθ = 90° = 0时式子无法成立, 且irradiance代表的是一个平面吸收的能量, 即便特指某一方向时特性也不变. radiance指的是从某一方向辐射的光线能量
Reflection Equation 反射方程#
反射方程定义的是 任何一个着色点, 在光照环境下, 把所有入射光线的贡献加起来, 来求最后出射光线的强度
渲染方程#
渲染考虑两种光线, 一个是反射来的光线, 一个是着色点自身发光发射出来的光线
单个点光源: Reflected Light(output Image) = Emission + Incident Light(from light source) · BRDF · Cosine of Incident angle
多个点光源: Sum over all light sources 把所有点光源各自的反射结果加起来
面光源:
把面光源视作点光源的集合, 积分面光源所占据的立体角, 考虑所有覆盖的方向的radiance
有其他物体反射的光源:
把反射光源的物体反射面视作单纯的光源来计算
公式简化#
Reflected Light(output Image) = Emission + Incident Light(from light source) · BRDF · Cosine of Incident angle
用简单的表达方式来表达复杂的式子
L(u) = e(u)着色点自发光能量 + fl(v) K(u,v)dv (所有方向忽略掉, 只考虑这个着色点, 所有来自其他光源的能量, 最后根据BRDF贡献给出射光线的能量)
进一步简写
L = E + KL 辐射出来的所有total能量L 等于 所有光源辐射的能量E 加上 辐射出来的能量被反射之后的能量KL K是反射操作符
解方程, 算出L
I是恒等算子, 代表能量保持, K代表能量变换与衰减, 去掉这两者差别, 两边L在数学形式化表达中视为同一个未知函数的不同表达形式, 两边L除了入射和出射以外, 物理本质上相等, 因为两者都是total radiance. 只是右边是没通过衰减的L, 左边是衰减后的L. 去掉衰减因素(I-K), 两者本质相等
最后简化成
L = E + KE + K^2E + K^3E +…
E代表Emission Directly From Light Sources, 相当于直面光源看到什么, KE 代表Direct Illumination 相当于光源反射一次看到什么, K的次幂表示反射次数, 反射2次以上就是indirect Illumination, 直接和间接光照的集合就是全局光照
光栅化只能做好Emission 和 Direct Illumination, 后面弹射多次的间接光照不好做
弹射次数演示#
光线弹射次数不够的话, 阴影内的部分物体(玻璃)无法正确显示
弹射次数越多, 亮度变化越不明显. 弹射次数达到一定次数, 画面不会再有剧烈变化了
能量守恒
如果是相机, 一直开着快门, 最后会出现过曝. 因为考虑时间因素进去, 积累的能量会越来越多
随机变量#
x random variable
x - p(x) 取特定值的特定概率
eg: 6面色子, x = 1,2,3,4,5,6
p(1) = p(2) = p(3) = p(4) = p(5) = p(6)
概率p非负, 所有概率加起来是1, eg pi = 1/6
期望: 不断去取随机变量, 求它们的平均
只掷一次, 期望取到的值是多少
Expected Value of X : 值乘以概率, 把所有随机值和概率相乘的结果相加
色子的期望是 (1+2+3+4+5+6)/6 = 3.5
概率密度函数PDF#
随机变量x可以取一组连续值中的任意一个, 其中特定值的相对概率由连续概率密度函数p(x)决定
假设数组[-3,3] 取随机值, dx在坐标系中升起柱形, 这个柱形面积就是这个值的概率. 中间值, 也就是期望最容易获得, 所以0的概率密度最大
公式中, dx表示概率图中微小矩形的单位宽度,dx会在积分运算被消去, 无需具体赋值
概率密度满足:
- 整个概率密度dx的积分为1
- 任何一个取值x乘以概率密度并积分起来, 就可以得到期望
如果函数的输入是随机变量 Y = f(X) X - p(x), 就可以得到函数的期望是多少
16 Ray Tracing 04#
蒙特卡洛积分#
给任意函数, 算a到b的定积分. 最后积出来是一个数. 假设一个坐标系, 定义一个函数, 取两个x值, 结果投影到x轴上, 形成的形状的面积就是定积分的结果
蒙特卡洛积分做的是随机采样, 随机取x, 找到结果y, 这个xy作为矩形的宽, 长就是ab, 求矩形面积, 然后求多次x, 最终把得到的所有长方形面积平均起来, 求到最接近的结果
涉及导数, 积分, 不定积分
如果在a到b之间均匀采样, 采样的PDF是各处相同的. 均匀采样指的是在区间[a,b]内, 每个点被抽中的概率密度相同的随机采样过程(色子就是这种情况. 非均匀的情况有比如游戏抽卡, 不同稀有度抽到的概率不同)
p(x)输出各处相同, 结果是p(x) = 1/b-a, 因为p(x)总和是1
蒙特卡洛积分需要用f(x)/p(x) 结果为f(x) 乘以 b-a, 就可以把b-a摘出去对式子进行简化
point:
- 采样数N越大, 得到的结果越准
- 在x上积分, 就一定要采样x
Path Tracing#
Whitted-Styly ray tracing:
- 总是在specular物体上反射 always perform specular reflections/ refractions
- 总是在漫反射物体上停止 stop bouncing at diffuse surfaces
Whitted问题1: specular完全镜面 Glossy并不是很光滑的表面, 接近镜子但比较模糊, Whitted-Style无法正确反应两者差别, 它仍然会用specular的光线反射来表达glossy Whitted问题2: 漫反射会反射光(均匀反射), 但Whitted不会体现这一点
color bleeding, 周边环境颜色通过反射体现在物体上的现象(放在红色墙面的黄色物体出现红色)
Path解决了whitted style 的问题
rendering equation
需要解决2个问题
1.考虑到各个方向的光线, 需要解决公式对半球积分 2. 递归问题 (间接光多次弹射多次计算)
- 把一个积分通过数值方法计算成一个值, 用蒙特卡洛方法来解决(只要是定积分)
现在只考虑一种情况
一个光源, 一个着色点, 一个摄像机, 着色点旁边有一个墙面(着色点不发光)
这个着色点的直接光照是什么?(间接光照直接判定为0) 每一个方向视为一个随机变量x, 求f(x)和p(x)
f(x) = Rendering Equation(不考虑自发光项) radiance · BRDF · cos p(x) = 1/2Π, 半球是2Π, 均匀采样, 每一个方向概率相同, 总和为1, 所以每个方向是1/2Π
代码
在着色点往半球方向发出N个光线, 如果光线打中光源, 整个rendering equation算出来.
更进一步, 引入间接光照
假设第一个反射点为p, 第二个为Q, 求Q反射到P点的radiance. 可以视作在P点观察Q点的直接光照
代码
当发射出去的光线打到的不是光源, 而是物体的q点, 把L radiance替换成q点反射过来的radiance (q,-wi)
此时有2个问题
- 发射的光线随反射次数指数上升 rays = N ^ #bounces 答案:N = 1 最合适
着色点随机往一个方向打出一根光线, n=1来做蒙特卡洛积分就是路径追踪
最后要的是一个像素的radiance, 但穿过像素的会是多个radiance, 因此要有足够多的paths作用于像素
Ray Generation
定义摄像机, 像素位置, 像素里面取N个位置, 从摄像机连一个线到样本位置上去(采样点), 如果光线打到场景某个点P, 把这个点算入对着色的影响
- 递归问题 什么时候停
俄罗斯轮盘赌 2个子弹, 生存概率是P = 4/6, 0 < P < 1能生存, 1 - P情况另算
定一个概率, 以一定概率P往某个方向打一个光线, 得到结果Lo除以P, Lo/P, 1-P概率不打光线, 得到0
E = P*(Lo/P) + (1-P) *0 = Lo, 期望为Lo
期望值计算 E = 所有结果总和 乘以 概率P (概率均匀分布的情况)
2种概率两种情况, 所以分为P和1-P
P的情况下
P*(Lo/P), 也就是说结果总和为Lo/P, 这是为了用1次采样来取得最接近的真实Lo
因为只通过一次采样来获取Lo, 所以需要除以P来保持平均值的准确性, 除以P是为了弥补较低的采样概率
假设6个弹巢一个实弹, 空枪一次得奖金10元, 空枪概率为5/6, 开一枪得到的Lo/P就是12, 意思是数学期望上开一枪得到的奖金期望数是12, 另外2元相当于剩下次数的补偿
假设连续5次空枪, P = (5/6)^5, 数学总收益为60, 带入公式计算, 总收益还是50
只采样一个方向, 但实际积分需要覆盖所有方向, 因此需要将一个样本放大以代表整个积分, 所以要除以P_BB, 随着采样样本增加, /P_BB校正值的平均值会收敛到真实积分
代码
以一定概率打出光线, 设定概率P_RR, 设定概率ksi在[0,1]里面取, ksi > P_RR则不发射光线, 比如P_RR为0.8, 那么Ksi小于0.8发射光线. 打出去的光线, 最后结果除以P_RR
问题: 采样率samples per pixel不足结果会有noise
解决问题
问题: 当光源小的时候, 原方法需要更多光线来寻找光源, 造成光线浪费
方法: 光源和采样点连线, 光源视作面, 有朝向,采样点法线, 光源法线和连线有夹角θ, θ’, 光源pdf = 1/A, A为光源面积, 计算dw和dA, dA是光源上的表面, dw是光源面积在这个连线方向上的立体角. 计算方法: 把dA面向dw方向, 再除以距离平方
f(x)是整个式子, p(x)是1/A
此时, 对光源贡献直接连线采样, 对非光源部分使用原方法(俄罗斯轮盘赌)
有物体在光源和采样点之间, 如何判断?
在采样点对光源方向打个光线, 如果被遮挡, 不计算
Side Note#
点光源不方便计算, 建议只用小的面光源
Ray tracing包含内容 以前:Whitted style ray tracing 现在:PathTracing 分单向, 双向 Photon mapping Metropolis light transport VCM/UPBP
遗留问题
- 对半圈进行均匀采样 给一个函数, 怎么取采样
- 蒙特卡洛积分可以用在任何PDF上, 怎么选择PDF 重要性采样
- 随机数分配(可以防止随机数扎堆或离得太远的情况出现) low discrepancy sequences
- 同时采样半球和光源 multiple imp.sampling
- 像素射出不同paths, 平均所有radiance, 加权, pixel reconstruction filter
- 像素radiance换算成颜色, gamma correction
- curves, color space, hdr
17 Materials and Appearances#
- 在山谷看到光柱(光的散射)
- 头发的透光性
- 布和金属的属性差别
- 蝴蝶的翅膀是鳞片叠起来的, 鳞片本身没颜色, 叠起来之后有颜色
- 彩虹和双彩虹
- 寿司, 鱼肉(次表面反射)
陶瓷同时有漫反射和镜面反射, 这是因为陶瓷表面有一层物质, 允许光和陶瓷原本的表面进行漫反射, 和这层物质进行镜面反射
漫反射#
进来的光线会均匀地往四面八方的方向反射
设定入射光是uniform(不管哪个方向进来的radiance都是一样的), diffuse也是uniform
如果这个点不发光, 也不吸收光(白的), 意味着出射光和入射光的radiance, irradiance都相等, 能量守恒
公式
BRDF = P/Π, 反射率P(albedo, color颜色)
glossy#
入射光反射到一个方向, 抛光金属(铜镜) 光滑, 但不够完全镜面(反射信息模糊)
玻璃, 水, Ideal Reflective, refractive material#
光线有一部分反射, 一部分折射(进入物体内部). 这种材质反射光同时让光穿过(玻璃), 也会反射光同时吸收光(有色玻璃)
反射公式 Perfect Specular Reflection#
入射光和出射光
方法一
假设入射光线wi, 出射光线wo正中间一定是法线方向, 且和法线的夹角为θi, θo. 利用向量相加, wi+wo, 新向量在法线方向, 长度为wi,wo其中一个向量在法线上投影长度的2倍
wo+wi = 2cosθn = 2(wi·n)n, wo = -wi + 2(wi·n)n
方法二
把这些角度投影到一个局部坐标系上去, 以顶视角去观察反射, 假设wi,wo以n为重心旋转, 旋转的角度就是phii和phio, 此时wi和wo在坐标系上是相反朝向的, 相互距离Π角度
转换公式为 Phio = (Phii + Π) mod 2Π, mod的意思是旋转角度大于等于360°时减去360°, 强制角度值在[0,2Π]区间
Phio 和 Phii 指的是顶视图坐标系中, 从x轴正方向到入射方方向,出射方向的角度
折射#
折射案例
棱镜, 光进入棱镜, 出来被分解成不同颜色
光进入物体发生折射, 比如玻璃, 看玻璃后面的物体可以看到位置有偏移
焦散 光线打到海水表面, 海水表面凹凸不平, 海底面光线聚集在特定地方, 形成特定图案
折射公式
Snell’s Law 折射定律
入射角, 出射角wi, wt, 和法线夹角θiθt, 满足 ηisinθi = ηtsinθt, η代表折射率, 不同物质折射率不同, 真空为1, 水为1.4, 由此算出折射角的θ
Phi和反射相同, 入射和折射Phi相反, Phit = Phii +- Π
折射表, 折射率越大, θt越小, 不同波长的光会被折射不同程度, 所以钻石折射率2.42, 看上去就有各种颜色
根据定律可以计算折射角 cosθt = 根号1-sin^2θt, sinθt = ηi/ηtsinθi
sin^2θ+cos^2θ=1 假设一个单位圆,r=1, 圆上点P(x,y)满足x = cosθ, y = sinθ, 勾股定理满足sin^2θ+cos^2θ=1
根号在内部内容小于0的情况下没有意义, 意味着比例ηi/ηt需要大于1, 意味着ηi大于ηt, 也就是全反射现象
Snell’s Window/ Circle
全反射现象, 入射介质折射率大于折射介质, 从足够大的角度入射到边界的光不会离开介质, 入射角大于临界角
人在水底往各个方向去看, 能看到一个锥形区域, 超出这个区域的光线会被反射到海底(只考虑弹射一次)这就是total internal reflection
图片中看到的不一定是太阳直接光, 而是水下物体反射的光或环境光在水中的散射光, 太阳光从空气进入水面, 打到水下物体反射回水面, 此时根据角度, 一部分光折射出水面, 一部分会再反弹回去(全反射), 反弹回去的光进入潜水员眼睛, 看到的就是图中的现象
左边的图描述的是在水中一个点发射光线, 超出范围的光线会被反射回水底, 在范围内的会折射出水面, 因此能在水中看到光的范围就这么大(97.2°)
BRDF和BTDF统称BSDF, R代表反射, T代表折射, S代表散射
菲尼尔项 Fresnel Reflection#
reflectance depends on incident angle (and polarization of light)
菲尼尔项决定了多少能量被反射, 多少被折射
angle from normal 越接近90°, 大量能量被反射. 越接近0, 会被折射
光线会沿着方向震动, 蓝绿两条线表示震动方向
车里看玻璃, 视线垂直平面可以看到外面, 但再往前的玻璃角度不同, 看到的就是像镜子一样反射的图像
上述是绝缘体的情况
金属(导体)不管什么角度反射率都很高
Fresenl approximate: Schlick’s approximation
公式简化成在0度的时候为R0 = (n1-n2/n1+n2)^2, 90度时为1(100%反射), 导体就是从90%反射到100%反射
导体折射率是复数(nk), 但一般不会考虑那么复杂
Microfacet Material: Motivation#
从宇宙看澳大利亚的沙漠, 是一个反射光的平面
Microfacet Theory
从远处看到的是平面, 且粗糙的
从近处看, 能看到凹凸不平的表面flat rough 远处看材质或外观.
且每个微原是镜面反射的物体 bumpy & specular 近处看的是几何
每个微表面有自己的法线
Microfacet BRDF#
可以研究微表面形成的法线分布
平的表面, 微表面法线分布会在宏观表面周围, 朝向和宏观表面法线相差不远 接近glossy材质
粗糙的话, 微表面朝向散布非常开, 和宏观表面法线相差很大, 表现接近diffuse
入射, 出射 = 考虑菲尼尔项F, 法线分布D(h), G表面凹凸不平时, 有可能会互相遮挡, 当角度达到一定程度时, 部分微表面失去作用, 特别是光线和平面几乎平行, 有G存在, 当视线和平面平行时, 不会太亮
Isotropic/Anisotropic Materials BRDFs 各向同性, 各向异性
例子: 单向打磨的电梯表面
各向同性 微表面不存在方向性
各向异性 法线分布具有方向性
旋转入射角和出射角, 结果相同, 就是各向同性. 结果不同, 就是各向异性, 结果就和绝对方位角有关
尼龙, 织布, 各向异性, 水平竖直一样, 对角线方向不一样
天鹅绒 表面是多个velvet形成的体积, 分布均匀时看上去是各向同性, 但可以用刷子刷向同一方向, 这是为什么把它定义为各向异性
- BRDF结果非负
- BRDF具有线性性质 BRDF可以拆分多个部分单独做光线传播再加起来
- BRDF有可逆性, 入射和反射方向互换, BRDF结果不变
- 能量守恒 BRDF不会让能量变多, 完全反射就是入射多少反射多少, 其他情况就是能量会吸收一部分再反射. 也因此多次反射后场景能量不会增加
各向同性, 计算可以少一个维度 各向同性意味着入射出射角度旋转相同度数, BRDF值不变, 而方位角差满足旋转对称性, 即 方位角差= Phio - Phii = (Phio + a) - (Phii + a) = Phio - Phii = 方位角差 满足两个角度同时旋转, 结果不变的性质 比如Phii = 30& o = 60 和 Phii = 120& o =150的结果一致, 比计算两个方位角少一个维度 各项异性需要绝对方位角, 因为坐标系(着色表面)本身不能单独旋转, 各项同性允许坐标系旋转, 因为那等同于两个方位角旋转相同度数 绝对方位角和方位角在几何上是一个东西
不论各向同性还是各向异性, 都具有可逆性, 就在计算时不用考虑PHI角度正负 因为可逆, 新的方位角差 Phinew = Phinew_o - Phinew_i = Phioldi - Phioldo = -(Phioldo - Phioldi) = -旧的方位角差, 所以f(方位角) = f(-方位角)
BRDF计算的是指定入射和出射角, 出射方向的radiance, 所以Phi i 大部分情况不等于Phio + Π, 除非你在镜面反射的方向看
BRDF测量
BRDF可以用各种各样的模型去表述, 但这只是基于物理的一种描述或近似
真正的BRDF是测出来的, 以前的模型去测量, 菲尼尔项的曲线和理论完全不符
BRDF测量
BRDF是入射方向和出射方向的函数, 盯着一个着色点看, 改变入射方向. 再拿个相机, 四面八方去拍这个着色点
算法, 每举所有出射方向, 放上光源. 每举所有入射方向, 放上相机, 得出所有radiance
- 如果是各向同性物质, 四维降到三维
- 只考虑相对方位角, 再砍掉一半测量量
- 测样若干次数, 最终结果猜出来, 加速测量速度
BRDF存储(大量数据压缩)
MERL BRDF Database BRDF库 一个9090180的三维数组, 代表θiθo, |Phii-Phio|