光栅化 VS 光线追踪
图形学研究如何使用计算机模拟现实,当我们在谈渲染的时候,大致可以分为两个方向:
Ray Tracing
,即光线追踪,一般用于离线渲染,效果好,但是计算量大,耗时长。Rasterization
,即光栅化,一般用于实时渲染,效果差,但是计算量小,耗时短。
实际上,在现代 GPU 和各种光栅化渲染算法的的加持下,光栅化的效果已经非常逼真了,光栅化的效果一点也不差。只是相比于光线追踪来说,效果还是差点。
一个简单的光线追踪流程:发射一条光线,经过一系列地镜面反射、漫反射、折射等现象,最终打到一个物体上,得到一个颜色。几个原因导致了计算量的爆炸:
- 像素数量多
- 因为反射和折射结果不稳定,一个像素需要几十甚至上百次采样平均才能获得一个稳定的结果
- 每一次采样都会反射或者折射很多次
- 每一次反射或者折射,都需要和场景中的每个物体相交判断,不过使用屏幕空间划分技术可以解决这个问题
总结一下,光线追踪的时间复杂度:Pixel * Sampling * (Reflection + Refraction) * (Object + Light)
,堪称炸裂。
如果你使用了屏幕空间划分技术(例如 BVH),会让结果好很多:Pixel * Sampling * (Reflection + Refraction) * log(Object + Light)
。
还有一种优化思路,就是让采样结果更加稳定,一旦采样结果稳定了,就可以大幅减少采样数量,在传统的 Whitted Style Ray Tracing
中,具体的措施有比如通过蒙特卡洛方法求各种表面和光源的概率分布,比如对光源进行重要性采样。
一个简单的光栅化流程:把场景中所有物体的点经过矩阵计算映射到 2D 屏幕空间,三个顶点构成一个三角形,对每一个像素,取最近的三角形,计算三角形在这个像素的颜色(通过三个顶点颜色插值)。
像素
无论是哪一种,都需要靠屏幕来展示它们,屏幕由一个一个像素构成,那么什么是像素呢?
通常来说,大部分普通人眼里的像素是这样的:
这种网格模型深入人心,但是这种模型仅仅在光栅化的时候才是可接受的,对于光线追踪来说,可能完全不是这样。
像素并不是你想得那么简单,更加专业的图形学人会告诉你:像素是一组离散的对场景颜色的采样结果,之所以这么说,是因为像素可能是一个采样点,也可能是多个采样点混合而成的,它的采样区域可能是方形的,也可能是圆形的。
所以,网格像素模型只是一种光栅化的时候简化像素的处理:我们认为在这个网格区域内,只产生一次采样,它处于网格的正中心。
那么如果要渲染一个场景,只需要把每一个网格填上颜色就可以了,光栅化实际上就是在聊怎么填颜色这件事情。比如你需要对场景里的物体进行排序,离相机近的物体表面颜色就是你想要绘制的图形的颜色。
光线追踪技术则是基于物理,从一个像素点出发,经过多次反射,得到最终颜色,但是一个像素一条射线远远不够,因为这样误差会很大,往往一个像素需要数百条射线的结果求平均。
光线追踪的本质就是对场景不断进行采样以降低噪点,最终得到最接近真实的图像。
从时间复杂度来说,光栅化无疑比光线追踪来得更加好,但是因为缺少严谨的物理模型,光栅化的效果比光线追踪差很多,所以在对性能要求不高,但是对效果要求高的离线渲染中,光线追踪被普遍运用。
截至文章编写日期,已经有游戏比如
赛博朋克2077 2.0
运用了Path Tracing
技术,也叫Monte Calo Ray Tracing
,比传统的Whitted Style Ray Tracing
性能更加好,效果也更棒。
光栅化程序开发流程
- 创建一个窗口,并绘制直线,三角形,带有顶点数据的物体。
施工中…
Reference
Fundamentals of Computer Graphics