🥾

基础的光线追踪

Why Ray Tracing?

光栅化不太好去表示一些全局的效果。
notion image
地图大,整个地图渲染非常耗,质量较低。
notion image
 
Ray tracing is accurate, but is very slow
  • Rasterization: real-time, ray tracing: offline
  • ~10K CPU core hours to render one frame in production
notion image

Basic Ray-Tracing Algorithm

Light Rays

Three ideas about light rays
  1. Light travels in straight lines (though this is wrong)
  1. Light rays do not “collide” with each other if they cross (though this is still wrong)
  1. Light rays travel from the light sources to the eye (but the physics is invariant under path reversal - reciprocity). 光线的可逆性,可以认为眼镜发出感知的光线,最后打到光源。
“And if you gaze long into an abyss, the abyss also gazes into you.” — Friedrich Wilhelm Nietzsche (translated)
notion image
虽然是错的,但可以这么理解。从相机(我们的眼镜)出发,往世界中投放光线,光线在弹来弹去之后到达光源。(光追中“追踪”的意思)

Ray Casting

Appel 1968 - Ray casting
  1. Generate an image by casting one ray per pixel
  1. Check for shadows by sending a ray to the light
notion image
假设眼镜是一个点,光源也是点光源。对于场景中的物体,光线打到它之后会发生完美的折射或反射。只考虑光线打到的最近的物体,这样解决了深度测试的问题。
notion image
eye ray 打到点之后,要考虑这个点会不会被照亮,往光源连线(shadow ray),如果中间没有物体阻挡,说明光源可以照亮这个点。如果有东西挡着,说明点在阴影里。有了法线,有了入射方向和出射方向,就可以开始着色。着色完就可以在 Image plane 写入像素的值。
⚠️
这里说的是光线只弹射一次。弹射多次要参考下面的 Recursive (Whitted-Style) Ray Tracing
notion image

Recursive (Whitted-Style) Ray Tracing

notion image
眼镜投射光线打到一个点的时候,如果是个玻璃材质,应该要做个镜面反射。
notion image
玻璃球还可以折射打到另外的点,再折射出来。
notion image
如果这个点,由于光线的弹射次数多了,在每一个弹射的点都会计算着色的值。(四条虚线)看光源是否能照亮到点。
如果光源能够照亮弹射的点,就把所有弹射点(光路,折射也算)着色的值都加到 image plane 对应的像素中。同时也考虑能量的问题,例如反射占了能量60%,折射能量占了40%。
 
notion image
对于不同类型的光线,眼镜直接打到的光线称为 primary ray,在一次弹射之后的光线称为 secondary rays,与光源连线判断可见性的叫 shadow ray。
notion image
notion image
还有很多技术问题:
  • 怎么判定光线被遮挡
  • 怎么判断光线投射出去会打到哪里
  • 怎么求反射光和折射光的方向,以及各自带的能量
  • 衰减怎么算

Ray-Surface Intersection 求光线和表面的交点

notion image
光线在数学上就是射线,有起点和方向。对于任何一个点,都可以用上图中的公式来表示。
💡
光线怎么和球做交点?
notion image
求公式中的 t,求传播多久可以打到球。
notion image
t 要满足物理上的意义,是正的。解出来的根也要有物理意义,解出来不能是虚数,而是实数。
我们还能将其推广到光线与隐式表面的求交:
notion image
同样可以求出不为虚数,不为负数的 t 值。
对于显式表面:
Why?
  • Rendering: visibility, shadows, lighting …
  • Geometry: inside/outside test
    • 随便取一个点,从其发射光线(射线),如果与模型有奇数个交点,那么一定在物体内。偶数在物体外。(3D也一样,物体必须封闭)
How to compute? Let’s break this down:
  • Simple idea: just intersect ray with each triangle
    • 一个一个三角形求是否和光线有交点
  • Simple, but slow (acceleration?)
  • Note: can have 0, 1 intersections (ignoring multiple intersections) 很少考虑平行情况
 
notion image
notion image
怎么样求光线与三角形的交点:
三角形在平面内,可以把问题分解成两个问题:
  1. 光线和平面怎么求交
  1. 找到交点之后判定点是否在三角形内。
 
💡
怎么和光线求交?

平面的定义

notion image
平面可以由一个法线和一个点定义,那么平面上所有的点都可以通过法线和点,用上图的公式来表示。
notion image
有没有办法一步求出来光线和三角形的交点?
答案就是:

Möller Trumbore Algorithm

A faster approach, giving barycentric coordinate directly
只要三个系数加起来等于1,就可以得到任意一个在三个点定义的三角形所定义的平面内的点
由于矢量是三维的,所以下面的等式就等于三个式子,三个未知量都可以求出来,利用克莱姆法则解线性方程组。
合理的解:t是正数、点在三角形内,也就是重心坐标的系数都要是非负的(1-b1-b2,b1,b2)。
notion image
💡
把光线和每个三角形都做一次求交,再找出最近的交点(t 最小),但是这样很慢。 如何提升速度?

Ray Tracing – Performance Challenges

Simple ray-scene intersection
  • Exhaustively test ray-intersection with every triangle
  • Find the closest hit (i.e. minimum t)
Problem:
  • Naive algorithm = #pixels ⨉ # triangles (⨉ #bounces)
  • Very slow!
For generality, we use the term objects instead of triangles later (but doesn’t necessarily mean entire objects)
notion image
上图如果用原始的方法,那每一根光线都要和 10.7M 的三角形求交,再乘以像素数,有玻璃,光线可能也不止弹射一次。