How to use a timer inside a vertex shader to animate point sizes in OpenGL

随声附和 提交于 2019-12-19 04:22:25

问题


I'm trying to implement a point cloud where the different points shall vary in size based on an uncertainty value associated with them. Let's say, if this value is zero, the size should be constant, if it's approaching 1, the radius of those points should vary more and more. First, the points should gain in size and after reaching a maximum, they should decrease until a minimum, and so on. A function to describe this phenomenon could be:

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

From what I've read, this could potentially be achieved by passing a uniform timer variable to my vertex shader and compute the point size in there. However, all the points should vary in the same time, meaning that a point that has an uncertainty of 1 and a point that has an uncertainty of 0.5 should reach their minimum and maximum value of pointSize at the same time. Additionally, the whole process shouldn't be dependent on the frame rate.

I'm not sure what's the best way of getting this done, how the increase-decrease-increase-pattern could be implemented best and where to put the necessary OpenGL (4.2) commands.

EDIT: I still hope to get an answer to this question, since The whole process of how such an animation effect could be achieved is unclear to me.


回答1:


You can pass a texture1D with the values for each point.Then use texelFetch() to retrieve the values.You can use an atomic counter (if using OpenGL 4.2) , or gl_vertexID to do this.Also take a look at this question and this one, the accepted answer also suggest additional solutions like UBOs. Though if your point cloud is pretty big then Buffer Textures is what you need.

Let's take the Buffer textures approach:

  • You create a texture buffer and fill it with values that going to define your points target size.(Read in the links I put above how to set it up.
  • In the vertex shader you access those values via texelFetch sampling .As I said,you can use gl_VertexID to sample by current vertex,(something like this):

    uniform samplerBuffer pointsBuffer;

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

  • Now, you probably want to interpolate the point size from the default to the target size based on some amount.Yes timer input which ranges between 0 and 1 can do the job.Use mix() built-in method to interpolate the point size from the default the destination.For more fun pass sin() or cos() based time :)

  • As you have mentioned OpenGL superbible , it has a chapter that explains how texture buffers work.Read it again.What you are trying to do is not a rocket science but not a beginner level either.So be patient -which is always good tip when working with OpenGL.




回答2:


First of all...thanks for your answer. I've worked things out using just a vertex shader. I guess this was the solution I was hoping to get. Maybe folks with the same problem can benefit from this:

Part of my vertex shader looks like this:

 ... 
 "  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 and my_loopDuration are uniform variables. The first one is set with glutGet(GLUT_ELASED_TIME) and the second one is an arbitrary number.



来源:https://stackoverflow.com/questions/14187346/how-to-use-a-timer-inside-a-vertex-shader-to-animate-point-sizes-in-opengl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!