11

像素的渲染是否可以在顶点着色器中终止。例如,如果一个顶点不满足某个要求,取消该顶点的渲染?

4

6 回答 6

16

我假设您说“终止渲染顶点”。不,你不能;OpenGL 对 VS 的输入顶点与输出的 1:1 比率非常严格。此外,它并不真正意味着你想要它,因为顶点不会被渲染。图元可以,一个图元可以由多个顶点组成。例如,丢弃三角形带中间的顶点意味着什么。

这就是几何着色器能够“剔除”图元的原因;它们专门处理一个基元,而不仅仅是一个顶点。这是通过简单地不发射任何顶点来完成的;GS 必须明确地发出它想要输出的顶点。


顶点着色器现在可以剔除图元。这是使用OpenGL 4.5 的“剔除距离”功能完成的。就像gl_ClipDistance,只是不是裁剪,而是在某个顶点超过阈值时剔除整个图元。

于 2013-08-13T13:36:23.050 回答
13

理论上,您可以使用顶点着色器来生成退化(零面积)图元。面积为零的图元不应导致任何光栅化,因此不会渲染任何片段。然而,它并不是特别直观,尤其是当您使用共享顶点的图元时。

但是不,取消一个顶点几乎没有意义。它是构建基元的基本单位。如果您只是删除单个顶点,那么您将以未定义的方式更改光栅化输出。

简而言之,顶点并不是在屏幕上创建像素的东西。正是顶点之间的连通性创造了图元,最终导致了像素。几何着色器在逐个基元的基础上运行,因此它们通常用于以编程方式取消光栅化和片段着色。


更新:

我注意到您将其GL_POINTS用作原始类型。在这种特殊情况下,您需要做的就是将其位置设置在相机观察体积之外的某个位置,以防止您的顶点进一步沿着管道向下移动。顶点将被剪裁,不会发生光栅化或片段着色。

这是在片段着色器中测试某些条件然后丢弃的更有效的解决方案,因为您跳过光栅化并且根本不必执行片段着色器。更不用说,discard通常最终会作为一个后着色器执行标志来告诉 GPU 丢弃结果 - 无论您在着色器中的哪个位置发出discard指令,GPU 通常都被迫执行整个着色器。因此discard很少会带来性能优势,并且在许多情况下,它可以禁用其他可能更有用的硬件优化。不幸的是,这就是 GPU 调度其着色器工作负载的方式的本质。

最便宜的片段是您永远不必处理的片段:)

于 2013-08-13T19:21:38.930 回答
9

您不能在顶点着色器中终止像素的渲染(它不处理像素),但您可以在片段着色器中使用丢弃指令。

于 2013-08-13T13:31:09.263 回答
6

我正在详细说明 Andon M. Coleman 的答案,这值得恕我直言,被标记为正确的答案。

即使 OpenGL 规范坚持不能跳过片段着色器步骤这一事实(除非您实际上删除了几何着色器中的整个基元,正如Nicol Bolas 正确指出的那样,这有点矫枉过正恕我直言),您可以做到实际上,通过让 OpenGL 剔除整个几何图形,因为现代 GPU 具有早期的片段拒绝优化,这可能会产生相同的效果。

而且,为了记录,让整​​个几何图形被丢弃真的很容易:只需将顶点写在 (-1, -1, -1),(1,1,1) 立方体之外,

gl_Position = vec4(2.0, 2.0, 2.0, 1.0);

……你走吧!

希望这可以帮助

于 2015-11-28T10:29:52.023 回答
0

您可以对顶点流进行更改,包括删除顶点,但可以在几何着色器中进行。如果您研究几何着色器,您可能会发现您正在寻找的解决方案只是未能“发射”一个顶点。

编辑:如果渲染三角形条带,您可能还需要注意在删除顶点时开始新的图元;如果你调查geom,你会明白为什么。着色器。使用 GL_POINTS 将不再是一个问题。

是的,例如,如果您发送一个只有 2 个顶点的三角形条带,那么您确实无法渲染任何东西——就像您首先传入这样一个退化条带时所做的那样。然而,这并不意味着顶点流不能在 GL 方面进行更改。

希望有帮助>汤姆

于 2016-06-09T14:14:34.870 回答
0
  1. 将位置设置为 ndc

    或者

  2. 设置flag并传递给fragment,根据flag丢弃在fragment中

于 2020-11-04T07:49:18.960 回答