Jump to content

  • Log In with Google      Sign In   
  • Create Account

noodleBowl

Member Since 08 Sep 2013
Offline Last Active Dec 17 2014 04:31 PM

Posts I've Made

In Topic: Hitting a milli

16 December 2014 - 01:21 PM

This can be quite easily done without needing any dynamic data, but it does depend on what kind of particle behaviour you want.
 
In the simplest case you can do a one-time-only initialization of your 1 million particles to a buffer object.  Give them an initial position, velocity and acceleration, then the new position at any given point in time is just a simple calculation (e.g see http://www.ugrad.math.ubc.ca/coursedoc/math101/notes/applications/velocity.html).


I have been playing around with the above concept. Just having initial static values for velocity and acceleration, then determining the positions of my particles using elapsed time. But I can't help feel like I am limited to only making simple explosions or stream fountains. I was thinking the limitation of this just extended to particles effecting world objects or each other.

For example, I attempted to make some particles orbit around a point
//In my vertex shader
//deltaTime is elapsed time
//accleration is a random static float value; Generated at init time
//initVelocity is a random static float value; Generated at init time
//orbitRadius is the size of the particles orbit around the point
//orbitPoint the point to orbit
//PI the value of pi

//Calc the orbit speed over time
vec2 orbitSpeed;
orbitSpeed.x = initVelocity.x + (accleration.x * deltaTime);
orbitSpeed.y = initVelocity.y + (accleration.y * deltaTime);

//Calculate the position of the particle over time
position.x = orbitPoint.x + cos(orbitSpeed.x * PI) * orbitRadius.x;
position.y = orbitPoint.y + sin(orbitSpeed.y * PI) * orbitRadius.y;

But all the particles "jam up" making the effect look much like the hands of an analog clock.
Also particles move much faster when using the same acceleration values, opposed to the way of stimulating the effect below and changing
the initVelocity value seems to have no effect either sad.png

If I use my sprite batcher to simulate particles and update on the CPU side, everything seems to be fine
//the delta value is not elapsed time, but time per frame. "Normal" delta time

accelerationX = 20.0f;
accelerationY = 20.0f;
orbitSpeedX += accelerationX * delta;
orbitSpeedY += accelerationY * delta;
positionX = orbitPointX + cos(orbitSpeedX * PI) * orbitRadiusX;
positionY = orbitPointY + sin(orbitSpeedY * PI) * orbitRadiusY;

So I'm not sure if it chalks up to horrible math or the limitation of only having static values. I mean I should be able to do this and have it look right when basing things on time in my vertex shader right?

In Topic: Hitting a milli

12 December 2014 - 09:46 PM

This can be quite easily done without needing any dynamic data, but it does depend on what kind of particle behaviour you want.

 

In the simplest case you can do a one-time-only initialization of your 1 million particles to a buffer object.  Give them an initial position, velocity and acceleration, then the new position at any given point in time is just a simple calculation (e.g see http://www.ugrad.math.ubc.ca/coursedoc/math101/notes/applications/velocity.html).

 

With this kind of setup you're going to bottleneck on fillrate far more so than on vertices or shader calculations, but fillrate will be a problem for any particle system anyway.

 

With this kind of setup are we strictly talking about a CPU based system? Or is this still all being done on the GPU?

Also one thing I'm not sure about is what would this buffer's setup look like look? Here I'm also assuming the particles are quads being generated through a shader

 

I don't think we would want to double up on data in a VBO and in prior testing using a UBO to hold the particle x and y positions, I was unable to handle a uniform block containing a vec2 array set to 10K on the vertex shader side of things (Nothing ever showed on screen and I was only getting 1 FPS).

 

I kind of find it a little hard to believe, which makes me think I set it up wrong

 

My vertex shader's uniform block:

layout(std140) particleBlock
{
   uniform vec2 positions[10000];
};

In Topic: Hitting a milli

12 December 2014 - 08:32 PM

I have seen both of these approaches stated before

 

For curiosity sake, is there a reason to choose one over the other? E.G Better performance, easier to add in particles being able to effect the world, one is a more "modern way", or etc. I guess I'm looking for pros and cons of sorts

 

In the texture storage based proposal, are we talking about actual textures right?

GLuint texture = NULL;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

Or am I reading that wrong and we are talking about TBOs?


In Topic: Particles: Batching VS instancing

10 December 2014 - 12:46 PM

int particleID = vertex_id / 4;
Wow, how did I not think of this before!

So how is the UBO supposed to work? I understand the basics of setting them and etc. But say we have X many particles
I dont think a uniform block looking like this is going to work. This block would only be able to account for 1 particle right?

layout (std140) uniform positionBlock{  vec2 particlePositions;};
Should it look something more like:
layout (std140) uniform positionBlock{  vec2 particlePositions[NUMBER_OF_PARTICLES_TO_STIMULATE_THIS_FRAME];};
Edit:
So after some playing around, I'm a little stuck in byte offset hell.

After setting up a UBO and filling it with some test data:



GLfloat *particlePos = new GLfloat[4];//Particle 1 posparticlePos[0] = 50.0f;particlePos[1] = 50.0f;//particle 2 PosparticlePos[2] = 150.0f;particlePos[3] = 150.0f;
I'm able to pass the first particle position and get it to show biggrin.png
But the next particle wouldn't sad.png

I figured out its do to the std140 layout byte offset. If I pad with two 0s for each particle position and try to grab the next particle
everything works. But I really don't want to do that. Is there another layout I can use in my shader to stop this?

Just in case I'm filling my buffer like this [Padding with 0s sad.png ]:
int size = 8;GLfloat *pos = new GLfloat[size];//Particle 1 pospos[0] = 10.0f;pos[1] = 25.0f;pos[2] = 0.0f;pos[3] = 0.0f;//particle 2 Pospos[4] = 50.0f;pos[5] = 50.0f;pos[6] = 0.0f;pos[7] = 0.0f;GLint blockIndex = glGetUniformBlockIndex(shaderProgram.programID, "particleBlock");glUniformBlockBinding(shaderProgram.programID, blockIndex, 0);glBindBuffer(GL_UNIFORM_BUFFER, ubo);glBufferData(GL_UNIFORM_BUFFER, size * sizeof(GLfloat), pos, GL_DYNAMIC_DRAW);glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
One more question, I noticed that (assuming I doing it right) if I set the uniform block to have an 10K vec2 array it completely kills my application. Is this just some shader or UBO limit? I hope this isnt the case, cause how am I supposed to reach 100k or even 1 million particles if that is the case? Maybe I shouldn't be doing that (have a super large vec2 array) maybe its done some otherr way??

In Topic: Particles: Batching VS instancing

09 December 2014 - 12:25 PM

You don't have to increase your data; you only need one XY value per particle.

In the vertex shader you take the vertex ID as an input (can't recall GLSL for this) and then use that to figure out which particle you are (int id = vertex_ID % 4), and use that to index into the UBO to get the data.


That is the one thing I can't get my head around for some reason. How do I actually only grab one only set of XY positions per particle.
If particlePositions is an array of values, where it has 3 particles worth of data inside, looking like:
particlePositions = {0,0, 50,50, 150,30};

And assuming vertex_id auto increases with each vertex. Then lets say we are on the 3rd pass (vertex_id is 2; since the counter starts at 0)
Then we are going to pull back only value '50'. Even if particlePositions[vertex_id] were to somehow pull back both XY for the particle,
on a subsequent increase of vertex_id the values would be wrong for the quads construction or we would explode since we over ran the array

PARTNERS