欢迎大家来到IT世界,在知识的湖畔探索吧!
让我们正式看看什么是可微分渲染。
微渲染不仅包括普通的正向渲染过程,还包括反向渲染过程。众所周知,正向渲染是由游戏资源生成图像的过程,反向渲染是由渲染结果推导出游戏资源的过程。当然,这种理解是片面的,但是现在,为了便于我们理解,我们可以这么说。
我们来看看上图。普通的渲染可以看作是一个非常复杂的函数f,它的输入X包括相机位置、方位、物体的顶点位置、纹理、材质参数等。F的输出就是渲染结果y。
在这个图中,上半部分是拟合渲染,下半部分是地面真实渲染。输入是x_opt和x_gt,opt和gt分别代表优化和基本事实。它们可以在渲染函数f后分别得到y_opt和y_gt,在我们定义了屏幕空间的可微损失函数后,可以得到它们之间的差值Z,得到y_opt的偏导数。
如果渲染函数f可微,就可以求出y_opt对x_opt的导数,最后用链式法则求出z对x_opt的偏导数。
当得到这些参数集的导数后,整个问题就变成了一个优化问题,可以用梯度下降等优化算法对目标函数进行优化,得到最优的参数集。此外,可以将各种神经网络添加到系统的上游和下游,用于各种应用。
有了可微渲染,上述问题的统一解决方案,其实就是先渲染高质量的图片A,再渲染Lod的图片B,在屏幕空间找到它们之间的图片差异损失,然后找到待拟合参数的梯度,利用梯度下降算法找到参数的最优解。实际上有各种各样的损失函数。要拟合的参数包括模型、材质参数、贴图,甚至着色器函数。
所以剩下的核心问题就是如何让渲染变得可区分。当然,广义来说,渲染包括光栅渲染、光线追踪渲染、神经渲染等。今天只能讨论光栅渲染这部分。
与正向渲染过程不同,反向渲染需要导出大量参数,这是一个难题。例如,一个1024*1024的映射具有大约10的6次方的参数。对于如此大量的参数推导,普通的有限差分算法肯定不行。
而PyTorch和Tensorflow中的自动微分技术却无能为力,因为它们是为线性代数和神经网络计算而设计的。普通的神经网络应用只产生数百个计算密集型操作,如矩阵向量乘法或卷积等。而渲染计算会产生庞大的计算图,计算负载不均衡,对性能和内存来说太多了。我们将详细介绍如何解决这些问题并实现一个高效的光栅化可微分渲染器。
02可区分渲染流水线的实现
下面将按这个顺序介绍,首先是可微分渲染流水线的顶层架构,然后是可微分GPU模拟的实现,也就是如何让光栅化器可微分。接下来是可微分着色器编译器的实现,因为除了光栅化器需要可微分之外,着色器也是游戏的重要组成部分,它也需要可微分。最后简单介绍一下下层引擎资产服务器,它负责将引擎游戏资产提供给我们的可微分光栅化器进行拟合和学习,并将结果转化为游戏资产。
首先我们来看一下可微分渲染流水线的整体结构,主要包括分布式训练单元和可微分GPU模拟。
训练单元客户端封装并提供场景、素材、动画等数据,配置各种学习策略。
Mythal Core提供了核心差分光栅化器。在当前版本中,我们在CUDA/C上实现了完整的高性能正反向渲染流程,GPU版本的性能完全满足资产辅助制作业务例程的要求。其中,光栅化、插值、纹理采样、着色器等部分的核心支持区分。
此外,我们也在追求计划的标准化。正因如此,我们将mythal的渲染核心封装成一个符合vulkan驱动标准并适配vulkan 1.2 API接口的虚拟GPU。
让我们来关注一下Mythal Core的设计和实现。
对于Mythal的渲染核心,首先我们面临的是“易于分布式部署和高性能”这两个要求。我们参考了大量的移动GPU设计理念,也借鉴了现代GPU硬件和商用GPU仿真软件的许多优秀解决方案。最后,整个栅格化过程是以基于分层瓦片的栅格化方式构建的。
在这种层次结构下,一方面,任务可以以宁滨、瓦片等不同粒度组织部署,非常适合未来灵活的部署需求。另一方面,基于磁贴的结构对缓存更加友好,便于我们在设备上更好地利用L1缓存。
实际上,我们也是如此。这种层级结构和CUDA对L1缓存的强大控制,意味着在每一个阶段,数据在计算前通过“生产者”和“消费者”的模式上传到L1缓存,后续实际计算时访问的大量数据固定在芯片的缓存中。同时,分层可以使每一层有更小的任务划分粒度,这也意味着可以方便地利用warp级别的高性能同步机制。最后,我们在当代GPU硬件上支持许多重要功能,以满足高性能目标的需求。最右边的列表展示了HTBR的一些重要特征。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/96476.html