Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

particle vector fields #37

Closed
Usnul opened this issue Feb 13, 2014 · 14 comments
Closed

particle vector fields #37

Usnul opened this issue Feb 13, 2014 · 14 comments

Comments

@Usnul
Copy link

Usnul commented Feb 13, 2014

http://www.unrealengine.com/files/misc/The_Technology_Behind_the_Elemental_Demo_16x9_(2).pdf
In general, this is a more flexible model, and one which has a good mapping to GLSL (approach is described in the slides on abstract level).

@Usnul
Copy link
Author

Usnul commented Feb 13, 2014

In a nutshell, imagine populating your scene with cubes each defining a velocity/acceleration vector inside. When a particle enters said cube - it is being affected by the velocity/acceleration vector altering its trajectory. You can create a set of cubes in a circle and make them point at a tangent, slightly pointed towards center of the circle - all particles entering this space will swirl in circles creating visual effect of a tornado.
Imagine a snowy landscape, with a blizzard, or a desert during a sandstorm. Vector fields would allow you to define "wind currents", after which you just unleash the particles into the scene and watch them get carried by the "wind" visually simulating that said storm effect. Vector fields can help simulate currents within various kinds of fluid substance, air being one of the examples. You could simulate schools of fish in the water, bubbles of air. You can also simulate magnetic and gravitation forces to some degree, for space environments for example.

@squarefeet
Copy link
Owner

That's a fascinating idea, though I daresay implementing it (into this project at least) would be too much of a sea-change. It's something I'll definitely look into and try experiment with, though. If I make any headway, I'll be sure to let you know.

Thanks for the idea!

@squarefeet
Copy link
Owner

PS. Likewise, if you experiment with it, do let me know as well :)

@cihadturhan
Copy link

Hi, I've been busy for a couple of weeks. Finally, I got some time to examine library. I found it easy to understand and examples helped me a lot on this.

Vector fields is a wonderful idea, we definitely need this. @Usnul have you started this? Vector fields are very useful, take a look this example

A couple months ago, I made a amateur force vector field so that I could implement gravitational and electric fields easily. Here is a snippet from there

[
    {
        a: 10000, //magnitude
        f: function(pos) {
            var p = $V([216, 216, 0]); //position of the source
            var r = p.subtract(pos);
            var dst = r.dot(r);
            dst = dst == 0 ? 1e10 : dst; //avoid division by 0
            var fGra = r.x(this.a / dst);

            return fGra;
        }
    }
]

This represents a simple gravitational field. I defined force fields as an array therefore one can define more than one force fields (gravity, magnetic, electric etc).

This is easily done in javascript but how can we pass it to the shader? As we define force field as a javascript function, we need to pass it to shader as a function pointer or else?

@squarefeet
Copy link
Owner

Hey @cihadturhan, thanks for checking out the library - I'm glad it wasn't difficult to get to grips with. I do feel the need for more examples, though; it's been on my todo list for a while now. That said, I'm glad the current ones helped.

So... vector fields, shaders, passing values, etc:

What I had thought of was to define a vector field using the following properties (all vec3s):

  • position, acceleration, velocity, size

The way to pass these properties to the shader is by using custom attributes in the material used by the particle system. See here for the current list of custom attributes, and here to see where they're added to the material.

I do see a bit of a problem, though... We can only really use up to 16 attributes, as that's the most common upper-limit of gl_max_vertex_attribs. I'm currently using 10 of the 16 available, leaving only 6 attributes to play with. I would prefer to use attributes since we can change these values on the fly. Uniforms are an option, but may well be fixed values (I need to double-check this - I have a feeling I'm wrong). Assuming they're not fixed, or we don't want to be able to change the vector field properties once a particle group has been created, then uniforms are a-okay.

Anyway, back to attributes: since each vector field would need 4 attributes in an ideal situation (we might be able to squash these into a mat4 (a 4x4 matrix) depending on whether mat4s are supported as attributes), having only 6 attributes left would mean that we couldn't really have that many vector fields at all... IMO the point of vector fields would be to have many of them...

Something to think about over a cup of tea...

@squarefeet
Copy link
Owner

Looks like I was wrong about uniforms:

The difference between attribute and uniform variable is that attribute variables contain data which is vertex specific so they are reloaded with a new value from the vertex buffer for each shader invocation while the value of uniform variables remains constant across the entire draw call.

From here.

It looks like since these vector fields would not (I assume) be vertex (read: particle) specific, uniforms would be okay to use.

That means we have a total of 256 uniforms to play with, excluding the 4 already in use.

It's looking more promising!

@cihadturhan
Copy link

256 uniforms? Seems much. I'll take a look to this. I'm on the phone now,will respond when I get back to home

@squarefeet
Copy link
Owner

Well, 256 is an average apparently, but just come across this site: http://webglstats.com/ (search for MAX_VERTEX_UNIFORM_VECTORS

It looks like 128 would be a safer upper limit to adhere to, since 100% of users have support for at least 128 uniforms.

Apparently my current desktop has support for 1024 uniforms, though. It looks like I'm in the minority!

@squarefeet
Copy link
Owner

I've just made a quick experiment and I've hit a problem...

I've added a vector field to the shader. I've got it detecting (albeit poorly at the moment) whether a given vertex is within the field. The problem is that when the vertex enters or leaves the field's influence it jumps position, rather than slowly integrating the new velocity values. I can't see a way around this using pure GLSL, since I'd need to track the amount of time the vertex sat within the field's influence (a cube, at the moment) and apply the field's as vertexPosition += (velocity * timeInField).

Wait... Maybe i could use distance from the field's edges as a time value..? Urgh.

PS. The experiment is sitting in SPE.Group on the VectorFields branch.

@cihadturhan
Copy link

It has been around two years since I did shader programming, so I refreshed my knowledge by some research. Now, I see your point. As you already said, yes we can use uniform variables because we don't need vector fields to be specific for each vertex. In addition, if we use it as vertex attribute, it will push redundant bytes to gpu memory.

Now, I'll take a look your code and review it.

PS. Ok, we can change the color if it's in the field. I think this might help us to debug.

@cihadturhan
Copy link

@squarefeet I've misunderstood your problem. I think it's possible to implement that using GLSL. I'll fiddle a bit and see what happens.

After some digging, I found out there is a variable built-in gl_Vertex which stores the current position of the vertex coordinates. However, the problem is there is no equivalent to gl_Vertex in WebGL GLSL so we need to assign it manually :( Here you can find some explanation

PS: Looks like these guys implemented gl_Vertex (and other predefined variables) so they use freely. Maybe we can borrow from them :)

@Usnul
Copy link
Author

Usnul commented Mar 5, 2014

a little note on space: since number of registers (variables) is limited - it may be valid to segment those variables. Say if you have 64bit register you can use 20 for each coordinate and 4 for flags

int20 x = r<<44;
int20 y = r<<24;
int20 z = r<<4;
char flags = r & 0x0f;

something along those lines, would be cool if int20 existed in GLSL :)
The way Epic guys stored their vector fields was using textures, so each pixel would be a collection of attributes describing a field.

@squarefeet
Copy link
Owner

@Usnul Hell of a good idea - I'd not thought of packing attributes in that way. I've played with bitmasks before, so it shouldn't take too long to implement a test of this. It would help on memory use as well, I would've thought :) Nice one!

@squarefeet
Copy link
Owner

@Usnul The packing of attributes into textures is also a pretty interesting idea. I wonder if I could do something similar using canvas... Ideas abound..!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants