Trajectory rendering
Trajectories are rendered as 3-D tubes, with the tube geometry generated on the GPU. This page covers the rendering side; how trajectories are computed and filtered is described in Trajectory Pipeline.
Source code: src/actors/trajectoryactor.cpp,
src/glsl/trajectory_tubes.fx.glsl, src/glsl/trajectory_positions.fx.glsl.
Tubes from line segments
Only the trajectory vertices live in GPU memory, in a vertex buffer. A geometry
shader turns each line segment into a triangle mesh approximating a tube
(trajectory_tubes.fx.glsl): for every vertex a normal is rotated around the
segment to produce the ring of tube vertices, and consecutive rings are connected.
At the joint between two segments, the normal must be perpendicular to the tangent at the joint, not to either of the two segments. Otherwise gaps appear at kinks. Consecutive normals must also be consistent with each other; if they are not, the tube twists along its length.
Both conditions require the normals to be computed iteratively along the
trajectory. A geometry shader sees at most a few adjacent vertices and cannot do
this. This is why normals are not computed in the shader but delivered as a
separate data item by MTrajectoryNormalsSource and bound as a vertex attribute.
Selection through the index buffer
Filtering trajectories — by ascent, by region, by any other criterion — does not touch the geometry. The full set of trajectories stays in the vertex buffer, and the selection is expressed as a set of indices in an index buffer. Changing a filter criterion therefore only means uploading a new index buffer, which is why dragging a filter threshold stays interactive even for large trajectory sets.
Particle positions
The position of each air parcel at a given time step is drawn as a sphere. These
are not real spheres but billboards: a geometry shader
(trajectory_positions.fx.glsl) expands each position into a screen-aligned
quad, which the fragment shader shades to look like a sphere. Animating the time
step then shows the parcels travelling along their trajectories.
Colouring and shadows
Tubes and particles can be coloured by pressure elevation, by an auxiliary variable carried along the trajectory, or by a constant colour, using a transfer function as a lookup table. Shadows are handled by the scene-wide shadow mapping described in Shadow mapping, rather than by projecting the geometry onto the ground as in the original implementation.