3D Mesh Simulations

CS 493/693 Lecture, Dr. Lawlor

Although we almost always use 2D textures, OpenGL has always supported 3D or "solid textures":
Texture wrapping and sampling modes are identical to 2D:       
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
GL_LINEAR means "trilinear" interpolation for a 3D texture (interpolation along each 3D axis), and GL_LINEAR_MIPMAP_LINEAR uses "quadrilinear interpolation" (interpolation along each3D axis, and then across mipmap levels).

Annoyingly, you can't bind an entire 3D texture as the framebuffer's attachment for writing, but you can attach to a given Z layer of the texture using

       glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
                GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_3D,
                your_tex_handle, 0, destination_layer);

You'll need to loop over and write to each layer of the texture separately.  It's a little weird that you can read from anywhere in 3D, but only write to a 2D surface.

Similarly, with fixed-function hardware you can only draw a 2D slice of a 3D texture.  To get the whole thing, you need to either draw a bunch of slices (hopefully not oriented so the camera can see between the slices), or just run a shader, and loop over the depth range of interest.

The big problem with 3D simulations is that 3D gets really huge really fast:
  1. 1024x1024 is 1 million pixels.  4MB for RGBA8, 8MB for 16-bit float RGBA.  At 1 billion finished pixels per second, we can do 1,000fps.  No problem!
  2. 1024x1024x1024 is 1 billion "voxels".  4GB for RGBA8, 8GB for 16-bit float RGBA.  At 1 billion pixels per second, we can do 1fps.  Big problem!
On modern high-end hardware, I seem to be able to comfortably render 512^3 volumes (1024^3 runs out of storage space and render bandwidth).  But the extra reads and binds needed for simulation means I can only get to about 128^3, and that's pushing it.  Big dense 3D simulations are one of the few things capable of bringing a modern GPU to its knees!