3

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.

Schnigges
  • 1,284
  • 2
  • 24
  • 48

2 Answers2

3

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.

Community
  • 1
  • 1
Michael IV
  • 11,016
  • 12
  • 92
  • 223
  • Ok, this explains how I get the pointSize data into my shader, but not how the animation effect can be achieved. Isn't it also possible to just use a VBO for the uncertainty data and pass it to the shader as a uniform? I guess the values in this VBO dont have to be changed or calcuated new every frame. – Schnigges Jan 07 '13 at 10:12
  • Have you read the answer in the link I put here? @Nicol Bolas unwraps all the possible options there. – Michael IV Jan 07 '13 at 10:18
  • I did read all of the links you put in your answer, but it's still not really clear to me. Maybe its because I started learning opengl just a few weeks ago, or i'm just too silly to See The analogy. In both links, The question was how to pass data into The vertex shader. I'll Probably use The aforementioned Buffer textures you suggested. Now The question is how i can use that data to animate my points. Don't I need some kind of timer variable to calculate when The maximum uncertainty value is reached and when to shrink The pointSize again? – Schnigges Jan 07 '13 at 11:13
  • Probably the lack of OpenGL experience is the real reason you having the hard time on this...I can't give you out the whole solution here as StackOverflow idea is to help people and not doing their stuff for them.The possible solutions I suggested are what you need.Now just try to implement them. – Michael IV Jan 26 '13 at 11:08
  • I don't want anybody to do my stuff, but as I said, the whole process of this kind of animation is unclear to me...I've spend hours of searching the web for any decent tutorials on this, but didn't succeed. I understand all of the stuff you suggested, but I can't see the connection on how to use them in order to achieve my point animation. I would really appreciate it if you could try to explain the process a little bit more. At the moment, all of those methods seem to me as different solutions to pass data to a shader, but the uncertainty data already lives inside a VBO. – Schnigges Jan 26 '13 at 11:21
  • It's true that I don't have much experience with OpenGL. I bought the Super Bible and the Orange Book on GLSL to learn the basics, but I couldn't find anything regarding this kind of animation in either of those books. I hope that you understand that I really tried to do it on my own, but without a simple example or a tutorial, it's pretty hard to do. – Schnigges Jan 26 '13 at 11:29
  • Hang on , I will extend the answer – Michael IV Jan 26 '13 at 12:35
1

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.

Schnigges
  • 1,284
  • 2
  • 24
  • 48