【问题标题】:Disable/skip vertex in shader在着色器中禁用/跳过顶点
【发布时间】:2011-11-10 20:56:54
【问题描述】:

我正在使用 WebGL 将巨大的点云(1.5 Mio. 点)渲染为 GLPoints,自然会遇到性能问题。

所以我的第一个想法是限制在屏幕上绘制的点数。尤其是远离相机的点是“无用的”,不应该被渲染。

我通过计算任意点与相机之间的距离来解决这个问题。在我的顶点着色器中,我只想将点渲染得离相机足够近。到目前为止,如果距离“s”在相机和剪切平面之间(因此为负数),我会尝试跳过它们。

if( s < 0.0){
  gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
  frontColor = vec4(0.0, 0.0, 0.0, 1.0);
  gl_PointSize = 0.0;
}else{
  gl_Position = ps_ProjectionMatrix * ecPos4;
}

但是,正如我从显示的 FPS 中看出的那样,它仍然被渲染(即使我没有看到它),而不是完全跳过顶点。 有没有办法完全禁用/跳过/“删除”顶点着色器中的顶点?


我可以看到截锥体剔除如何帮助加快处理速度。为了澄清事情,扑杀应该在什么时候进行?由于每次摄像机移动后都必须重新计算剔除,我应该放入主循环吗?但是做 1 Mio。渲染循环中的计算似乎不是一个好主意。

我是否正确理解,一旦我的相机看起来与我的点完全不同的方向,这些应该由 WebGl/硬件自动剪辑?然而,我觉得“远离”并没有帮助。 (FPS没上)谁能详细说明一下!

我使用的引擎有一个默认的透视投影矩阵。显然它会影响每个顶点的坐标。投影矩阵与自动裁剪有什么关系?

【问题讨论】:

  • 欢迎来到 StackOverflow,希望您阅读FAQ
  • 嗨,克里斯蒂安。我读了它,但它没有详细介绍礼仪。显然不应该问候或感谢其他用户?对吗?
  • 不是那么严格,但它用不必要的喋喋不休使问题变得臃肿。但我在评论中没有提到这一点。我只是想确保您了解该网站的运作方式,因为新手有时会将其误认为是一个论坛。对不起,如果我的评论让您感到困惑,您的问题实际上还不错。
  • 在两个答案中查看我的 cmets。软件截锥体剔除绝对不能解决您的问题。只需在顶点阶段完成其工作后,让 OpenGL 的硬件视图截头截体剪裁即可。顺便说一句,这不是答案,应该是原始问题的评论或附件。
  • 您只需要调整投影矩阵以获得更紧密的远平面。如果您不知道怎么做,或者不知道什么是远平面,那么请深入研究基本的 3D 计算机图形,尤其是变换。

标签: opengl-es-2.0 shader webgl vertex


【解决方案1】:

听起来您需要调整投影矩阵,以便您的视锥剔除那些距离太远而无法对您的图像做出有意义贡献的点。这个tutorial from lighthouse3d 提供了对视锥体的描述,并描述了在软件中实现基于视锥体的剔除的方法。请注意,这在您的情况下不是必需的,因为 OpenGL 会为您执行此操作,前提是您已正确设置投影矩阵。

【讨论】:

  • 好点,没想到这一点。最简单的事情总是最后浮现在脑海中。
  • 我认为软件视图截锥剔除教程的链接有点误导,因为需要做的就是简单地调整他的投影矩阵,让 OpenGL 的视图体积裁剪为他做剔除在顶点着色器阶段之后。如果你确实提到了软件截锥体剔除,那么这在他的情况下是行不通的,因为测试每个点肯定效率太低,更不用说对批处理的影响了。
  • 你是对的,克里斯蒂安。我认为我没有仔细检查过本教程——我只是在开头看到了平截头体的解释。我只是说我在第一句话中所说的,以及你在这里建议的:调整投影矩阵。我会编辑答案。
  • 我调整了投影矩阵,现在我的 OpenGL 的“自动”裁剪可以像宣传的那样工作。谢谢大家的帮助。
【解决方案2】:

首先,没有。您不能完全丢弃顶点。两个顶点的三角形是什么(当你丢弃第三个时)?您可以使用几何着色器在每个基元的基础上执行此操作,但恕我直言,WebGL 不支持。即使你只绘制点图元,顶点着色器仍然没有任何图元的概念,不能仅仅丢弃顶点。

您可以做的是将顶点移到查看体积之外。这样它就被剪掉了,你只需要为顶点着色器付费,既不需要光栅化(在使用大小为 1 的点时也不会花费太多),也不需要片段着色器。

这似乎是您目前想要做的,但实际上将顶点的 w 坐标设置为 0 并不是一个好主意,这会导致在透视分割期间出现未定义的行为。只需将其设置在规范视图体积之外([-1,1] 立方体):

if( s < 0.0 )
    gl_Position = vec4(2.0, 0.0, 0.0, 1.0);
else
    gl_Position = ps_ProjectionMatrix * ecPos4;

你也不需要惹gl_PointSize。将它的位置设置在观看范围之外就足够了。

编辑:但在你的情况下,詹姆斯回答的解决方案要容易得多。只需更改投影矩阵的远平面,其任务就是剪掉太远的对象。

【讨论】:

  • @Tom 没有人谈到软件截锥剔除。如您所知,OpenGL 在顶点着色器阶段之后和光栅化和片段着色器之前执行视锥体裁剪。因此,要自动剪掉太远的点,只需将顶点位置设置在着色器中的视图体积之外([-1,1] 立方体),如上所示。或者更简单,无需任何努力,只需通过适当调整投影矩阵来调整视图体积的远裁剪平面,就像 James 建议的那样。也许他指向软件截锥剔除教程的链接具有误导性。
  • 感谢您的重新解释。还有一件事我还不太明白。 “[-1,1] 立方体”是什么意思。 gl_Position 不应该是 vec4 吗?
  • 对于 [-1,1] 立方体,我的意思是一个在 x、y 和 z 中从 -1 到 1 的框。您的查看体积(可见场景)在顶点着色器阶段(以及随后的透视划分)中(或应该)被转换为这个。此卷之外的所有内容都被剪掉了。为了更深入地了解 OpenGL 的转换管道,this question 的答案可能会有所帮助。
  • 谢谢!该链接非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 2016-03-28
  • 2019-01-24
相关资源
最近更新 更多