光源模型分析

发布时间 2023-06-14 19:13:24作者: 小淼博客

一、光源模型概述

     在成像系统中,光源作为成像过程中的重要环节,需要对其进行良好的模型建立,从而深入理解在渲染或实际成像过程中的需求,通过理解光源模型,从而设置合理的曝光时间、光圈大小等参数,对实际工程应用领域也有非常重要的指导作用。

二、光源基础模型

1. 定向光(Directional Light)

     定向光是最简单的光源模型,也叫平行光,通常用于模拟太阳、月亮这类无限远的光。光照亮度 \(C_{light}\) 和光的方向 \(L\) 都是定值,除了光照亮度 \(C_{light}\) 可能会由于阴影而衰减。定向光没有位置,当然,真实的光源都是有位置的。定向光对于光源到场景的距离远大于场景大小的情况。例如:太阳,除了场景在太阳系星球的内部的情况。但有时为了性能或者为了一些特殊效果,也可以把定向光限制在一个“盒子”里面,其方向仍然唯一不变,但颜色有所差异,比如盒子外的颜色为纯黑,而内部的颜色可以是常量也可以是某种插值获得的结果。

2. 点光源(Punctual Light)

     Punctual Light 不是按时赴约的光,而是有位置的光源。用 Punctual 是来自于拉丁语 puctues ,意思是点。点光源不仅有位置,而且均匀的射像空间中所有方向。点光源的方向 \(l\) 依赖于光的位置 \(p_{light}\) 和着色点的位置 \(p_0\) , \(l=\frac{p_{light} - p_0}{\vert p_{light} - p_0 \vert}\) .
也可以写成:
\(d=p_{light} - p_0, r=\sqrt {\vec d \cdot \vec d}, l=\frac{d}{r}\),其中的 \(r\) 不仅可以用于方向向量的归一化,而且可以来计算光照亮度的衰减。
     点光源的强度会随着距离增加而衰减,且与距离的平方成反比,即:

\[c_{light}(r)=c_{light0} \cdot (\frac{r_0}{r})^2 \]

\(c_{light0}\) 是距离为 \(r_0\) 处的光照亮度,由于点光源均匀的向四面大方发射光,将点光源抽象为一个球面波,所以辐照度为 \(E=\frac{\Phi}{4\pi R^2}\)
为了防止 \(r=0\) 时,分母为 0 导致出现无限大的光强,所以诸如 UE引擎 里面会在分母上加一个小的参数:

\[c_{light}(r)=c_{light0} \cdot (\frac{r_0 ^2}{r^2+\delta}) \]

这里设置光源半径最小值可能更符合实际光源的情况(实际光源有尺寸大小),这里使用 \(r_{min}\) 作为实际光源的尺寸:

\[c_{light}(r)=c_{light0} \cdot (\frac{r_0 ^2}{max(r,r_{min})^2}) \]

     此外,在实际运用中,通常为了性能考虑,需要对随距离平方衰减的光强再乘以一个窗口函数 (windowing function ),毕竟远处的光很弱,我们可不想为了这些微弱的光徒增计算量,如下图展示了UE4里面点光源及其半径:

image
     注意上图中,在光源最大半径范围以外的区域,是没有计算这个光源光照的,且交界处都有平滑过渡的感觉,所以需要合理设计窗口函数,使光强缓慢衰减且刚好在截止半径处衰减为0。
下图展示了一种窗口函数对于光衰减的影响:

WindowFunction:

\[f_{win(r)}=(1-(\frac{r}{r_{max}})^4)^+;f < 0,f_{win(r)}=0. \]

PythonCode:

import matplotlib.pyplot as plt
import numpy as np
LightRidian = 1
R0 = 2
Sigma = 0.0001
Rmax = 6
r = np.linspace(R0,10,100)
E = LightRidian*R0*R0/(r**2+Sigma)
F_window = 1 - (r/Rmax)**4
F_window_Res = (F_window + abs(F_window)) / 2
Res = E * F_window_Res
plt.plot(r, F_window_Res, color='red', label='F_window: WindowFunc')
plt.plot(r, E, color='green',label='E: Ridian')
plt.plot(r, Res, color='blue', label='E*F_window: Result')
plt.legend()
plt.show()

3. 聚光灯(Spotlight)

     前面所述的点光源,其光强虽然会随着距离而衰减,但是各个方向上是等同的,而此处的聚光灯,更进一步考虑了光强在不同方向上的函数分布。即:

\[c_{light}=c_{light0}f_{dist}(r)f_{dir}(l) \]

     下面我们来确定 \(f_{dir}\) 函数,一个常见的聚光灯模型如图所示:

     锥之间的范围称为半影(penumbra)。内外圆锥的内角分别为和。聚光灯可计算一个聚光灯系数,范围为[0,1],代表某方向的放射比率。内圆锥中系数为1(最亮),内圆锥和外圆锥之间系数由1逐渐变成0。另外,可用另一参数p代表衰减(falloff),决定内圆锥和外圆锥之间系数变化。方程式如下:

\[spot(\alpha)=\left\{ \begin{aligned} 1 \quad if \; cos\alpha \ge cos\frac{\theta}{2} \\ \frac{cos\alpha - cos\frac{\phi}{2}}{cos\theta - cos\frac{\phi}{2}} \quad if \; cos\frac{\phi}{2} \lt cos\alpha \lt cos\frac{\theta}{2} \\ 0 \quad if \; cos\alpha \lt cos\frac{\theta}{2} \end{aligned} \right. \]

ue中的聚光灯如下图:

三、光源模型软件使用@IES Viewer

Reference

  1. Illuminating Engineering Society 照明工程协会软件 IES Viewer
  2. 光源模型-知乎
  3. 光源类型-博客园
  4. learnopengl