内容创建/渲染

Differential Slang:应用实例

 

Differential Slang 可以轻松地与现有的代码库集成,从 Python、PyTorch、CUDA 到 HLSL,以帮助执行多个计算机图形任务,并实现新的数据驱动和神经研究。在这篇文章中,我们介绍了几个使用可微分 Slang 的代码示例,以展示不同渲染应用程序的潜在用途和集成的容易性。

这是关于可区分俚语系列的一部分。要获取更多关于 Slang 语言中的差分编程和自动梯度计算的信息,请参阅Differential Slang:一种用于学习渲染器的着色语言

示例应用程序:基于外观的 BRDF 优化

计算机图形学中的基本构建块之一是 BRDF 纹理图,它表示材料的多种特性,并描述光如何与渲染表面相互作用。艺术家创作和预览纹理,但随后渲染算法会自动转换纹理,例如过滤、混合 BRDF 属性或创建 mipmaps。

渲染是高度非线性的,因此纹理贴图上的线性操作不会产生正确的线性变化外观。为了在 mipmap 链创建等应用程序中保持外观,提出了各种模型。这些模型是近似的,通常只为特定的 BRDF 创建;在呈现更改时必须设计新的。

我们建议使用可微分渲染和数据驱动方法来构建外观保持 mipmap,而不是细化这些模型。想要了解更多信息和代码示例,请访问 /shader-slang GitHub

Three columns of images showing the differences in rendering results of a surface with a brick-and-grass material.
图 1。反向渲染可以对材质进行外观保留缩小:(左)天真地向下采样的材质;(中)使用 Slang 优化的低分辨率材料;(右)参考。

在图 1 中,左列显示了使用天真的下采样材质渲染的曲面。中间一列显示了使用低分辨率材质渲染的同一曲面,该材质是通过使用 Slang 的自动微分功能实现的优化算法获得的。右列显示了使用参考材质而不进行下采样的渲染结果。使用优化材质的渲染比使用天真的下采样材质保留了更多的细节,并且匹配得更接近参考材质。

为了展示 Slang 的灵活性和与多个现有框架的兼容性,我们在 PyTorch 中编写了优化循环 Jupyter 笔记本,轻松实现了代码的可视化、交互式调试和 Markdown 文档。着色代码是用 Slang 编写的,这对图形程序员来说很熟悉。Easy Slang、Python、PyTorch 和 Jupyter 的互操作性使您能够选择用于数据驱动图形开发的最佳语言组合。

示例应用程序:纹理压缩

纹理压缩是一项优化任务,它可以显著减少纹理文件大小和内存使用,同时努力保持图像质量。有许多纹理压缩方法和许多不同的压缩器可用,其中最流行的是硬件块压缩(BC)。我们展示了如何使用梯度下降,通过 Slang 自动微分功能,为 BC7 模式 6 纹理压缩自动找到接近最优的解决方案。

通过使用梯度下降,我们不需要显式地编写压缩代码。Slang 通过模式 6 解码器的后向微分自动生成 BC7 块颜色插值的梯度:

[Differentiable]
float4 decodeTexel() {
return weight * maxEndPoint + (1 - weight) * minEndPoint;
}

为了便于压缩,我们提供了一个有效的初始猜测,将端点初始化为包围块的颜色空间框的角,并将插值权重设置为 0.5。我们对 BC7 量化进行建模,并迭代调整每个 4×4 块的端点和权重,确保原始纹理与其压缩版本之间的差异最小。

这种简单的方法实现了高压缩质量,为了获得最佳计算性能,我们将前向(解码)和后向(编码)过程合并到一个计算着色器中。每个线程在 BC7 块上独立工作,通过将所有数据保留在寄存器中并避免累积梯度的原子操作来提高效率。在 NVIDIA RTX 4090 上,这种方法每秒可以压缩 400 个 4k 纹理,压缩速度达到 6.5 GTexel/s。

这个示例是使用 Slang 和 Falcor 渲染基础设施的 Python 接口编写的。想要了解更多信息和代码示例,请访问 NVIDIAGameWorks/Falcor GitHub

应用示例:NVDIFFREC

Figure shows that the pipeline takes as input 2D images of an ancient artifact, and a randomly initialized soup of triangles, and outputs a triangle mesh whose shape and material matches the input images.
图 2:反向渲染管道nvdiffrec,用 Slang 重写,以与手工区分的 CUDA 内核相同的性能运行

Nvdiffrec 是一个用于优化关节形状、材质和照明的大型反向渲染库。Nvdiffrec 可以从一系列 2D 观测中重建各种场景属性,并可用于各种反向渲染和外观重建应用。

Nvdiffrec 是一个用于关节形状、材质和照明优化的大型反向渲染库。Nvdiffrec 根据一系列 2D 观测重建各种场景属性,并可用于各种反向渲染和外观重建应用。

最初,Nvdiffrec 的性能关键操作是使用 PyTorch 扩展来加速的,PyTorch 是用手工区分的 CUDA 内核构建的。CUDA 内核执行以下任务:

  • 损失计算(log-sRGB 映射和曲宽缩小)
  • 切线空间法线映射
  • 顶点变换(顶点数组与一批 4×4 矩阵的乘积)
  • 立方体贴图预过滤(用于分割和着色模型)

Slang 生成自动区分的 CUDA 内核,实现与手写、手动区分的 CUDA 代码相同的性能。这大大减少了代码行的数量,同时保持与其他 CUDA 内核的兼容性和互操作性。Slang 使代码更易于维护、扩展和连接到现有的渲染管道和着色模型。

想要了解更多关于 nvdiffrec 的 Slang 版本的信息,请访问 /NVlabs/nvdiffrec GitHub

示例应用程序:可微分路径跟踪器

我们将传统的实时路径跟踪器转换为可微分路径跟踪器,重用了超过 5K 行的 Slang 代码。以下是 Slang 中两个不同的反向路径跟踪示例:

结论

想要了解更多信息,请参阅 SLANG.D:快速、模块化和可微分着色器编程 论文,并开始探索可微分渲染 Slang

 

标签