This is a description of my mid-semester project for CMPS 290b / Scientific Visualization Seminar
The assignment in this case was to download a set of data files from a simulation of Hurricane Isabel (courtesy the Visualization and Graphics Group at NCAR) and to develop a meaningful visualization of the data. I chose to visualize cloud water density, precipitation, pressure and wind flow. Cloud density, precipitation and pressure were displayed via volume rendering, while the wind data was displayed via editable interactive streamlines.
Volume rendering is a natural way of displaying cloud and precipitation data, as the very model of volume rendering itself is one of light interacting with a diffuse translucent "cloud". In this case the data we are representing as a cloud actually is a cloud, and the transformation is far too natural to pass up.
I used splatting (an image-based approach to volume rendering, in which screen-aligned sprites are drawn in back-to-front order with an alpha component), with hexagonal sprites, roughly corresponding to the projected shape of the datagrid. I ran into the obvious problem of the shape of the projection of "a cube" being different in different parts of the image. Rather then robustly solving the problem of how to rewarp the splats, I simply set the alpha at the edges to be lower then at the center, thus preventing the artifacts from creating unwanted occlusions (in exchange for accepting the occassional unwanted transparent lines) and roughly approximating the gaussian textures traditionally used by the splatting algorithm. The splats were essentially polygonal sprites pumped through the graphics card's 3d accelerator using OpenGL(tm). Artifacts of this method can be clearly seen in the image below.
For each splat, the shading normals were set to the gradient of the volume field at that point. The shading results from this help to clearly see relative depth, and can be seen in either the image below this section, or the one above it. For added shading relief, the specular highlight color was chosen to be pure white, regardless of the diffuse color picked from the volume transfer functions.
The advantage to using the graphics card's hardware to accelereate the spatting algorithm was that of interactivity of visualization. One of these screenshots was taken at a resolution that exceeded the plausible realtime capability of an nVidia GeForce card, but the bulk of them were interactively viewable.
Rather then using a complicated transfer function, I used two distinct simple ones, one for opacity, and the other for color. Both were based on the mean and standard deviation of the volume data. The color was represented by a function which was blue at one standard deviation or more below the mean data value, yellow at one standard deviation or more above the mean data value, or a simple linear ramp between yellow and blue from -1 to 1 standard deviations from the mean.
The opacity field was slightly more complicated. Initially represented by a function which remapped the spline function "x*x*(3-2*x)" to the domain of mean-1*std_dev to mean+1*std_dev, the opacity trasnfer function could be edited interactively by shifting the domain up and down by one tenth of a standard deviation, or by scaling the input values about the current center (initially the mean).
The picture below demonstrates changes in the input scaling of the opacity transfer function.
Streamlines were created through Euler integration of the wind UVW vector field. Some difficulty was present in the transformation between the curvilinear lattitude-longitude grid of the data array, and the orthogonal grid of the display. The technique I used to solve this was to transform each local segment of the curvilinear grid onto the orthogonal display space, assuming local linearity as a decent approximation before each integration step. Naturally integration errors occur due to this, but I felt the integration step could be set to a sufficiently small quantity where this wasn't noticable and the time to compute each streamline would still be masked by the time to volume render the data.
In order to allow clarity of visualization of the streamlines, while simultaneously allowing some degree of resolution in flow visualization, I adopted the following algorithm. Rather then displaying a dense field of streamlines, I displayed a few (32) sparse streamlines with clearly visible objects at their origins. Clicking on these objects allows the user to move the origin of the streamline, which turns green while being edited, as seen in the figure below. Wind speed is indicated by the size of bumps displayed at every n integration steps along the streamline, and also implicitly by the distance between these bumps. The bumps along the streamlines are shaded to give a sense of depth.
Editing is allowed in two modes. When holding down the left mouse button and clicking on the streamline, its origin is constrained to follow the projection of the mouse pointer onto the x-y plane on which the streamline currently resides. When holding down the right mouse button, the origin is constrained to move in the a-z plane, where "a" is the axis among {x,y} that is most closely aligned to the screen.
The volume field displayed in the screenshot below is one of precipitation.
In addition to interactivity in the transfer function and streamline origin, I also implemented interactivity in the view position, the data field, and the animation step. The sequence of images at the very top of this document is a series of images of cloud density at various animation steps.
The camera is constrained to rotate about a center anchor point. Left mouse button rotates the view in yaw-pitch space, right mouse button zooms towards and away from the anchor pont, and middle mouse button translates the anchor point in a plane parrallel to the screen.
Interactive display of pressure, precipitation and cloud density volume fields was facilitated via the simple trick of allowing the user to switch volume fields at the click of a keyboard button. Each volume field remembered its particular transfer function, so a carefully crafted transfer function for cloud data wouldn't have to be recreated after snapping to view pressure or precipitation data.
While cloud and precipitation density are both important to the physical mechanism of the hurricane, and help give a sense of what the phenomenon actually look like, no study of a hurricane would be complete without display of the raw fluid dynamics concepts of pressure and wind flow. Below is a volume rendering of the pressure field with stream tracers in the wind field. The ability to snap between this visualization, and one of cloud or precipitation density from the same viewpoint, not only allows the user to compare water and pressure in the same region, but also helps gives a context for pressure data by allowing comparisons to the more physically visible water and precipitation data. Below is a visualization of the pressure field.
Turning the streamlines on/off was also enabled, as seen in the pictures below.
Display of the North American coastline near the hurricane was enabled using a very simple hack. In each volume field, certain voxels were marked as having invalid data (pressure and wind speed make no sense within the landmass of the earth). Displaying these as white, rather then failing to draw a voxel at these spots altogether, gave a view of the coastline in the context of the hurricane, as seen below