Tuesday, December 13, 2011

More Volume Rendering

This weekend I worked on making the volume data (generated by 3D Perlin noise) look smoother, trying to light it directly using the most basic O(N^2) approach, and parameterizing the activities that I'll do for my final animation.

Direct lighting of the volume data has given me the most trouble this weekend.  From total light blowout to a white shell around my volumetric sphere to lighting that appears to be stuck to the outside of the sphere, to strange little color explosions that shift around with the time parameter, I'm just not having any luck getting the direct lighting working correctly.  There are several images and videos belowing illustrating various weird effects when direct lighting is turned on.

Below the noise is tweaked to keep it from filling the sphere by applying a step-function "cut-off" to the perturbed position.  The result looks something like lava lamp blobs.


Below I've turned down the density scalar on the resulting noise.


By giving the sphere containing the volume data the same indes of refraction as air, the containing sphere sort of disappears.  I say "sort of" because when it's animated, you can still make out the spherical shape of the container.


By changing the rgb absorption coefficients, the smoke changes colors.


Now I'm trying to do direct lighting of the volume using, roughly, the following algorithm:

For each each little step along each marched ray through the volume, I send out "shadow" rays to each of the point lights.  The light being refracted through the volume (attenuated along the primary ray), is, at each little step, added to by the sum of the attenuated contributions from each shadow ray.  That sum of refracted plus attenuated shadow ray is then available to be attenuated back along the primary toward the eye.

Here's a screen shot showing way too much light apparently evenly scattered in the volume.  Where the density is really low (wherever the black cloud isn't), there are few particles to scatter the available direct light, so it should keep going until it hits an area of greater density, where it should be absorbed and scattered in relation to the density.


This image makes it look like I have a white shell around a volume that still appears unlit.


By changing the density of the noise inside the volume, the cloud disappears behind the white shell.


Here I turned up the noise density and turned off the direct lighting.


Now I have positioned the eye inside the volume.  You can see artifacts I think are related to the white shell you see from the outside.


I've started using positional density of the noise along with angle between view direction and each light direction.  I noticed various mentions that local density gradients could be used to approximate normals for Blinn-Phong style shading of the volume, so perhaps I'll need to come up with an efficient way to compute or keep track of those.  Below I'm using density and angle between view and light directions to scale the amount of light attenuated at each step.  It has created white blobs in my cloud, but the shell is still all white.


Aha!  I've finally discovered the source of the white shell.  I had divided the distance from the point of interest to the edge of the sphere in the direction of a light into evenly sized bits plus a remainder.  Then I started at the edge of the sphere (well, just short of it actually) and worked back toward the point of interest, attenuating the light along the way.  By taking care of the remainder and attenuating from the very edge of the sphere, the white shell went away.

Unfortunately, the volume still doesn't look properly lit.  It's got a few white blobs near the edge of the sphere, but the rest just looks to be the color prescribed by the absorption coefficients.


Here's another look at the same problem.


I was using a step-function to cut off the noise based on the length of the perturbed position.  This was an attempt to keep the noise from just filling the sphere with what appeared to be a slightly more homogeneous mixture of smoke and air, which was kind of boring.

So to blur the smoke a little more, I changed that step-function cut-off to scale the noise using a negative sigmoidal curve.  So if the length of the perturbed position is greater than 0.3, I use something akin to:  1 / (1 + exp((<perturbed_pos> - 0.3) * 12).  The minus 0.3 shifts what is normally a zero-centered sigmoid to the region where you want the cutoff.  The 12 is a scalar that affects how step the sigmoid is, the higher it is, the closer it gets to a step function.  I picked 12 by trial and error.

Below is the result, with direct lighting turned off.


Now with it turned on.


I monkeyed around with the rgb-dependent scatter and absorb coefficients, the density of the noise, and lots of other things, generating a lot of messy pictures.











I started making animations by using a time value to parameterize the way things move or rotate in the scene.  One of the first things I learned about ffmpeg is that even if I generated anti-aliased frames, the video quality can still be really crappy.  Here's an example.


That happened when I did it like this:

ffmpeg -i screen%04d.ppm video.mpg

Then I saw a tip that helped, and now I get a little better results with this:

ffmpeg -i screen_%04d.ppm -vcodec mpeg4 -b 4800k video.avi

As you can see below, it's a little better, but still not great.


So off I go, using the machines in the new cs lab to render little movies, all night long.

Here's a close up movie of my first attempt at direct lighting, back when the noise was more homogeneous.  It really looks kind of like the lights are interacting with the smoke, or at least it's hard to tell because it's so noisy.


Here's something with nicer looking noise, and with the direct lighting turned off.


Now here it is with direct lighting:


I started scaling the attenuated light at each step along shadow rays by the density and angle between view and light vectors at each step.  That sort of made it look like the direct lighting affects the outside of the sphere, while the absorption proceeds unlit on the inside:


No comments:

Post a Comment