Monday, February 21, 2011

Project Final Report–3D Fluid Simulation

Introduction and Problem/Project Description

The goal of this project was to simulate fluids in 3D, in real-time using a simple particle system to represent the fluid behavior. The particle system would be robust enough to handle a lot of particles at once on the screen and not affect the performance of the fluid simulation. The secondary goal was also to achieve additional performance by simulating the fluids on the GPU through the use of GPU hardware acceleration via compute shaders in Microsoft’s DirectX 11 API.

Approach

The approach to the project was simple. First figure out how fluids are typically modeled in computer graphics, and then to apply the same algorithm used in my project. I searched through many existing research papers and books and eventually found an implementation based on a particle approach that satisfied what I had in mind for the results.

Technical Details

The method used to model fluids in my demo is called Smoothed Particle Hydrodynamics. SPH is a technique developed a few years ago to model the consistency and behavior of fluids by applying the typical Navier-Stokes equation to a particle system. The basic concept involves a few steps.

The first step is to obtain a density for each particle based on surrounding particles. By using a special statistical technique called a smoothing kernel, we can obtain an average density around that particle based on the surrounding particles. Without the use of a grid, we must check against all other particles in the scene, making it an n^2 algorithm, but it can be cut down considerably by using sorting and grid techniques to reduce the number of particles to check against to the ones around it.

Then, once we have density, we can apply this density to calculate a force based on the densities of the surrounding particles. This is also where we calculate the viscosity component of the Navier-Stokes equation and output a final overall force for the particle.

Finally, we must integrate the position of the particle based on this calculated force (in addition to any added in external forces). To do this, I used a numerical integration technique called Verlet integration which was able to handle the fluid time-steps relatively well without making the fluids behave strangely on large time-steps.

The resulting calculations were then rendered to screen using an efficient sprite batching technique to watch the flow of the fluids.

Here is a link to the technical paper used for creating the fluid simulation.

Results

fluids3d_screenshotfluids3d_screenshot2

A screenshot of the fluids filling a small glass box (left) and spilling over the sides (right)

Future Enhancements

Given additional time, the first thing I would like to improve is the efficiency of the algorithm. I have taken a lot of time to make the current algorithm as efficient as I could, however a grid+sort algorithm would considerably reduce the complex from the current n^2 algorithm I’m using now. Doing this could increase the efficiency enough to increase the particle count ten fold without impacting performance from how it is now.

The next step would be a nicer rendering method. The current particle system does a great job showing the flow of the particles and fluid, but lacks in visual stimulation. Improving the technique to provide a 3D isosurface extraction method (marching cubes to create metaball rendering) could provide a much nicer looking fluid, though potentially at the cost of visualizing flow).

Project

Upon request, I can ship the source code and project files for the demo. The requirements are a DirectX10 or higher video card which support compute shader 4.0, 4.1, or 5.0, and Windows Vista or 7. The project is built in Visual Studio 2010, and there are no special requirements for compilation.

Monday, February 14, 2011

Renderman

Here are some images created in renderman. The first is a renderman scene that simply has some changes from the original scene provided by the professor. The second image shows the same scene with some new shaders. The third image is an image created from a new scene using unique shaders and values.

mod shadersnew shaderseyes

All shaders were found at http://www.renderman.org/RMR/Shaders/surface.html

Follow the link to find shaders to use yourself. Credit for these shaders go to their respective authors. I did not make any of the shaders used in the above images.

Wednesday, February 9, 2011

Ray Tracer Part Seven: Tone-Mapping

Here are some screenshots from the results of applying Ward and Reinhard tone mapping as a postprocess.

ward_1ward_1000ward_10000

The above three images are Ward tone-mapping. From left to right, LMAX values of 1, 1000, and 10000

reinhard_1reinhard_1000reinhard_10000

These are from the Reinhard model. Again, from left to right are LMAX values 1, 1000, and 10000. These three are very similar due to the nature of how the Reinhard model works.

Thursday, January 27, 2011

Ray Tracer Part Six: Transmission (refraction)

Now that we have reflection in our scene, we can go ahead and add refraction. The computation for refractions is based on snell’s law and is a bit more complex than reflections, but nonetheless, since we already have our raytracer setup to spawn additional rays, it’s not too difficult to add support. Below is our scene with transmission enabled to make a glass-like sphere:

Refractive

Ray Tracer Part Five: Reflectivity (and recursive tracing)

The next part of our raytracer involves adding in reflectivity to objects, which extends our raytracer to a recursive raytracer. This means that for each ray shot into our scene, we may end up tracing more to resolve reflections or (soon to be) transmissions (refractions) in our scene. Below shows the result of adding a reflective surface to our scene:

Reflective

Tuesday, January 18, 2011

Mid-Quarter Update

Project Title: Using particles to model fluid simulation
Name: Michael Culek
Course: Computer Graphics II (4003-571)
Professor: Reynold Bailey
Blog: http://mxc4873.blogspot.com/

Revised proposal Information:

Project Objectives
Model 3D fluid simulation using particle simulation.
Enhance performance by enabling the use of compute shaders.
Be able to apply outside forces and pressure to a system at any point in space.

 My goal is to implement the above tasks on my own by the end of the quarter.

 Revised Project Timeline
                Pre-week 6
                        Implemented basic fluid behavior.

                Week 6-7
                        Begin work on adding forces back into the system.
Implement a GUI model system for monitoring information and adding information to the world.

                            Week 8-9
                                    Optimize existing code to run better of lower end systems
Begin implementing other potential rendering methods (metaballs, marching cubes, etc)

                            Week 10
                                    Polish

Done so far
Thus far, I have managed to get fluids working with somewhat little success. The fluid simulator does obey basic incompressibility rules; however the variables and constants are far from perfect. A basic compute shader (though highly unoptimized) has been implemented.

Assessment
Thus far I have managed to come a long way. With basic fluid simulation already working, quite a bit has managed to get accomplished. Part of the reason for this rapid succession is due to the effort being put into my 2D class project which also involved fluids. My 2D projects, however, have not been modified to work in full 3D, which this project is capable of.

Wednesday, January 12, 2011

Ray Tracer Part Four: Procedural Shading

Since we have completed the basic shading stage of our raytracer, we are able to move on to more advanced concepts such as texture mapping. In this case, we are not using textures from files, but rather, procedurally generated textures, which we will map to our surface using calculated u,v coordinates.

imageimage

On the left, you can see the procedurally shaded floor using a procedural shader which generates a color in a tile-pattern. The calculation simply detects if the position is an even or odd row/column and returns the correct color. On the right, you can see a slightly more interesting shader which simply calculates the difference between the center point of a square area and returns a color based on the distance from it. If the point is outside of the circles radius, we color it yellow, otherwise, black.