像素的渲染是否可以在顶点着色器中终止。例如,如果顶点不满足某个要求,则取消该顶点的渲染?
答案 0 :(得分:15)
我假设你说“渲染顶点会被终止”。不,你不能; OpenGL对VS的输入顶点与输出的1:1比率非常严格。此外,它并不意味着你想要它,因为顶点不会被渲染。 Primitives 可以,并且基元可以由多个顶点组成。例如,丢弃三角形条带中间的顶点意味着什么。
这就是Geometry Shaders能够“剔除”原语的原因;它们专门处理原语,而不仅仅是单个顶点。这是通过简单地不发射任何顶点来完成的; GS必须明确地发出它想要输出的顶点。
顶点着色器现在能够剔除基元。这是使用the "cull distance" feature of OpenGL 4.5完成的。它就像gl_ClipDistance
,而不是剪切,如果其中一个顶点超过阈值,它会剔除整个图元。
答案 1 :(得分:11)
理论上,您可以使用顶点着色器生成退化(零区域)基元。具有零区域的基元不应导致任何栅格化,因此不会渲染任何片段。但是,它并不是特别直观,特别是如果您使用的是共享顶点的基元。
但不,取消顶点几乎毫无意义。它是构建基元的基本单元。如果只删除单个顶点,则将以未定义的方式更改栅格化输出。
简单地说,顶点不是在屏幕上创建像素的顶点。它是顶点之间的连接,它创建了最终导致像素的基元。几何着色器以原始为基础进行操作,因此它们通常以编程方式取消光栅化和片段着色。
的更新:强>
我注意到你使用GL_POINTS
作为原始类型。在这种特殊情况下,您需要做的就是防止顶点沿着管道向下移动,将其位置设置在摄像机查看量之外的某个位置。顶点将被剪裁,不会发生光栅化或片段着色。
这是一种更有效的解决方案,用于在片段着色器中测试某些条件然后丢弃,因为您跳过光栅化并且根本不必执行片段着色器。更不用说,discard
通常最终作为后着色器执行标志工作,告诉GPU放弃结果 - 无论您在着色器中的哪个位置发出{{{},GPU都经常被强制执行整个着色器1}}指令。因此discard
很少提供性能优势,并且在许多情况下,它可以禁用其他可能更有用的硬件优化。不幸的是,这就是GPU调度着色器工作负载的方式的本质。
最便宜的片段是您永远不必处理的片段:)
答案 2 :(得分:6)
您无法终止顶点着色器中的像素渲染(它不处理像素),但您可以使用 discard 指令在片段着色器中。
答案 3 :(得分:3)
我正在详细阐述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);
...然后你离开!
希望这有帮助
答案 4 :(得分:0)
您可以对顶点流进行更改,包括删除顶点,但执行此操作的位置将在几何着色器中。如果你研究几何着色器,你可能会找到你正在寻找的解决方案,而不是“发射”一个顶点。
编辑:如果渲染一个三角形条带,你可能还想在删除一个顶点时小心地开始一个新的图元;如果你调查geom,你会明白为什么。着色器。使用GL_POINTS,这不是一个问题。
是的,例如,如果你发送一个只有2个顶点的三角形条带,那么你确实无法渲染任何东西 - 正如你在第一时间传入这样一个退化条带时所做的那样。但这并不意味着顶点流不能在GL方面改变。
希望有帮助>汤姆
答案 5 :(得分:0)
将位置设置为ndc
或
设置标志并传递到片段,并根据该标志将其丢弃在片段中