Wednesday, January 26, 2011

Rendering to a Texture

Maintaining the correct viewport and projection/model matrices proved to be the most difficult task in rendering particles to a texture.  The viewport must be set to the same size as the texture attached to the framebuffer when rendering to a texture and this causes variations in the perspective from the default window framebuffer.  The velocity grid must be aligned such that it intersects the (texture framebuffer's) viewing frustrum perfectly.  Unfortunately, an orthogonal projection will not work in this case since z values are needed for the depth render buffer attached to the texture framebuffer.

I managed to get the particles rendering to a texture (still animating in real-time) and apply them to a simple cube:

















Next I will focus on rendering and animating this texture in the terrain scene and continuing to modify colour values for the output textures.  Also, currently only one texture is rendered at the end of the velocity computation, but ideally multiple textures will be rendered and combined later on.

Tuesday, January 25, 2011

Framebuffer Objects

Rather than rendering individual points for each position within our velocity grid we can render this data into a texture using a Framebuffer Object.  Specifying an additional Framebuffer (other than the default OpenGL Framebuffer) can be set up as follows:



Once the FBO is set up and we bind it during rendering, all draw calls will be written to the off-screen buffer and copied to the specified texture.  If the particle grid is rendered at each stage of the velocity and pressure calculation the resulting textures can then be combined to form an animated texture at each time step.  Applying this texture to a surface will make it appear to be fluid-like even though it is only 2D.  With more ability for post processing, rendering to texture seems like a better approach than simply rendering particles as points.

Tuesday, January 18, 2011

Point Based Water Progress

I've managed to manipulate the perspective, size and viscosity of the NVidia Fluids CUDA sample code:
http://developer.download.nvidia.com/compute/cuda/sdk/website/Physically-Based_Simulation.html

It is now displayed in a 3D perspective and similar size to the terrain that is below it.  The colour has been changed and the viscosity has been reduced to feel more like water.

Next I will take a look at changing the individual point colour values in another CUDA kernel function to try to make the colour more realistic.  Also, work needs to be done to figure out how to properly display the terrain within the water (depth issues).

Introduction

This blog will serve as record keeping for work using NVidia's CUDA technology to simulate fluid effects including: water, smoke and fire.

Numerous resources have been helpful in grasping CUDA concepts located at:
[1]http://developer.nvidia.com/object/gpucomputing.html

Two chapters from GPU Gems 1 & 3 have been the most helpful for this application:
[2]http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html - this chapter deals with creating a grid based Navier-Stokes equation solver that writes data to textures for fluid simulation and extensions for cloud or smoke simulation
[3]http://http.developer.nvidia.com/GPUGems3/gpugems3_ch30.html - this chapter outlines a more dynamic and complex approach to render different types of 3D fluids

The classic method of solving fluids is by using either a 2D or 3D Navier-Stokes equation solver:



where p is the pressure, r is the mass density, f represents any external forces (such as gravity), and U2207.GIF is the gradient differential operator [3]


In short, solving for the velocity u at positions within a grid can be used to simulate different types of fluid based on the other parameters.