渲染方程

$$L_o(x, \omega_o) = L_e(x, \omega_o) + \int_{H^2} f_r(x, \omega_o, \omega_i) L_i(x, \omega_i) \cos \theta_i d\omega_i$$翻译:观察一个点的亮度主要由自发光和其他光的影响

决定观察某个点$x$时候,此时你的观察角是$\omega_o$,此时首先加上这个点的自发光,随后是这个点被其他的光影响的光照求和。

这是图形学中最最基础的公式,这个公式仅仅只是作为方向指引,在实际的问题解决中,有如下三个核心问题:

1.如何获取任意入射方向的入射辐射亮度。这其中包括了阴影问题

2.半球上光照与散射函数的积分计算代价极高.

3.射辐射亮度的计算是递归的,因为场景中每一个物体都是一个反射光源

因此在引擎中,我们只能通过近似解去尽可能逼近该方程的理论值,注意,第一项为自发光颜色,与第二项积分线性组合,在处理中很简单,因此近似的渲染模型往往都是对积分项的近似,自发光独立与渲染模型相加就行。或者简单来说,是对函数$f_r$的近似,即BRDF方程。

基础光照的解决方案

现实生活中主要有三种光照类型,高光、漫反射光、环境光。

Specular highlights + Diffuse reflection + Ambient lighting

Blinn-Phong模型

参考文档:
(13 封私信) 入门Shading,详解Blinn-Phong和Phong光照模型 - 知乎

该模型能够简单地描述物体表面对光的吸收和反射,使物体表面呈现出不同的明暗程度,但其不是最真实的一种反射光模型。

它能够用尽量简单的数学原理尽可能解释物体表面呈现出不同颜色及明暗程序的原因。

$$I = I_{ambient} + I_{diffuse} + I_{specular}$$

Blinn-Phong模型中考虑了三个假设:

假设1:物体表面接收到的各种环境光都是相同强度的。
这样可以简化计算,因此环境光与光源的角度无关,与观察角度也无关,所以它是一个常数。
$$I_{ambient} = K_{a} L_{a}$$

假设2:理想的漫反射表面会把光线向所有方向均匀散射。
根据Lambert定律,只有入射光线的垂直分量才对照明起到作用。
$$I_{diffuse} = k_d(l \cdot n)L_d$$
当光源位于物体表面以下时,漫反射将没有作用,因此当入射光线的垂直分量为负数时,我们设定为0。
从物理角度来看,光照的强度会随着光源与物体间距离变长而逐渐衰减:$d$表示光源和三维物体表面上点的距离,$a$、$b$和$c$表示距离衰减系数
tips:在物理世界中,点光源发出的光向四周球面扩散。根据能量守恒定律,随着距离 $d$ 的增加,光线覆盖的球面积以 $4\pi d^2$ 的速度增长。这意味着单位面积接收到的光能(光强)与距离的平方成反比。
$$I_{diffuse} = \frac{k_d}{a + bd + cd^2} \max((l \cdot n), 0) L_d$$

假设3:提出了一个近似模型考虑镜面反射光部分,将表面看成是光滑的,观察者看到的光线强度取决于物体表面反射光的方向r和观察方向v这两者之间的夹角
$$I_{specular} = k_s L_s \cos^\alpha \phi = k_s L_s \max((r \cdot v)^\alpha, 0)$$

最后的公式:
$$I = \frac{1}{a + bd + cd^2} (k_d L_d \max((l \cdot n), 0) + k_s L_s \max((r \cdot v)^\alpha, 0)) + k_a L_a$$
Blinn-phong模型也有很多问题,比如能量不守恒,因为该模型本质上是一个是经验函数,为的是渲染的效果好。模型还是过于简单了,不过,通过模型我们已经解决了最开始提出的三个问题中的问题二和问题三。

那么如何解决问题一呢?

Shadow Map

假设有一个模拟太阳位置的摄像机,在可观察的视线范围内,物体表面各个点到摄像机的距离可以组合成一张深度图,它记录了从该光源的位置出发、能看到的场景中距离它最近的表面位置。这张深度图就叫做ShadowMap。

深度图是通过模拟太阳位置的摄像机获取到的,并非真正渲染场景的视角,真正渲染场景的视角,是B点所在位置的相机。

假设B观察到的三个点p1、p2、p3,在渲染的过程中,首先会把这三个点的顶点位置变换到光源空间下,这样就能得到它们在光源空间中的三维位置信息:sun(p1)、sun(p2)、sun(p3)。

使用xy分量对ShadowMap进行纹理采样,就能获得它们的深度信息sun-depth(p1)、sun-depth(p2)、sun-depth(p3)

B视角下这三个点的深度信息可以通过z分量获得,它们的深度信息是B-depth(p1)、B-depth(p2)、 B-depth(p3)

通过同一位置在不同视角下世界空间的深度值对比,就能判断出该点是否处于阴影中。如果阴影深度值小于顶点深度值,那么这个点就处在阴影中。否则这个点就被光源照亮。

通过Blinn-phong+Shadow Map已经能够非常近似的解决渲染方程的实践性问题,在早期的游戏中已经有了还算说的过去的画面。