自发光灯光
至今为止,人们发明了很多光源,现在被广泛使用的有: 1. 白炽灯的钨丝很小。电流通过灯丝时,使得灯丝升温,从而使灯丝发出电磁波,其波长的分布取决于灯丝的温度。但大部分能量都被转化为热能而不是光能。 2. 卤素灯,在灯中充入惰性气体,使得灯的寿命增加,与白炽灯一样使用钨丝。 3. LED灯
发光效率是衡量光源将能量转化为可见光的效率。对人眼来说,非可见光波长的辐射几乎没有价值,有趣的是,它是光度量(发出的光通量)与辐射量(它所使用的总功率或它发出的总波长的总功率(以光通量计算)之比:
其中V(λ)为光谱响应曲线。 发光效率的单位是流明/瓦特,如果i是光源消耗的功率(而不是发射的功率),那么发光效率也包含了光源将功率转换成电磁辐射的有效程度的度量。发光效率也可以定义为表面某一特定方向上的某一点上的发光强度与辐照度的比值(辐射强度的光度当量),也可以定义为表面某一特定方向上的某一点上的发光强度与辐照度的比值。
黑体发射器
黑体,是一个理想化了的物体,它能有效地将能量转化为电磁辐射。虽然真正的黑体在物理上是不可实现的,但一些发射器表现出接近黑体的行为。黑体也有一个有用的封闭形式的表达式,作为温度和波长的函数,这是对于黑体发射器来说非常有用的建模。
黑体之所以如此命名,是因为它们吸收了所有的入射能量,并且没有反射。因此,一个真正的黑体看起来是完全黑色的。它能够吸收外来的全部电磁辐射,并且不会有任何的反射与透射。换句话说,黑体对于任何波长的电磁波的吸收系数为1,透射系数为0。
普朗克定律给发出一个用于测量黑体发出的辐射的函数,其形参为波长λ和温度T(单位:开尔文)
其中c为光速,h为普朗克常量,kb为波尔兹曼常数,k为开尔文温度
这里我们需要将波长单位从纳米转化成米。
void Blackbody(const Float *lambda, int n, Float T, Float *Le) {
if (T <= 0) {
for (int i = 0; i < n; ++i) Le[i] = 0.f;
return;
}
const Float c = 299792458;
const Float h = 6.62606957e-34;
const Float kb = 1.3806488e-23;
for (int i = 0; i < n; ++i) {
// Compute emitted radiance for blackbody at wavelength _lambda[i]_
Float l = lambda[i] * 1e-9;
Float lambda5 = (l * l) * (l * l) * l;
Le[i] = (2 * h * c * c) /
(lambda5 * (std::exp((h * c) / (l * kb * T)) - 1));
CHECK(!std::isnan(Le[i]));
}
}
斯蒂芬-玻尔兹曼定律给出了黑体发射体在点p处的发射辐射度。 $M(p)=sigma T^4$
其中σ是斯蒂芬玻尔兹曼常数,5.67032 × 10^−8 Wm^−2 K^−4 。请注意,所有频率上的总发射以t^4的速度快速增长。因此,如何将黑体发射器的温度加倍,那么总能量就会增加16倍。
标准光源
另一种有用的灯光发射分布类型是一个 由CIE(国际照明委员会)制定的“标准光源”标准。
灯光类接口
类名为Light,位于core/light.h与core/light.cpp中。
所有的灯光类型都有4个公共参数: 1. flags:基本光源类型标记。例如, 灯光是否用delta分布来描述。(这类灯的例子包括点光源,它从一个点发出照明,以及方向灯,所有的光都来自相同的方向。)蒙特卡罗算法对来自光源的光照进行采样,需要知道哪些光线是由delta分布描述的。 2. transformation:控制坐标与旋转用的 3. MediumInterface:介质接口。 4. nSamples:采样数
LightFlags
类型flags枚举与对应方法
enum class LightFlags : int {
DeltaPosition = 1, DeltaDirection = 2, Area = 4, Infinite = 8
};
inline bool IsDeltaLight(int flags) {
return flags & (int)LightFlags::DeltaPosition ||
flags & (int)LightFlags::DeltaDirection;
}