【问题标题】:Deferred render vs forward render + early-z延迟渲染与前向渲染 + early-z
【发布时间】:2021-01-11 09:24:26
【问题描述】:

如果是前向渲染,那么FS执行的次数是(numberOfAllPixels * numberOfLights),如果是延迟渲染,那么FS执行的次数是(numberOfVisiblePixels * numberOfLights)。

所以如果我在前向渲染中加入early-z,那么FS执行的次数也变成了(numberOfVisiblePixels * numberOfLights),那么延迟渲染没有任何优势吗?

【问题讨论】:

  • 您所说的“numberOfAllPixels”实际上是在渲染过程中生成的片段数,而“numberOfVisiblePixels”只是帧缓冲区的像素数。但是“如果是延迟渲染,那么 FS 执行的次数就是 (numberOfVisiblePixels * numberOfLights)”。是一个错误的假设。延迟的一个要点是使用一些光体积几何体仅在可以产生任何效果的地方渲染光。如果你有很多灯都会影响整个屏幕,那么延迟会因带宽使用而杀死你,而不是向前过度绘制。

标签: opengl graphics render vulkan


【解决方案1】:

在前向渲染中,您必须多次重新渲染整个场景。在延迟渲染中,您只需渲染一次场景即可。

重新渲染整个场景意味着重新做一堆工作,包括但不限于:

  • 场景的 CPU 处理。也就是说,遍历场景图并发出渲染命令。
  • GPU 处理绘图命令之间的状态变化..
  • GPU 读取网格的顶点数组。
  • 顶点着色器执行。

所有这些都只需要在延迟渲染中发生一次。

别忘了“early-z”不是免费的。不仅要生成这些三角形,而且还必须对它们进行光栅化。它们必须深入到处理管道中才能被剔除。这不是什么大不了的事,但也不是什么都不是。

所以是的,前向渲染中的深度预传递意味着您仅在绝对必要时才运行 FS。但是你仍然在运行一大堆不必要的东西。

【讨论】:

  • 为什么要多次重新渲染整个场景?你的意思是每盏灯一次吗?如果是这样,您可以将一组灯光作为统一传递,并遍历片段着色器中的灯光。
  • @tuket:是的,你可以。但问题的前提是:“FS 执行的次数是 (numberOfAllPixels * numberOfLights),*”如果是这样,那么这意味着您正在为每个灯光渲染整个场景,这是常见的- 呈现前向渲染的愚蠢方式。
  • 如果您在片段着色器中迭代灯光数组,它将是numberOfAllPixels * numberOfLights。如果为每盏灯渲染整个场景,你也会为每盏灯重复顶点变换,所以它会是numberOfLights * (numberOfAllPixels + numberOfVertices)
  • @tuket:问题的前提是“FS 执行的次数”不是“FS 执行中的循环数”或“顶点变换的数量”或其他。我回答的重点是让 OP 的注意力从“FS 执行的次数”上移开,看看其他事情是如何受到影响的。
  • 啊,好吧,有道理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多