前言
本篇将介绍局部光照模型——每个物体的光照独立于其他物体,即仅考虑光源直接发出的光线,忽略场景中反弹的
为何我们可以看见这个五彩缤纷的世界?
光源是由红蓝绿三色的混合光,而人的视网膜有三种光受体,分别对于红绿蓝三色光敏感,当光线刺激到相应的光受体,基于光线的强度而产生不同程度的刺激,随后光受体将神经冲动沿着神经传至大脑,大脑再根据光受体所受刺激再观察者大脑中生成相应画面。总的来说,就是人眼接收到了从物体射来的光线
光照与材质
如下图所示,下图左边是一个不受光照的物体,而右边是一个受光照的物体,显然易见,右边更有立体感,而左边看着像个2d物体。这都是光照和阴影的功劳。实际上,我们在视觉上对世界的感知依靠与光照与材质
材质可以看作是确定光照和物体表面如何进行交互的属性集,其中的属性包括:表面反射光和吸收光的颜色,表面材质的折射率,表面材质的折射率,表面的透明度。根据这些属性,即可创造处许多种类的物体
光照现象
所有的光和物质相互作用都是两种现象的结果:散射(scattering)和吸收(absorption)
- 散射:发生在当光线遇到任何种类的光学不连续性时,可能存在于具有
不同光学性质的两种物质分界之处
,晶体结构破裂处,密度的变化处等。散射并不改变光的总量,只改变方向
。其中散射又分为反射(reflection)和折射((refraction)
- 吸收:发生在
物质内部
,造成一些光转变成另一种能量并消失。吸收会减少光量,但不影响方向
光照类型
光照类型有四种
-
漫反射光
当光线照射到表面某一点时会发生散射,一部分光进入物体内部,并和表面附近的物质相互作用,而另一部分光会向各个方向均匀散射
-
镜面光
当光线照射到两种不同折射率介质间的物体表面时,一部分光被吸收,而剩下的光发生散射(菲涅尔效应)。若折射光沿折射向量从介质的另一侧射出,并进入观察者眼中,此时物体将呈现透明状
-
环境光
由其他物体反射来的间接光照
-
自发光
物体自身发射的光
经验模型
经验模型有三种
-
Lambert漫反射模型
只考虑环境光和漫反射光.漫反射效果与光源位置有关,与观察者位置无关
漫反射公式
\(k_d\)为漫反射系数,I为入射光强度,n和l分别为法向量和入射方向
效果
可以看到漫反射已经让物体呈现出立体感了,但还缺少高光
-
Phong模型
额外考虑镜面反射
镜面反射公式
\(L_s = K_s(I / r^2)max(0, cos \alpha)^p\),其中\(\alpha\)是高光的反射方向与观察方向的夹角,而p用于衰减光强(因为离反射光越远,能看到的反射光应越弱)效果
-
Blinn-Phong模型
Blinn-Phong基于Phong模型将反射方向与人眼观察方向夹角替换为半程向量h和法线向量的夹角\(\alpha\)
Blinn-Phong与Phong模型的区别
- 半程向量相对反射向量计算更快,且效果差不多
- 若入射方向和视线方向不变,半角向量只需计算一次并重用
- phone模型在某些情况下效果不如Blinn-Phong模型,Blinn-Phong高光更加平滑。比如,当反射光方向与观察方向的夹角大于90°时(入射光与观察方向在同一侧),此时高光项为0无贡献,就会导致断层
效果
菲涅尔效应
-
什么是菲涅尔效应?
先来看这样一个例子,假设我们身处于一个水质清澈且面积很大的小池塘里,此时我们向下俯视,基本可以看清池塘底部,这是因为有部分光线照射到池塘,且以接近0.0°的角度反射进我们眼睛(由下处的菲涅尔方程可解释),也就是说反射到我们眼中的光量很低,而折射光量很高;现在我们换个角度观察,假设我们望向离我们较远的池水,会看到极强的反射光,这是因为有部分光线照射到池塘,且以接近90°的角度反射进我们眼中,可见反射光量是十分高的,这就是菲涅尔效应。总的来说菲涅尔效应便是
反射的光量取决于介质、法向量n和入射向量L间的夹角
-
石里克近似
菲涅尔方程以数学的方式描述入射光被反射的百分比,即\(R_F \in [0,1]\)(\(R_F\)为一个RGB向量),反射的光量与介质和法向量n和入射向量L间的夹角相关。若\(R_F\)为反射光量,则(\(1-R_F\))为折射光量
由于光照过程较为复杂,一般不会用完整的菲涅尔房产用于实时渲染,而是采用
石里克近似
(Schlick approximation)法来代替:\(R_F(\theta_i) = R_F(0°) + (1 - R_F(0°))(1-\cos \theta_i)^5\),其中\(R_F(0°)\)是介质的一种属性。\(R_F(0°)\)部分常见的有关属性数值如下
着色频率
我们以三角形面的法线向量和三角形顶点的法线向量计算出来的光照效果是不同的,以下将介绍三种着色频率
-
面着色/逐三角形着色(Flat Shading)
面着色以一个面作为一个着色单位,对每个面的法线向量进行一次Blinn-Phong反射计算.因为模型大部分都是以三角形进行表示的,所以也记录了每个三角形面的法线向量
效果
优点
- 计算很快
缺点
- 效果很差
-
逐顶点着色(Gouraud Shading)
逐顶点着色对每个三角形顶点进行一次着色
-
如何求得每个顶点的法向量?
将所有共享一点的面的法线向量求和再求平均,最后进行标准化
对于上图顶点法线的求法:\(n_{avg} = \frac{n_0 + n_1 + n_2 + n_3}{\|n_0 + n_1 + n_2 + n_3\|}\)
效果
-
-
逐像素(Phong Shading)
对三角形内每一点都进行光照计算
-
如何求得三角形内任意一点的法向量?
利用重心坐标(按理来说,重心坐标一定是采用观察空间里的重心坐标,但计算一般采用投影后的二维平面,这里存在一个误差需要进行矫正)公式进行插值https://www.cnblogs.com/chenglixue/p/16867745.html
效果
优点
- 效果很好
缺点
- 计算量太大
-
-
随模型精度的增加,三种着色方法的效果
可以看出,模型精度增加到一定程度,三种方法呈现的效果是差不多的
透视矫正
-
为什么需要透视矫正(Perspective-Correct Interpolation)?
在Phong Shading中,我们提到过通过使用重心插值的方式求三角形内任意一点,但这个重心插值的对象本应是世界空间中的坐标,但大多数计算都是使用透视投影后的二维平面内的数据,而恰恰问题就出在这里。如下图所示,在屏幕空间进行插值后得到c的intensity为0.5,但在观察空间中,点c的intensity不为0.5,也就是说透视投影后进行插值的坐标或属性会存在一定误差
-
如何进行矫正?
为了证明更简洁,在此处我们采用深度值z的插值且只考虑x,z轴来介绍
如下图所示,我们定义屏幕空间的插值比例为s,而观察空间的比例为t,坐标\(a(u_1,d),c(u_s,d),b(u_2,d),A(X_1,Z_1),C(X_t,Z_t),B(X_2,Z_2)\)
推导过程如下:
根据上图可以轻易得到以下三个式子:
- \(\begin{equation} \frac{X_1}{Z_1} = \frac{u_1}{d} \Rightarrow X_1 = \frac{u_1 Z_1}{d} \tag{1} \end{equation}\)
- \(\begin{equation} \frac{X_2}{Z_2} = \frac{u_2}{d} \Rightarrow X_2 = \frac{u_2 Z_2}{d} \tag{2} \end{equation}\)
- \(\begin{equation} \frac{X_t}{Z_t} = \frac{u_s}{d} \Rightarrow Z_t = \frac{d X_t}{u_s} \tag{3} \end{equation}\)
对观察空间和屏幕空间进行插值,可以得到如下三个式子:
- \(\begin{equation} u_s = u_1 + s(u_2 - u_1) \tag{4} \end{equation}\)
- \(\begin{equation} X_t = X_1 + t(X_2 - X_1) \tag{5} \end{equation}\)
- \(\begin{equation} Z_t = Z_1 + t(Z_2 - Z_1) \tag{6} \end{equation}\)
将式子(4)和(5)带入(3),可得:
\(\begin{equation} Z_t = \frac{d(X_1 + t(X_2 - X_1))}{u_1 + s(u_2 - u_1)} \tag{7} \end{equation}\)
将式子(1)和(2)带入(7),可得:
\(\begin{equation} Z_t = \frac{d(\frac{u1 Z_1}{d} + t(\frac{u_2 Z_2}{d} - \frac{u_1 Z_1}{d}))}{u_1 + s(u_2 - u_1)} = \frac{u_1 Z_1 + t(u_2Z_2 - u_1 Z_1)}{u_1 + s(u_2 - u_1)} \tag{8} \end{equation}\)
将式子(6)带入(8),可得:
\(\begin{equation} Z_1 + t(Z_2 - Z_1) = \frac{u_1 Z_1 + t(u_2 Z_2 - u_1 Z_1)}{u_1 + s(u_2 - u_1)} \tag{9} \end{equation}\)
观察式子(9)可以得知,已经成功求得一个t和s的关系式,化简可得:
\(\begin{equation} t = \frac{s Z_1}{s Z_1 + (1-s)Z_2} \tag{10} \end{equation}\)
将式子(10)带入(6),可得:
\(\begin{equation} Z_t = Z_1 + \frac{s Z_1}{s Z_1 + (1-s)Z_2}(Z_2 - Z_1) \tag{11} \end{equation}\)
对式子(11)化简,可得最终答案:
\(\begin{equation} Z_t = \frac{1}{\frac{1}{Z_1} + s(\frac{1}{Z_2} - \frac{1}{Z_1})} \tag{12} \end{equation}\)
虽然以上证明是线性插值的矫正过程,但对于重心坐标插值也同样适用。此处不再对其进行推导,直接给出公式。
重心坐标插值的透视矫正公式
:\(\begin{equation} Z_t = \frac{1}{\frac{\alpha}{Z_A} + \frac{\beta}{Z_B} + \frac{\gamma}{Z_C}} \tag{13} \end{equation}\)
-
推广,任意属性(法向量等)的插值结果
推导如下:
设任意属性为I
易得:
\(\begin{equation} I_t = I_1 + t(I_2 - I_1) \tag{14} \end{equation}\)
将式子(10)带入(14),可得:
\(\begin{equation} I_t = I_1 + \frac{s Z_1}{s Z_1 + (1-s)Z_2}(I_2 - I_1) \tag{15} \end{equation}\)
再排列一下:
\(\begin{equation} I_t = \frac{(\frac{I_1}{Z_1} + s(\frac{I_2}{Z_2} - \frac{I_1}{Z_1}))}{(\frac{1}{Z_1} + s(\frac{1}{Z_2} - \frac{1}{Z_1}))} \tag{16} \end{equation}\)
将式子(12)带入(16),可得:
\(\begin{equation} I_t = \frac{(\frac{I_1}{Z_1} + s(\frac{I_2}{Z_2} - \frac{I_1}{Z_1}))}{\frac{1}{Z_t}} \tag{17} \end{equation}\)
类似,推出重心坐标插值的任意属性公式:
\(\begin{equation} I_t = \frac{I_A\frac{\alpha}{Z_A} + I_B \frac{\beta}{Z_B} + I_c \frac{\gamma}{Z_C}}{\frac{1}{Z_t}} \tag{18} \end{equation}\)
变换法向量
-
为什么需要变换法向量?
虽然法向量存于世界空间,但从局部空间变化到世界空间可能会导致模型的位置形状发生改变。因此,法向量需随模型发生变化
-
如何进行法向量变化?
如下三图所示,向量u与法向量n正交,若对此应用一个非等比缩放变换A(下图将x轴放大两倍),变换后的u和n不再正交
那么问题来了,若给定一个用于变换点与向量的变换矩阵A,如何可以求出这样一个变换矩阵B:通过它变换法向量n,使变换后的u和法向量再次正交——\(uA · uB = 0\)?
-
推导
若法向量n正交于u,则能逐步推出:
- \(u·n = 0\)
- \(u n^T = 0\)。将点积变为矩阵乘法
- \(u(AA^{-1})n^T = 0\)
- \((uA)(A^{-1}n^T) = 0\)
- \((uA)((A^{-1}n^T)^T)^T = 0\)
- \((uA)(n(A^{-1})^T)^T = 0\)
- \(uA · n(A^{-1})^T = 0\)
- \(uA · nB = 0\)。即求出,\(B = (A^{-1})^T\)
-
reference
[Game-Programmer-Study-Notes/README.md at master · QianMo/Game-Programmer-Study-Notes · GitHub](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/《Real-Time Rendering 3rd》读书笔记/README.md)
https://games-cn.org/intro-graphics/
传统的经验光照模型详解_白筱风的博客-CSDN博客_光照模型
计算机图形学五:局部光照模型(Blinn-Phong 反射模型)与着色方法(Phong Shading)_剑 来!的博客-CSDN博客_计算机图形学光照模型
https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf
Directx12 3D 游戏开发实战
标签:begin,frac,局部,tag,光照,end,equation,向量 From: https://www.cnblogs.com/chenglixue/p/17140982.html