2

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

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

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

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

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

4

2 回答 2

3

您可以传递带有每个点的值的纹理 1D。然后使用texelFetch ()检索值。您可以使用原子计数器(如果使用 OpenGL 4.2)或gl_vertexID来执行此操作。也看看这个问题和这个第一,接受的答案还建议了其他解决方案,例如 UBO。虽然如果您的点云很大,那么Buffer Textures就是您所需要的。

让我们采用缓冲区纹理方法:

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

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

    void main() { float destSize = texelFetch(pointsBuffer, gl_VertexID).x; ... }

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

  • 正如您提到的 OpenGL 超级棒,它有一章解释了纹理缓冲区的工作原理。再读一遍。您要做的不是火箭科学,也不是初学者水平。所以请耐心等待 - 这总是很好的提示使用 OpenGL。

于 2013-01-07T08:23:20.690 回答
1

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

我的顶点着色器的一部分看起来像这样:

 ... 
 "  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) 设置,第二个是任意数字。

于 2013-01-26T18:47:33.703 回答