Creating a particle system using transform feedback

Transform feedback provides a way to capture the output of the vertex (or geometry) shader to a buffer for use in subsequent passes. Originally introduced into OpenGL with version 3.0, this feature is particularly well-suited for particle systems, because among other things, it enables us to do discrete simulations. We can update a particle's position within the vertex shader and render that updated position in a subsequent pass (or the same pass). Then the updated positions can be used in the same way as input to the next frame of animation.

In this example, we'll implement the same particle system from the previous recipe (Creating a particle fountain), this time making use of transform feedback. Instead of using an equation that describes the particle's motion for all time, we'll update the particle positions incrementally, solving the equations of motion based on the forces involved at the time each frame is rendered.

A common technique is to make use of the Euler method, which approximates the position and velocity at time t based on the position, velocity, and acceleration at an earlier time:

In the previous equation, the subscripts represent the time step (or animation frame), P is the particle position, and v is the particle velocity. The equations describe the position and velocity at frame n + 1 as a function of the position and velocity during the previous frame (n). The variable h represents the time step size, or the amount of time that has elapsed between frames. The term an represents the instantaneous acceleration. For our simulation, this will be a constant value, but in general it might be a value that changes depending on the environment (wind, collisions, inter-particle interactions, and so on).

The Euler method is actually numerically integrating the Newtonian equation of motion. It is one of the simplest techniques for doing so. However, it is a first-order technique, which means that it can introduce a significant amount of error. More accurate techniques include Verlet integration and Runge-Kutta integration. Since our particle simulation is designed to look good and physical accuracy is not of high importance, the Euler method should suffice.

To make our simulation work, we'll use a technique sometimes called buffer ping-ponging. We maintain two sets of vertex buffers and swap their uses each frame. For example, we use buffer A to provide the positions and velocities as input to the vertex shader. The vertex shader updates the positions and velocities using the Euler method and sends the results to buffer B using transform feedback. Then, in a second pass, we render the particles using buffer B:

In the next frame of animation, we repeat the same process, swapping the two buffers.

In general, transform feedback allows us to define a set of shader output variables that are to be written to a designated buffer (or set of buffers). There are several steps involved that will be demonstrated, but the basic idea is as follows. Just before the shader program is linked, we define the relationship between buffers and shader output variables using the glTransformFeedbackVaryings function. During rendering, we initiate a transform feedback pass. We bind the appropriate buffers to the transform feedback binding points. (If desired, we can disable rasterization so that the particles are not rendered.) We enable transform feedback using the glBeginTransformFeedback function and then draw the point primitives. The output from the vertex shader will be stored in the appropriate buffers. Then we disable transform feedback by calling glEndTransformFeedback.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.196.59