该文章介绍了 Legacy Deferred Lighting (light prepass) rendering path 的详情。查看该文章获取延迟光照的技术概述。
Note: 延迟光照从Unity 5.0开始,被认为是旧的特性,所以它不支持某些渲染特性(例如 Standard shader, reflection probes)。新的项目应该考虑使用 Deferred Shading rendering path 来代替.
NOTE: 当相机使用正投影时,延迟渲染是不被支持的。如果相机的投影方式被设置为 Orthographic,该相机将一直使用 Forward rendering.
Overview
当使用 Deferred Lighting,那么作用在物体上的光照数量将没有限制。所有的光照都被逐像素的评估,这意味着所有的光照都能对法向贴图正确响应,等等。此外,所有的光源都有 cookies 和 shadows。
延迟着色的优点是光照的处理开销与被光照的像素数成正比。这由场景中光照的体积决定,不管有多少游戏对象被照亮。因此,保持小的光照,可以提升性能。Deferred shading 也有高一致性和可预见的表现。每个光照的影响被逐像素计算,因此在分解大三角时,没有光照计算。
在不好的方面,延迟着色没有真正支持抗锯齿,并且不能操作半透明游戏对象(它们会用 forward rendering)。它也不支持 Mesh Renderer 的 Receive Shadows 标记,并且culling masks只被有限制的支持。你最多只能使用4个culling masks。 也就是说,您的 culling masks层至少必须包含所有层除去四个任意层,因此必须设置32层中的28层。 否则您会得到错误的图形。
Requirements
它需要显卡有 Shader Model 3.0 (or later), 支持 Depth render textures 和 two-sided stencil buffers。大部分2004年后生产的PC显卡支持deferred lighting, 包括 GeForce FX and later, Radeon X1300 and later, Intel 965 / GMA X3100 and later。在手机上,所有有 OpenGL ES 3.0 功能的 GPUs 支持 deferred lighting, 并且 有一些 OpenGL ES 2.0 显卡同样支持 (那些支持depth textures的).
Performance Considerations
在延迟着色中,实时光照的渲染开销,是正比于被光照亮的像素数量的,而不取决于场景复杂度。因此小的点光源或放射光源的渲染是很廉价的,并且如果它们部分或全部被场景中的游戏对象遮挡,那么渲染代价会更加的廉价。
当然,有阴影的光照比没有阴影的光照开销更大。在延迟渲染中,有阴影的物体仍然需要为每个产生阴影的光源再渲染一次或多次。此外,提供阴影的光照着色比禁止阴影的着色有更高的开销。
Implementation Details
当延迟光照被使用,Unity的渲染过程发生在三个pass中:
1. Base Pass: 对象被渲染到结果屏幕空间缓存中,有depth, normals, 和 specular power。
2. Lighting pass: 前面生成的缓冲区用于将光照计算到另一个屏幕空间缓冲区中。
3. Final pass: 对象被再次渲染。它们去除计算过的光照,将它与颜色纹理组合并添加任何 ambient/emissive 光照。
对象的shader不能使用deferred lighting来渲染当延迟过程完成,会使用forward rendering path代替。
Base Pass
Base pass渲染每个对象一次。观察空间的法向和 specular power 被渲染进一个单独的 ARGB32 Render Texture (法向信息在 RGB 通道, specular power 在 A 通道)。如果平台和硬件允许 Z buffer 作为纹理来读取,那么深度不会明确的渲染。如果 Z buffer 不能作为纹理读取,按么深度将使用一个额外的渲染pass中渲染 shader replacement。
Base pass的结构是个 Z buffer 填充了场景内容和一个 Render Texture 含有 normals 和 specular power。
Lighting Pass
Lighting pass 基于深度,法向和specular power计算光照。光照在屏幕空间被计算,所有其计算时间不依赖于场景的复杂度。Lighting buffer 是一个独立的 ARGB32 Render Texture,有漫反射光照在 RGB 通道 和 黑白镜面光照在A通道。光照值是对数编码的,来提供比常规 ARGB32 纹理 更大的动态范围。当一个相机启用HDR渲染,那么lighting buffer 是 ARGBHalf 格式,并且不使用对数编码。
不通过相机近平面的点光源和放射光源被渲染为3D形状,当场景启用了深度测试。跨越近平面的光源也使用3D形状渲染,但是模型的后面采用反转的深度测试代替。这让部分或全部被遮挡的光源的渲染很廉价。 如果一个物体同时与相机的远近平面相交,上面的优化就不能被使用,光会被渲染为紧密的四边形,没有深度测试。
上述特性不支持平行光源,它们总被渲染为全屏的四边形。
如果光源启用阴影,它们同样会被渲染和提供在该pass中。注意阴影不是“免费”的;产生阴影的物体需要被渲染并且必须提供一个更复杂的光照shader。
唯一可用的光照模型是 Blinn-Phong。如果你希望使用不同的光照模型,请修改来自Built-in shaders 的 Internal-PrePassLighting.shader。替换到“Resources”文件夹在您的“Assets”文件夹中。 然后在Edit - > Project Settings - > Graphics窗口。改变“Legacy Deferred”列表的选项到您的“Custom Shader”。然后配置您的shader选项。
Final Pass
Final pass生成最终的渲染图像。在这里所有的对象会被再次渲染,取得光照,并与纹理组合,加上emissive lighting。光照贴图也是在次阶段提供的。靠近摄像机,使用实时照明,只添加间接照明。 随着远离相机,逐渐变为烘培全部光照。