《Unity Shader入门精要》读书笔记05
第 5 章 Unity 中的基础光照
物理;一些定义
- 光源(light source):一个没有体积的点
- 辐照度(irradiance):在垂直于 的单位面积上单位时间内穿过的能量;和照射到物体表面时光线之间的距离 成反比, 可以用光源方向 和表面法线 计算。
- 散射(scattering) 只改变光线的方向,但不改变光线的密度和颜色。吸收(absorption) 只改变光线的密度和颜色 ,但不改变光线的方向。
- 折射(refracion)/ 透射(transmission)散射到物体的内部。
- 反射(reflection)散射到物体外部。
- 高光反射(specular),在光照模型中表示物体表面是如何反射光线的。
- 漫反射(diffuse),在光照模型中表示有多少光线会被折射、吸收和散射出表面。
- 出射度(shading)描述出射光线的数量和方向。辐照度和出射度之间是满足线性关系的,它们之间的比值是材质的漫反射和高光反射属性。
- 着色(shading) 指的是根据材质属性,使用一个等式去计算沿某个观察方向的出射度的过程。这个等式被称为光照模型(Lighting Model)。
- BRDF(Bidirectional Reflectance Distribution Function)光照模型,本章涉及的 BRDF 都是经验模型。
计算机图形学的第一定律:如果它看起来是对的,那么它就是对的。
标准光照模型
在BRDF理论提出前就被广泛使用了。基本理念由裴祥风(Bui Tuong Phong)提出。标准光照模型只关心直接光照(direct light),即直接从光源发射出来照射到物体表面后,经过物体表面的一次反射直接进入摄像机的光线。
标准光照模型将进入摄像机内的光线分为 4 个部分。
- 自发光(emissive) 。这个部分用于描述当给定一个方向时,一个表面本身会向该方向发射多少辐射量。在没有使用全局光照(global illumination)的情况下,这些自发光的表面并不会真的照亮周围。只是本身看起来更亮。
- 漫反射(diffuse) 。这个部分用于描述。当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。
- 高光反射(specular) 。这个部分用于描述,当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。
- 环境光(ambient) 。用于描述其他所有的间接光照。
自发光
直接使用该材质的自发光颜色:
漫反射
Lambert 光照模型。漫反射光照符合兰伯特定律(Lambert‘s law):反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比。
是表面法线, 是指向光源的单位矢量,是材质的漫反射颜色,是光源颜色。 可以防止物体被从后面来的光源照亮。高光反射
经验模型,并不完全符合真实世界中的高光反射现象。
用表示表面法线,表示指向光源的单位矢量,表示指向相机的单位矢量。可以计算反射方向:
用 Phong 模型计算高光部分:
是材质的光泽度(gloss)/ 反光度(shininess), 越大,亮点越小。 是材质的高光反射颜色,用于控制该材质对于高光反射的强度和颜色。 则是光源的颜色和强度。这里也用max()防止 为负数。Blinn 模型避免计算反射方向 ,引入新的矢量 。
Blinn 模型:
在硬件实现时,如果摄像机和光源距离模型足够远的话,Blinn 模型比 Phong 模型快, 以为此时可以认为 和 是定值, 同样;反之,Phong 模型可能更快。两者都是经验模型。
环境光
在真实的世界中,物体也可以被间接光照(indirect light) 照亮。我们用环境光来近似模拟间接光照。
逐像素or逐顶点
在片元着色器中计算光照模型,称为逐像素光照(per-pixel lighting)。Phong 着色(Phong shading)在面片之间对顶点法线进行插值,也被称为 Phong 插值或者法线插值着色技术。
在顶点着色器中计算光照模型,称为逐顶点光照(per-vertex lighting)。高洛德着色(Gouraud shading)在每个顶点上计算光照,然后在渲染图元内部线性插值。在某些情况下会产生明显的棱角现象。
总结
标准光照模型——Phong 光照模型;Blinn-Phong 光照模型。因为 Blinn 模型计算高光反射的方式和 Phong 模型不同,除了性能外,还有其他差异。
- 局限性:无法表现菲涅耳反射(Fresnel reflection);Blinn-Phong 模型是各向同性(istropic),然而现实中拉丝金属、毛发等表面是各向异性(anisotropic)反射性质的。
在 Unity 中实践
实践
在 Unity 中实现以下光照模型。
逐顶点的漫反射光照
1 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' |
- 将法线变换到世界空间,可以使用顶点变换矩阵的逆转置矩阵,
- 因此我们首先得到模型空间到世界空间的变换矩阵的逆矩阵_World2Object,然后通过调换它在mul函数中的位置,得到和转置矩阵相同的矩阵乘法。
- 由于法线是一个三维矢量,因此我们只需要截取_World2Obiect的前三行前三列即可。
- saturate函数是CG提供的一种函数,它的作用是可以把参数截取到[0,1]的范围内。
对于细分程度较高的模型,逐顶点光照可以得到较好的光照效果。但是对于细分程度较低的模型,逐顶点光照就会出现一些问题
逐像素的漫反射光照
- 顶点着色器不需要计算光照模型,只需要把世界空间下的法线传递给片元着色器即可;
- 片元着色器需要计算漫反射光照模型。
半兰伯特模型(Half Lambert)
兰伯特模型改善了“漫反射光照下,背光面没有明暗变化,导致细节缺失”的问题。由Valve公司在开发《半条命》时提出。
广义的半兰伯特光照模型公式:
通过这样的方式,我们可以把的结果范围从[-1, 1]映射到[0, 1]范围内。这样,背光面也可以用明暗变化。
需要注意的是,半兰伯特是没有任何物理依据的,它仅仅是一个个视觉加强技术。
逐顶点的高光反射
逐像素的高光反射
至此,实现了一个完整的 Phong 光照模型。
Blinn-Phong 光照模型
Blinn-Phong 光照模型的高光反射部分看起来更大、更亮一些。(和 Phong 模型相比)
实际渲染中绝大多数情况选择 Blinn-Phong 光照模型。
Unity 内置函数
- 这些函数都没有保证得到的方向矢量是单位矢量。所以使用前记得归一化。
- 部分函数只能在前向渲染中使用,如WorldSpaceLightDir、UnityWorldSpaceLightDir和ObjSpaceLightDir。
实践
使用内置函数来改写 Blinn-Phong 光照模型.shader
- 标题: 《Unity Shader入门精要》读书笔记05
- 作者: 铁名_IronName
- 创建于 : 2026-01-15 15:25:27
- 更新于 : 2026-01-17 13:44:29
- 链接: https://blog.ironname.top/2026/01/15/《Unity-Shader入门精要》读书笔记05/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。