使用 Direct3D 9 (纹理表示 PRT)

DirectX SDK 中包含的 PRTDemo 示例和 PRTCmdLine 模拟器表示网格顶点处的传输向量。 为了准确表示 PRT 信号,这可能需要对当前游戏不切实际的分割。 在纹理贴图中表示传输向量是一种替代方法,其数据成本与网格复杂性无关。 可通过多种方式使用 D3DX PRT 库生成传输矢量纹理贴图。

预计算传输向量

一种方法是修改 PRTDemo 和 PRTCmdLine 样本,以计算表面参数化中的每个纹素处的传输向量。 为此,请按以下步骤操作:

  1. 修改对 D3DXCreatePRTEngine 的 调用以从网格中提取纹理坐标 (ExtractUV 必须为 TRUE)
  2. D3DXCreatePRTBuffer 调用替换为具有相同纹理大小的 D3DXCreatePRTBufferTex

除 ComputeBounceAdaptive、ComputeSSAdaptive、ComputeSS 和 ComputeDirectLightingSHAdaptive 外,所有 ID3DXPRTEngine 方法均适用于每个纹素模拟。 虽然纹理空间模拟将生成正确的结果,但它通常可能相当缓慢,因为它最有可能以高密度计算传输向量。

另一种方法是计算具有纹理坐标的自适应每顶点 PRT 模拟 (,这些坐标将用于每纹素数据) ,然后使用使用 D3DXCreatePRTBufferTex 以适当的分辨率) 创建的输出缓冲区调用 ID3DXPRTEngine::ResampleBuffer (。 这适用于 SDK 中的所有 D3DX PRT 功能,通常比直接计算每个纹素传输缓冲区更高效。

运行时计算

如果使用单个聚类,则可以像任何其他纹理一样筛选和 mip 映射结果,像素着色器与 PRTDemo 附带的顶点着色器代码相同。

如果压缩生成多个群集,则无法筛选或 mipmap 数据,因为聚类分析索引不是连续的。 下面是处理多群集数据的一些替代方法:

  • 在像素着色器中自行执行所有筛选。 遗憾的是,由于性能原因,这通常不切实际。
  • 如果纹理是低分辨率非 mip 映射纹理 (即:光线贴图) ,则直接在纹理空间中直接计算光线(其中不会发生任何筛选)并用着色纹理呈现对象可能更有效。 这实质上是完全在 GPU 上创建的动态光映射。
  • 如果使用纹理图集 (请参阅 使用 UVAtlas (Direct3D 9) ) ,则可以通过让纹理空间中连接组件中的所有传输矢量位于同一群集中来手动聚类场景。 这样,可以筛选纹理,因为通过构造访问的所有纹素都将位于同一群集中。 给定人脸的群集 ID 可以从顶点着色器传播。

像素着色器具有少得多的无法编制索引的常量寄存器,因此像素着色器与顶点着色器稍有不同。 使用多个群集时,以低分辨率动态纹理和使用纹理负载存储每个群集的工作将是最高效的呈现方式。

预计算的辐射传输

PRT 演示示例

PRT 模拟器 (prtcmdline.exe)