【问题标题】:How to use a timer inside a vertex shader to animate point sizes in OpenGL如何在顶点着色器中使用计时器来为 OpenGL 中的点大小设置动画
【发布时间】:2013-01-06 22:11:51
【问题描述】:

我正在尝试实现一个点云,其中不同点的大小应根据与它们相关的不确定值而变化。比方说,如果这个值为零,则大小应该是恒定的,如果它接近 1,那么这些点的半径应该越来越多。首先,点的大小应该增加,达到最大值后,它们应该减小到最小值,依此类推。 描述这种现象的函数可能是:

pointSize = x +/- c * pointUncertainty, where x = standard point size 
                                              c = scaling constant

根据我的阅读,这可以通过将一个统一的计时器变量传递给我的顶点着色器并计算其中的点大小来实现。但是,所有点应该同时变化,这意味着不确定性为 1 的点和不确定性为 0.5 的点应该同时达到它们的最小和最大值 pointSize。此外,整个过程不应依赖于帧速率。

我不确定完成这项工作的最佳方法是什么,如何最好地实现增加-减少-增加-模式以及在哪里放置必要的 OpenGL (4.2) 命令。

编辑:我仍然希望得到这个问题的答案,因为我不清楚如何实现这种动画效果的整个过程。

【问题讨论】:

    标签: opengl timer shader point


    【解决方案1】:

    您可以传递带有每个点的值的texture1D。然后使用texelFetch() 检索值。您可以使用atomic counter(如果使用OpenGL 4.2)或gl_vertexID 来执行此操作。也看看this 问题和this 一个,接受的答案还建议其他解决方案,如UBO。 虽然如果您的点云很大,那么 Buffer Textures 就是您所需要的。

    让我们采用Buffer textures 方法:

    • 您创建了一个纹理缓冲区并用将要达到的值填充它 定义您的点目标大小。(阅读我在上面放置的链接如何 设置它。
    • 在顶点着色器中,您可以通过 texelFetch 采样访问这些值。正如我所说,您可以使用 gl_VertexID 按当前顶点进行采样,(类似这样):

      统一采样器缓冲点缓冲区;

      空主() { 浮动 destSize = texelFetch(pointsBuffer, gl_VertexID).x; ... }

    • 现在,您可能希望根据某个数量将点大小从默认值插入到目标大小。是的,范围在 0 和 1 之间的计时器输入可以完成这项工作。使用 mix() 内置方法从默认目的地插入point size。为了更有趣,可以通过基于时间的 sin() 或 cos() :)

    • 正如你提到的 OpenGL 超级棒,它有一章解释纹理缓冲区是如何工作的。阅读它again。你想做的不是火箭科学,也不是初学者。所以要耐心——这在使用 OpenGL 时总是很好的提示。

    【讨论】:

    • 好的,这说明了我如何将 pointSize 数据放入我的着色器,但不说明如何实现动画效果。是否也可以仅将 VBO 用于不确定性数据并将其作为制服传递给着色器?我猜这个 VBO 中的值不必每帧都更改或计算新的。
    • 您是否阅读了我放在这里的链接中的答案? @Nicol Bolas 在那里展开了所有可能的选项。
    • 我确实阅读了您在答案中提供的所有链接,但对我来说仍然不是很清楚。也许是因为我几周前才开始学习opengl,或者我太傻了,看不到这个比喻。在这两个链接中,问题是如何将数据传递到顶点着色器。我可能会使用您建议的上述缓冲区纹理。现在的问题是我如何使用这些数据来动画我的观点。我不需要某种计时器变量来计算何时达到最大不确定性值以及何时再次缩小 pointSize?
    • 可能缺乏 OpenGL 经验是你在这方面遇到困难的真正原因......我不能在这里给你完整的解决方案,因为 StackOverflow 的想法是帮助人们而不是做他们的为他们准备的东西。我建议的可能解决方案就是您所需要的。现在尝试实施它们。
    • 我不想让任何人做我的事,但正如我所说,这种动画的整个过程对我来说是不清楚的......我花了几个小时在网上搜索任何不错的教程,但没有成功。我了解您建议的所有内容,但我看不到如何使用它们来实现我的点动画。如果您能尝试多解释一下该过程,我将不胜感激。目前,所有这些方法在我看来都是将数据传递给着色器的不同解决方案,但不确定性数据已经存在于 VBO 中。
    【解决方案2】:

    首先...感谢您的回答。我只使用顶点着色器就可以解决问题。我想这是我希望得到的解决方案。也许有同样问题的人可以从中受益:

    我的部分顶点着色器如下所示:

     ... 
     "  float standardPointSize = 100.0;"
     "  float timeScale = standardPointSize / my_loopDuration;"
     "  float currentTime = mod(my_time, my_loopDuration);"
     "  float offset = currentTime * timeScale * in_uncertainty;"
     "  if(currentTime < my_loopDuration / 4)"
     "  {"
     "      gl_PointSize = standardPointSize - 4 * offset;"
     "  }"
     "  else if(currentTime >= my_loopDuration / 4 && currentTime < my_loopDuration / 2)"
     "  {"
     "      gl_PointSize = standardPointSize - standardPointSize * in_uncertainty + 4 * offset - 1 * in_uncertainty * standardPointSize;"
     "  }"
     "  else if(currentTime >= my_loopDuration / 2 && currentTime < 3 * my_loopDuration / 4)"
     "  {"
     "      gl_PointSize = standardPointSize + 4 * offset - 2 * in_uncertainty * standardPointSize;"
     "  }"
     "  else if(currentTime >= 3 * my_loopDuration / 4 && currentTime <= my_loopDuration)"
     "  {"
     "      gl_PointSize = standardPointSize + standardPointSize * in_uncertainty - 4 * offset + 3 * in_uncertainty * standardPointSize;"
     "  }"
     ...
    

    my_time 和 my_loopDuration 是统一变量。第一个用 glutGet(GLUT_ELASED_TIME) 设置,第二个是任意数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多