首页 > 解决方案 > 除了映射到剪辑空间之外,顶点函数还能做什么?

问题描述

Metal Shading Language 包含很多数学函数,但似乎Metal 官方文档中的大多数代码只是使用它来将顶点从像素空间映射到剪辑空间,例如

RasterizerData out;

out.clipSpacePosition = vector_float4(0.0, 0.0, 0.0, 1.0);

float2 pixelSpacePosition = vertices[vertexID].position.xy;

vector_float2 viewportSize = vector_float2(*viewportSizePointer);

out.clipSpacePosition.xy = pixelSpacePosition / (viewportSize / 2.0);

out.color = vertices[vertexID].color;

return out;

除了GPGPU使用核函数做并行计算外,顶点函数还能做什么,举几个例子?在游戏中,如果所有顶点位置都由 CPU 计算,为什么 GPU 仍然很重要?顶点函数通常做什么?

标签: metal

解决方案


首先,我将解决这个声明

在游戏中,如果所有顶点位置都由 CPU 计算,为什么 GPU 仍然很重要?顶点函数通常做什么?

我不相信我见过有人计算网格的位置,这些网格稍后将用于在 GPU 上渲染它们。它很慢,您需要将所有这些数据从 CPU 获取到 GPU(如果您有专用的 GPU,这意味着通过总线复制它)。而且它不是那么灵活。除了顶点位置之外,还有更多的东西需要产生任何有意义的图像,在 CPU 上计算所有这些东西只是浪费,因为 CPU 大部分情况下并不关心这些数据。

顶点着色器的唯一目的是为光栅化器提供位于剪辑空间中的图元。但还有一些其他用途,主要是基于不同 GPU 功能的技巧。

例如,顶点着色器可以将一些数据写入缓冲区,因此,例如,如果您不想在稍后的顶点阶段再次转换它,您可以流式输出转换后的几何图形,如果您有使用相同的多通道渲染几何不止一次。

您还可以使用顶点着色器仅输出一个覆盖整个屏幕的三角形,以便在整个屏幕上每个像素调用一次片段着色器(但老实说,您最好为此使用计算(内核)着色器)。

您还可以从顶点着色器中写出数据而不生成任何图元。您可以通过生成退化三角形来做到这一点。您可以使用它来生成边界框。使用原子操作,您可以更新最小/最大位置并在稍后阶段读取它们。这对于灯光剔除、平截头体剔除、基于瓷砖的处理和许多其他事情很有用。

但是,这是一个很大的问题您可以在计算着色器中完成大部分此类工作,而无需使用 GPU 来运行所有顶点组装管道。这意味着,您可以只使用计算着色器(而不是顶点和片段着色器以及介于两者之间的许多管道阶段,例如光栅化器、原始剔除、深度测试和输出合并)来制作全屏效果。您可以计算边界框并在计算着色器中进行灯光剔除或平截头体剔除。

有理由启动整个渲染管道而不是只运行计算着色器,例如,如果您仍将使用从顶点着色器输出的三角形,或者如果您不确定图元在内存中的布局方式,那么您需要顶点组装器来完成组装图元的繁重工作。但是,回到您的观点,顶点着色器的几乎所有合理用途都包括在剪辑空间中输出图元。如果您不使用生成的图元,最好坚持使用计算着色器。


推荐阅读