任意输出变量
任意输出变量 (AOV) 是 HDRP 摄像机可以生成的额外图像。这些变量可以输出每个像素的额外信息,你以后可以将其用于进行合成或其他图像处理(例如降噪)。
以下是三个 AOV 的示例,从左到右包含每个像素的反照率、法线和对象 ID:
在 HDRP 中,可以通过以下方式来访问和配置 AOV:
- 使用 HDRP 合成器工具。
- 使用 Unity Recorder 和 AOV Recorder 包。
- 使用脚本 API 在场景中的任何 HDRP 摄像机中设置自定义 AOV 请求。
前两个选项在其用户界面中提供了有限的 AOV 选择,而第三个选项在 HDRP 摄像机可以输出的数据方面大幅提高了灵活性。
材质属性 AOV
以下是可使用 AOV API 来访问的材质属性的列表。
材质属性 | 描述 |
---|---|
Normal | 输出表面反照率。 |
Albedo | 输出表面法线。 |
Smoothness | 输出表面平滑度。 |
Ambient Occlusion | 输出环境光遮挡(对于 AxF,为 N/A)。 |
Specular | 输出表面镜面反射。 |
Alpha | 输出表面 Alpha(像素覆盖率)。 |
通过 AOV 选择光照
可以使用 AOV 从选定光源列表中输出贡献值,也可以使用 AOV 来仅输出光照的特定分量。
光照属性 | 描述 |
---|---|
DiffuseOnly | 仅渲染漫射光照(直接和间接)。 |
SpecularOnly | 仅渲染镜面反射光照(直接和间接)。 |
DirectDiffuseOnly | 仅渲染直接漫射光照。 |
DirectSpecularOnly | 仅渲染直接镜面反射光照。 |
IndirectDiffuseOnly | 仅渲染间接漫射光照。 |
ReflectionOnly | 仅渲染反射。 |
RefractionOnly | 仅渲染折射。 |
EmissiveOnly | 仅渲染发射光照。 |
自定义通道 AOV
最后,可以使用 AOV 来输出自定义通道的结果。特别是,可以输出在每个自定义通道注入点上处于活动状态的所有自定义通道的累积结果。这可用于输出自定义通道计算的任意信息(例如场景游戏对象的对象 ID)。
脚本 API 示例
以下示例脚本从 HDRP 摄像机输出反照率 AOV,并将生成的帧以一系列 .png 图像的形式保存到磁盘。要使用此示例脚本,请将其附加到 HDRP 摄像机并进入运行模式。
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering.HighDefinition.Attributes;
public class AovRecorder : MonoBehaviour
{
RTHandle m_TmpRT; // 用于渲染 AOV 的 RTHandle
Texture2D m_ReadBackTexture;
int m_Frames = 0;
// 在第一帧更新之前调用 Start
void Start()
{
var camera = gameObject.GetComponent<Camera>();
if (camera != null)
{
var hdAdditionalCameraData = gameObject.GetComponent<HDAdditionalCameraData>();
if (hdAdditionalCameraData != null)
{
// 初始化新的 AOV 请求
var aovRequest = AOVRequest.NewDefault();
AOVBuffers[] aovBuffers = null;
CustomPassAOVBuffers[] customPassAovBuffers = null;
// 通过表面反照率请求 AOV
aovRequest.SetFullscreenOutput(MaterialSharedProperty.Albedo);
aovBuffers = new[] { AOVBuffers.Color };
// 分配 RTHandle 来存储中间结果
m_TmpRT = RTHandles.Alloc(camera.pixelWidth, camera.pixelHeight);
// 向新的 AOVRequestBuilder 添加请求
var aovRequestBuilder = new AOVRequestBuilder();
aovRequestBuilder.Add(aovRequest,
bufferId => m_TmpRT,
null,
aovBuffers,
customPassAovBuffers,
bufferId => m_TmpRT,
(cmd, textures, customPassTextures, properties) =>
{
// 通过回调读回 AOV 数据并将其写入磁盘
if (textures.Count > 0)
{
m_ReadBackTexture = m_ReadBackTexture ?? new Texture2D(camera.pixelWidth, camera.pixelHeight, TextureFormat.RGBAFloat, false);
RenderTexture.active = textures[0].rt;
m_ReadBackTexture.ReadPixels(new Rect(0, 0, camera.pixelWidth, camera.pixelHeight), 0, 0, false);
m_ReadBackTexture.Apply();
RenderTexture.active = null;
byte[] bytes = m_ReadBackTexture.EncodeToPNG();
System.IO.File.WriteAllBytes($"output_{m_Frames++}.png", bytes);
}
});
// 立即构建 AOV 请求
var aovRequestDataCollection = aovRequestBuilder.Build();
// 最后设置对摄像机的请求
hdAdditionalCameraData.SetAOVRequests(aovRequestDataCollection);
}
}
}
}