全局光照由两部分组成:直接光照和间接光照。
直接光照由直接光照射到物体上以后直接弹射到人眼接收到的光照。
间接光照为直接光照照射到物体上又弹射到其它物体上面以后多次弹射才被人眼接收的光照(两次及以上的光照统称为间接光照)
材质光照编写的部分:
- 直接光:直接光漫反射,直接光镜面反射,阴影遮挡
- 间接光:间接光漫反射,间接光镜面反射,环境遮挡
- 自发光
注意:间接光也是可以分直接光和间接光部分的,只是现在的技术还不能实时的计算,现在的实时渲染只用来计算精确的直接光,其它直接放到的间接光里面去计算。所以,现在的间接光源里面除了计算直接光生成的间接光照,还有一些无法实时计算的天光和环境光,自发光,区域光的部分内容。
光照组成:
- 精确的光源直接光照
- Baked GI :包含精确光源的间接光漫反射、以及环境光源的漫反射(直接+间接)
- Reflection :周围环境的镜面反射(直接+间接)
- 自发光
游戏中常用的光照技术
实时光照模型
- Lambert 基础漫反射实现 NdotL
- Phong Lambert的基础上增加了镜面反射
- PBR 基于物理的渲染技术。 可以对光和材质之间的行为进行更加真实的建模。一般在游戏中会使用BRDF(双向反射分布函数)进行计算绘制。
优势:产生动态光照效果
缺点:计算消耗大,无法实时计算间接光
实时阴影技术
- Planar Shadow 平面阴影,通过压扁模型到一个平面实现阴影的渲染。效率高,无法和模型之间进行交互,只是一个平面。因为省,一般在手机低性能设备上使用。
- Projector Shadow 是常用的实时阴影实现方式,其基本原理是通过摄像机将需要显示阴影的物体,渲染到一张RenderTexture(RT)上,记录下物体的颜色值(可设置为自定义颜色),并将RT关联到Projector组件的材质上;然后通过Projector组件将需要接收阴影的物体以Projector组件的材质再渲染一遍来实现阴影的显示。Projector(投影仪)是一种常用的虚拟现实和增强现实工具,可以将三维画面投射到房间内的墙壁或幕布上,从而形成立体的虚拟环境。在Unity中,您可以使用Projector组件来实现类似的效果。
- ShadowMap 光源看不到的地方,就是处于阴影的地方。这也是游戏常用的方式,具体实现方式是以光源为相机进行一张深度图渲染,然后进行模型渲染只要比深度图的深度要大,则处于阴影中。为了保证精度以及大场景阴影渲染,采用级联阴影贴图。CSM(Cascaded Shadow Map)是一种利用分层的ShadowMap技术实现大场景的阴影算法。它将视锥体进行从近到远的划分,为每个分片生成一张相同分辨率的光源空间下的深度图,再根据视线到物体之间的距离,决定该区域下使用哪张深度图进行深度比对,从而在不同区域下得到精度不同的阴影。而防止锯齿需要软阴影则使用平均深度贴图。PCF(Average Depth)是一种常用于渲染阴影的技术,它利用了物体表面反射和漫反射的特性,通过逐点比较像素的深度值来生成平均阴影。与SSM(Single Slope Shadow Map)类似,PCF也是基于光线跟踪算法的一种渲染方式,但它不需要预先计算光线的传递函数,而是通过逐点比较像素的深度值来生成平均阴影。相比SSM,PCF的精度更高,能够更好地表现出物体的明暗变化。
- Unique Character Shadows 是指在不同物体之间具有独特阴影表现的技术。你需要额外的渲染一张深度图使用,比如在角色身上单独渲染一张高精度的shadowMap,用于提高角色身上的阴影精度。然后再加上pcss,ShadowPCSS(百分比软阴影),生成感知准确的柔和阴影。早前unity实现的点击这里
- Per Object ShadowMap 由于静态平行光源下的静态物体均可在离线状态下烘焙阴影到 Lightmap(Shadow mask),此时若使用 CSM 渲染余下的少量动态物体将会造成 Shadowmap 的浪费。使用逐物件阴影解决方案会得到比较显著的 GPU 性能提升。当前HDRP引擎已经支持,在相机上面,可以设置Static Shadow Caster 来开启单个阴影渲染。点击这里 可以查看github上面开源的项目学习。这种实现需要光源和物体都保持不动。
- Capsule Shadows 是一种动态阴影,可以对模型的蒙皮进行投射,通常是在物体表面上产生球形或半球形的阴影。它可以用来增强模型的立体感和真实感,并且可以根据光线的变化而改变形状和颜色。可以用来增强人的立体感,可以用作扩充ao。点击这里 查看商店内的实现。
- Contact Shadows是一种用于控制高清渲染管线光线在深度缓冲区内行进阴影的属性。它可以为场景添加更为准确的阴影近似,从而实现其他阴影算法难以达到的波状外形阴影,为角色增添更多的细节和真实感。要在HDRP资源中启用Contact Shadow功能,可以在Lighting > Shadows > Use Contact Shadows选项中进行设置。这种技术实现是通过光线步进的方式实现,性能消耗比较大,所以在urp和内置渲染管线中没有实现。ue中的实现,点击这里。
实时阴影的优点就是能够产生动态的实时阴影,缺点是消耗大,不够逼真(相对于来说,比没有强)。
预先烘焙 LightMap
原理
Unity LightMap的原理是将场景中的灯光与物体产生的光照与阴影信息烘培在一张或者多张Lightmap贴图中,这些物体将不再参与实时光照计算,从而减少了大量的性能开销。
在lightmap烘焙原理上,会接触到两个单词:
辐照度(Irradiance)是指物体受到的电磁辐射能量密度。
辐射率(Radiance)是指衡量物体表面以辐射的形式释放能量相对强弱的能力。物体的辐射率等于物体在一定温度下辐射的能量与同一温度下黑体辐射能量之比。黑体的辐射率等于1,其他物体的辐射率介于0和1之间。
简而言之,辐照度就是单位时间物体表面接收的光照能量。辐射率就是物体表面反射出去的能量比例。
实现过程:
- 给每个需要lightmap的模型单独生成一组UV。
- 利用unity内置的离线渲染器进行贴图生成,每个模型都有对应的贴图。
- unity会将贴图合并成为图集,并对uv进行tillingoffset进行设置,以及设置好模型拾取的lightMap图集的纹理的下标,保证模型拾取到对应的数据。
- 在shader中,读取对应的lightMap纹理,通过tillingOffset以及LightMapUV进行数据采样,生成相应的光照效果。
优点
消耗低,能够保存直接光和间接光的漫反射效果,以及物理正确的高保真效果,还能烘焙其它多种信息(AO等)
缺点
- 需要额外生成一套LightMapUV。
- 只能对静态物体产生作用,无法与场景中动态物体产生响应。
- 只能烘焙漫反射信息,无法体现动态镜面反射效果。
- 一些复杂表面物体会占用大量的LightMap像素,例如插片很复杂的树叶,大量放置的草,小石头,栅栏,电线,管道,装饰等。
预先烘焙 光照探针 Light Probe
原理
光照探针是存在于场景中的具体的空间点,能够捕捉某一点位置上的辐照度(Irradiance),通过球谐函数的方式存储数据。Light Map 和 Light Probe 一样都是存储辐照度(Irradiance),区别在于Light Map是存储在2D纹理上面,只用于静态烘焙的物体上面,而Light Probe则是保存的是3D空间某一个位置点的SH系数。
实现过程:
- 在unity中创建Light Probe Group,可以按需求编辑探针组内点的数量。
- 通过烘焙生成照明,来生成每个点的光照数据。
- 在shader中获取SH数据来设置模型的环境光的漫反射数据。
优点
- 无需生成额外的UV,计算速度快,消耗低
- Light Probe计算把光照信息存储在3D空间点上面。任何物体可以根据当前位置采集到Light Probe的数据。解决了Light Map无法应用在动态物体上的缺点。
- 可以给所有的物体提供光照(包括粒子,体积雾等)。
- 可以保存直接光和间接光漫反射为SH系数,作为参数使用。
- 可以烘焙遮挡信息(Occlusion Probes)
缺点
- Light Probe是Per-mesh sampling,就是每个mesh使用的同一套的SH数据,最多由三个Light Probe计算得出。精度上面相对于Light Map的像素级别的控制要差很多。
- Light Probe是稀疏的摆放结构,如果摆放的密度不对,会出现漏光的情况,比如室内和室外的区分(解决方案就是要区分出室内和室外的区域,原神的解决方案是用一个box框出区域)。
扩展
- 光照探针代理体(Light Probe Proxy Volume)以及Unreal的体积光照贴图(Volumetric Lightmaps)点击这里
- 在HDRP中有Adaptive Probe Volumes (APVs) 自适应探针体积 点击这里
- 《使命召唤:无限战争》:Precomputed Lighting
- 《全境封锁》PRT(Precomputed Radiance Transfer Probes)
未来趋势
LightMap做不了的事情,交给Light Probe(给动态物体提供环境漫反射)
LightMap做得了的事情,未来也会被Light Probe 取代
Refletion Probe(IBL技术)
IBL(Image Based Lighting)是一种用于游戏中的照明系统,它利用了图像采样技术来模拟真实世界的光照效果。与传统的光照系统不同,IBL系统不需要在游戏中实时计算光源的位置和强度,而是将真实世界的光照效果预先制作成一个 Cubemap 或者反射探测器的材质,然后在游戏中通过采样这个 Cubemap 或者反射探测器来实现光照效果。
文章
在uinty中实现
- 在unity中创建一个Refletion Probe。
- 设置好相关配置后,点击Bake生成当前位置拾取的周围的光照图像(无法拾取到动态模型的图像)。
- 在shader中实现采样Refletion Probe生成的Cubemap用于生成环境光的镜面反射。
特性
它可以通过设置区域,也就是一个包围盒,让物体渲染时选择采样哪个Refletion Probe。
新特性可以采样两个Refletion Probe进行融合,动态物体可以有光滑的过渡效果。
优点
- 能够表现间接光的镜面反射效果(IBL)
- 预先生成图像,性能消耗相对较低(内存增加,空间换时间)
缺点
- Refletion Probe的摆放是稀疏的,因此反射是非常不准确的,很容易出现漏光现象,这也是PBR渲染中常见的现象。(可以使用Normalized Reflection Probe解决此问题,性能消耗会提升)
- 特定需求下需要实时反射,也就是实时获取Refletion Probe,性能损失过大。(可以使用双抛物面贴图 Dual-Paraboloid Map,只需要采样两次即可生成一个不错的Cubemap,在GTA V中使用)
SSR 屏幕空间反射
屏幕空间反射(Screen Space Reflection, SSR),又叫实时局部反射(Realtime Local Reflection, RLR),是一种计算机图形学中的一种特殊效果,它可以在屏幕上产生类似于凹凸不平的表面的效果。当物体位于屏幕上时,它会产生镜像效果,从而使得屏幕上的物体看起来有些模糊或者是凸出。
实现原理
最简单的原理是:获取到屏幕的法向和深度,每个像素点进行射线弹射,找到当前对应的深度位置,拾取相应的颜色数据(Linear Raymarch)。
文档地址
优点
- 反射是实时更新的
- 适用于任何物体
- 反射效果相对接近物理正确
- 有非常逼真的模糊效果
缺点
- 物体拾取点在屏幕外,是无法拾取到的,只能拾取屏幕内的颜色,会造成失真。视频地址
- 屏幕边缘的效果也会有瑕疵。
- 目前只适用于Deferrd管线(需要屏幕深度,屏幕法向),在Forward管线下,消耗较高。
SSGI 屏幕空间全局光照
SSGI是Screen Space Global Illumination。通过向屏幕视图内的对象添加动态间接光照来创建自然光照。利用SSGI,还可从自发光表面(例如霓虹灯或其他明亮表面)获得动态光照。
unity: 插件 Radiant Global Illumination
技术git Unity Screen Space Tech Stack
ue:屏幕空间全局光照
Planar Refletion 实时平面反射
在一个平面上面渲染其朝向的物体的反射效果。
优点
- 适用于平面模型上面(地板,水面等),能够正确的呈现出比较正确的镜面反射效果。
- 能够没有渲染的背面,以及屏幕外的物体。
缺点
- 只适合用在平面上,不能用在任何结构复杂的表面。
- 它的实现是通过一个额外的相机实时渲染一张反射图,有额外的消耗。如果需要粗糙的效果还需要模糊效果,增加消耗。
SSAO 屏幕空间环境光遮蔽
原理
- 第一种是不带法向只是用深度的,获取某一个像素的被遮挡管线,会先获取它的世界空间坐标,然后再基于当前位置,在周围一定范围随机撒点,然后判断这些随机点是否被遮挡,计算出一个被遮挡的比例实现。
- 第二种是带有法向的,与上面的区别就是会根据其世界空间下的朝向去撒点,这样可以提高精度。
优点
- 效果是实时渲染的,可以实现屏幕中的正确遮挡关系。
- 适用于任何物体表面。
缺点
- 屏幕的边缘会有瑕疵
- 需要额外的法向和深度贴图,需要一定的计算损耗,移动平台损耗大。
Ray Tracing 光线追踪
本来想直接写实时光追的,但是实时光追是从光线追踪进化来的,所以在这里补一下光线追踪的相关信息。由于光线追踪的实现极其复杂并且考虑很多情况的处理,这里只使用通俗易懂的方式对原理进行解析。
递归光线追踪(Recursive Light Tracing,RLT)
递归光线追踪的方式是在绘制一个像素的颜色时,会在世界空间下从相机发射一条射线,穿过像素的世界位置,触碰到物体后,分散出三条射线:
- 朝向光源发射一条射线 来获取到光源的贡献
- 基于法向计算出反射方向发射一条射线,获取到触碰物体对它反射的贡献
- 基于法向计算出透射方向发射一条射线,获取到可以穿透的关系对它的贡献
每条光线以此递归下去,来获取光线追踪渲染的效果。
路径追踪 Path Tracing
路径追踪是在离线渲染器中常用的一种追踪算法,只要算力足够,它可以表现出真实的渲染效果。
其视线原理是通过像素点获取实际渲染场景中的位置,然后根据位置的法向朝向半球区域发射出n根射线(常用的是蒙特卡洛积分),每根射线接着发散,按照此方法继续发散,根据获取到的颜色进行处理得到。
路径追踪计算直接光和间接光是可以分开计算的,比如直接光朝向光源区域进行发散n跟射线,间接光则是往周围的物体投射n根射线去发散。
路径追踪的质量是由发散的射线的数量决定的(samples),数量越多,越接近于现实。相应的,计算量也会几何上升,比如每个点发射256根射线,每根射线弹射四次,那么,这个点的计算量就是256的四次方,那就是四百多万次,计算量非常的庞大。可想而知,现实生活中的渲染计算量多么庞大(狗头)
Real-Time Ray Tracing 实时光追
实时光追技术有别与传统的离线渲染器(路径追踪)。实时光追是在基于光栅化渲染器的基础上,利用GPU加速光线追踪计算出某些光照效果,将结果输出成屏幕RT,然后传递到光栅化的渲染管线中去。其实是一种光栅化渲染与光追技术混合使用的方式。
实时光追可以看做是屏幕空间技术的升级版。
实时光线追踪功能
- 光线追踪阴影
为环境中的物体模拟柔和的面积光照效果。这意味着根据光源的大小或光源角度,物体的阴影在靠近接触面的部分会比较锐利,离接触面越远就越柔和且变宽。
- 光线追踪反射(RTR)能够模拟准确的环境表现,并且可支持多次反射。图上显示顺序分别为屏幕空间反射 (SSR),单次反弹的光线追踪反射,多次反弹的光线追踪反射。相比之下,SSR仅能进行一次反射反弹,并且仅限于屏幕上的可见内容。与之不同的是,RTR能够多次反弹,并且不会局限于屏幕上的可见内容,这意味着我们可以看到书的侧面、摄像机背后的反射效果,以及通过窗户反射到表面上的额外灯光。
- 光线追踪半透明光线追踪半透明(RTT)能准确表现玻璃和液体材质,在透明表面上显示符合物理的正确反射、吸收和折射。
- 光线追踪环境光遮蔽光线追踪环境光遮蔽(RTAO)准确地对环境光照被遮挡的区域投射阴影,使物体更好地融入环境,例如在角落和墙壁相交处投射阴影,或者为裂缝或皮肤上的皱纹增添深度。
- 光线追踪全局光照光线追踪全局光照(RTGI)会对那些未被光源直接照射的场景区域施加实时交互反射光照效果。
文档查看地址:uereal
光照方案
直接光漫反射
动态物体使用实时光照模型计算 静态物体烘焙到LightMap/LightProbe
直接光镜面反射
实时光照模型计算
直接光阴影
动态物体 使用实时阴影技术计算 静态物体烘焙到LightMap/LightProbe
间接光漫反射
- 烘焙到LightMap/Light Probe
- 预计算技术,使用Dynamic LightMap / Light Probe
- 高端设备使用 SSGI 或 光线追踪GI
间接光镜面反射
- 反射球Refletion Probe(IBL技术)一部分增加Planar Refletion
- 高端设备使用SSR 或 光线追踪反射(RTR)
间接光遮挡
- SSAO + 烘焙AO
- 高端设备 光线追踪AO(RTAO)