《Fundamentals Of Computer Graphics》第二章 杂项数学 总结
开篇第二章“Miscellaneous Math”讲了许多高中、大学所学的一些基础数学知识:集合、映射、区间、三角函数、积分、密度函数等等。不过我觉得还是有一些要注意的地方。
立体角与球面三角学(Solid Angles and Spherical Trigonometry)
传统的三角学涉及的是平面上的三角形,三角形其实也能定义在非平面表面。这种三角学在许多领域例如天文学出现,研究这些三角形的领域叫球面三角学。它虽然不会经常在图形学中被使用,但是出现的时候一般都非常重要。
在球面三角学中对计算机图形学非常重要的一个概念叫做立体角(Solid Angle),立体角让我们可以量化例如在天上的飞机占据视野的多少。整个测量过程其实很简单,把能“看到”飞机的所有方向投影到单位球,接着测量面积。测量出的面积大小就是立体角的大小,不过立体角的单位是Sr(Steradian),在单位球上的总立体角就是\(4\pi\,\mathrm{sr}\)。
我还稍微查了下资料,wiki百科上还给出了立体角积分公式,这里可以稍微了解一下,能让你对立体角有更好的理解。首先通过\(\Delta \theta\)和\(\Delta \varphi\)分割半径为\(r\)的球面,如图所示。
作者:Travailen
当\(\Delta \theta\)和\(\Delta \varphi\)在极小情况下,这个时候分割出来的每一极小份的曲面可以被当作一个矩形。因此这个时候的极小份的面积为
\
当\(r=1\)时,极小立体角的大小就是极小面积的大小
\
因此立体角的积分公式为
\[\Omega = \int \int_{S} \sin\theta\,d\theta\,d\varphi \]
单位正交基的确定
有时候需要为给定的向量求一个标准正交基,比如在写全屏光线追踪着色器,这个时候要为每个像素发出光线,此时就需要一个标准正交基。对于给定的向量\(\mathbf{a}\),我们需要标准正交基\(\mathbf{u}\)、\(\mathbf{v}\)、\(\mathbf{w}\)。其中\(\mathbf{w}\)与\(\mathbf{a}\)方向一致,\(\mathbf{u}\)、\(\mathbf{v}\)一般不关心是什么。书中还是给了两种方法
从一个辅助向量构造(Constructing a Basis from a Single Vector)
这个方法实际上就是挑选一个不与\(\mathbf{w}\)共线的一个辅助向量\(\mathbf{t}\),值得注意的是辅助向量\(\mathbf{t}\)不可与\(\mathbf{w}\)过于接近,\(\mathbf{u}\)、\(\mathbf{v}\)、\(\mathbf{w}\)可以如下计算
\[\mathbf{w}=\frac{\mathbf{a}}{||\mathbf{a}||} \]
\[\mathbf{u}=\frac{\mathbf{t} \times \mathbf{w}}{||\mathbf{t} \times \mathbf{w}||}\]
\[\mathbf{v}=\mathbf{w} \times \mathbf{u}\]
从两个辅助向量构造(Constructing a Basis from Two Vectors)
使用这个方法需要最好挑选两个垂直的向量\(\mathbf{a}\)、\(\mathbf{b}\),要注意的是向量\(\mathbf{a}\)、\(\mathbf{b}\)不可过于接近,这个时候可以求出\(\mathbf{u}\)、\(\mathbf{v}\)、\(\mathbf{w}\)
\[\mathbf{w}=\frac{\mathbf{a}}{||\mathbf{a}||}\]
\[\mathbf{u}=\frac{\mathbf{b} \times \mathbf{w}}{||\mathbf{b} \times \mathbf{w}||}\]
\[\mathbf{v}=\mathbf{w} \times \mathbf{u}\]
由重心坐标得到三角形上的点的证明
对于在三角形上的给定一点\(\mathrm{P}\),可以得到\(\vec{P} = \alpha \vec{A}+\beta\vec{B}+\gamma\vec{C}\),其中\(\alpha+\beta+\gamma=1\)。书上的证明实在是太复杂了,我想了想其实有更好的几何证明方法。
在三角形\(\mathrm{ABC}\)上做\(\mathrm{DE}\)平行于\(\mathrm{AC}\),接着在线段\(\mathrm{DE}\)上取一点\(\mathrm{P}\),如下图所示。
如图所示,现在可由两个系数\(k\)与\(t\)确定三角形\(\mathrm{ABC}\)上一点
\[\vec{P} = \vec{B}+(1-t)(1-k)(\vec{A}-\vec{B})+t(1-k)(\vec{C}-\vec{B})\]
化简可得
\[\vec{P}=(1-t-k+tk)\vec{A}+k\vec{B}+(t-tk)\vec{C}=\alpha\vec{A}+\beta\vec{B}+\gamma\vec{C}\]
易得
\[\alpha=1-t-k+tk\]
\[\beta=k\]
\[\gamma=t-tk\]
因此可证得\(\alpha+\beta+\gamma=1\)
蒙特卡洛积分(Monte Carlo Integration)
蒙特卡洛积分实际上就是通过随机样本来对函数的某区域进行积分
现要求沿表面法线方向的半球的入射光线所贡献的辐照度
\
可以通过数量为\(\mathrm{N}\)的随机采样点来获得辐亮度的积分值,因此每个采样点的权重是\(\frac{2\pi}{\mathrm{N}}\),由此可写如下代码
const float3 dir = octDecode(coor.x, coor.y);
float3 result = float3(0.0, 0.0, 0.0);
for (uint i = 0; i < SAMPLECOUNT; i++)
{
const float3 randDir = randomDirection * sign(dot(dir, randomDirection));
const float3 radiance = envCube.SampleLevel(linearClampSampler, randDir, 0.0).rgb;
result += radiance * saturate(dot(dir, randDir));
}
result = 2.0 * PI / float(SAMPLECOUNT) * result;重要性采样(Importance Sampling)
当被积函数在积分区域内的值有很大的变化时,我们可以把采样点集中分布在一些区域,不过这个时候每个采样点都有特定的非均匀权重。如果我们知道概率密度函数\(\mathrm{PDF}\)就能求出积分值,代码如下
const float3 dir = octDecode(coor.x, coor.y);
float3 result = float3(0.0, 0.0, 0.0);
for (uint i = 0; i < SAMPLECOUNT; i++)
{
const float3 randDir = randomDirection * sign(dot(dir, randomDirection));
const float3 radiance = envCube.SampleLevel(linearClampSampler, randDir, 0.0).rgb;
result += radiance * saturate(dot(dir, randDir)) / directionImportance;
}
result = 1.0 / float(SAMPLECOUNT) * result;
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]