glColorMask()/glDepthMask() 在现代硬件上的性能提升?
Performance gain of glColorMask()/glDepthMask() on modern hardware?
在我的应用程序中,我有一些着色器只写入深度缓冲区,以便稍后用于阴影。我还有一些其他着色器渲染全屏四边形,其深度不会影响所有后续绘制调用,因此它的深度值可能会被丢弃。
假设应用程序 运行s 在现代硬件上(从 5 年前到现在生产),如果我禁用阴影贴图着色器的颜色缓冲区写入 (glColorMask(all to GL_FALSE)
),我是否会获得任何额外的性能,和深度缓冲区写入(使用 glDepthMask()
)用于全屏四边形着色器?
换句话说,这些函数是否真的禁用了一些内存操作,或者它们只是改变了一些掩码位,这些掩码位在渲染管道的这一部分中用于固定的按位操作逻辑?
关于测试的同样问题。如果我事先知道所有片段都会通过深度测试,那么禁用深度测试会提高性能吗?
我的 FPS 测量结果没有显示出任何显着差异,但在另一台机器上的结果可能会有所不同。
最后,如果在禁用 depth/color test/write 的情况下渲染速度更快 运行,那么它 运行 会快多少?这种性能提升不会被 gl 函数调用开销抵消吗?
你的问题遗漏了一件非常重要的事情:你必须做一些事情。
每个片段都有颜色和深度值。即使你的 FS 没有产生价值,那里仍然会有价值。因此,每一个产生的没有被丢弃的片段都会写入这些值,只要:
- 颜色通过
glDrawBuffers
路由到颜色缓冲区。
- 有一个适当的 color/depth 缓冲区附加到 FBO。
- color/depth 写掩码允许写入。
因此,如果您正在渲染并且不想将其中一种颜色写入或写入深度缓冲区,则必须执行其中一种操作。更改 #1 或 #2 是 FBO 状态更改,这是您可以在 OpenGL 中执行的最重量级操作之一。因此,您的选择是更改 FBO 或更改写掩码。后者永远是性能更友好的操作。
也许在您的情况下,您的应用程序对 GPU 或 CPU 的压力不足以让这样的更改变得重要。但总的来说,改变写掩码比玩 FBO 更好。
If I know beforehand that all fragments will pass depth test, will disabling depth test improve performance?
您是否同时更改其他状态,或者这是您唯一感兴趣的状态?
查看这些先验性能问题的一个好方法是查看 Vulkan 或 D3D12,看看它在 that API 中需要什么。改变任何管道状态都是一件大事。但是改变两个状态并不比一个更重要。
因此,如果更改深度测试与更改其他状态(混合模式、着色器等)相关,则可能不会再造成任何伤害。
与此同时,如果您真的 非常关心性能,以至于这种事情很重要,您应该进行应用程序测试。这应该在您实现它之后发生,并且会发生在所有感兴趣的硬件上。而且您的代码应该足够灵活,可以根据需要轻松地从一种切换到另一种。
在我的应用程序中,我有一些着色器只写入深度缓冲区,以便稍后用于阴影。我还有一些其他着色器渲染全屏四边形,其深度不会影响所有后续绘制调用,因此它的深度值可能会被丢弃。
假设应用程序 运行s 在现代硬件上(从 5 年前到现在生产),如果我禁用阴影贴图着色器的颜色缓冲区写入 (glColorMask(all to GL_FALSE)
),我是否会获得任何额外的性能,和深度缓冲区写入(使用 glDepthMask()
)用于全屏四边形着色器?
换句话说,这些函数是否真的禁用了一些内存操作,或者它们只是改变了一些掩码位,这些掩码位在渲染管道的这一部分中用于固定的按位操作逻辑?
关于测试的同样问题。如果我事先知道所有片段都会通过深度测试,那么禁用深度测试会提高性能吗?
我的 FPS 测量结果没有显示出任何显着差异,但在另一台机器上的结果可能会有所不同。
最后,如果在禁用 depth/color test/write 的情况下渲染速度更快 运行,那么它 运行 会快多少?这种性能提升不会被 gl 函数调用开销抵消吗?
你的问题遗漏了一件非常重要的事情:你必须做一些事情。
每个片段都有颜色和深度值。即使你的 FS 没有产生价值,那里仍然会有价值。因此,每一个产生的没有被丢弃的片段都会写入这些值,只要:
- 颜色通过
glDrawBuffers
路由到颜色缓冲区。 - 有一个适当的 color/depth 缓冲区附加到 FBO。
- color/depth 写掩码允许写入。
因此,如果您正在渲染并且不想将其中一种颜色写入或写入深度缓冲区,则必须执行其中一种操作。更改 #1 或 #2 是 FBO 状态更改,这是您可以在 OpenGL 中执行的最重量级操作之一。因此,您的选择是更改 FBO 或更改写掩码。后者永远是性能更友好的操作。
也许在您的情况下,您的应用程序对 GPU 或 CPU 的压力不足以让这样的更改变得重要。但总的来说,改变写掩码比玩 FBO 更好。
If I know beforehand that all fragments will pass depth test, will disabling depth test improve performance?
您是否同时更改其他状态,或者这是您唯一感兴趣的状态?
查看这些先验性能问题的一个好方法是查看 Vulkan 或 D3D12,看看它在 that API 中需要什么。改变任何管道状态都是一件大事。但是改变两个状态并不比一个更重要。
因此,如果更改深度测试与更改其他状态(混合模式、着色器等)相关,则可能不会再造成任何伤害。
与此同时,如果您真的 非常关心性能,以至于这种事情很重要,您应该进行应用程序测试。这应该在您实现它之后发生,并且会发生在所有感兴趣的硬件上。而且您的代码应该足够灵活,可以根据需要轻松地从一种切换到另一种。