The scene description file must be written with animation commands built-in to the translate vectors of the scene description file so that as POV-Ray renders the frames of the animation, the animated object appears to move.
The key to creating POV animations is the built-in variable "clock".
Here is a simple animation and the scene file from which it is rendered...
The sphere has a translation that looks like "translate <clock,0,0>". This uses the clock value to determine the location of the sphere on the x-axis. Once translation has been setup, the file is rendered something like this...
xpov +h120 +w160 +i anim_demo.pov +kff20 +oxtest +a
This is the absolute shortest form of an animation I know of. We need to examine the various switches on this command line...
| xpov | This is the call to the POV-Ray renderer on my Linux machine. |
| +h120 | Set the height of the frame images to 120 pixels. |
| +w160 | Set the width of the frame images to 160 pixels. |
| +i anim_demo.pov | Provide the name of the scene file we are animating. |
| +kff20 | Sets the final frame value to 20 neatly dividing the default clock value (0.0 - 1.0) into twenty values. |
| +oxtest | Provide a name for the output frame images: xtest01.tga, xtest02.tga, xtest03.tga,...,xtest20.tga |
| +a | Use anti-aliasing while rendering images. |
When the rendering is done you will have...
xtest01.tga xtest06.tga xtest11.tga xtest16.tga xtest02.tga xtest07.tga xtest12.tga xtest17.tga xtest03.tga xtest08.tga xtest13.tga xtest18.tga xtest04.tga xtest09.tga xtest14.tga xtest19.tga xtest05.tga xtest10.tga xtest15.tga xtest20.tga |
TGA files cannot be used in an animated GIF so we need to convert them. By far the quickest way to do this is by using the ImageMagick tools. In particular I use mogrify (one of the utilities included with ImageMagick) to convert from TGA to GIF format.
Here is the command I use...
then you will have...
xtest01.gif xtest06.gif xtest11.gif xtest16.gif xtest01.tga xtest06.tga xtest11.tga xtest16.tga xtest02.gif xtest07.gif xtest12.gif xtest17.gif xtest02.tga xtest07.tga xtest12.tga xtest17.tga xtest03.gif xtest08.gif xtest13.gif xtest18.gif xtest03.tga xtest08.tga xtest13.tga xtest18.tga xtest04.gif xtest09.gif xtest14.gif xtest19.gif xtest04.tga xtest09.tga xtest14.tga xtest19.tga xtest05.gif xtest10.gif xtest15.gif xtest20.gif xtest05.tga xtest10.tga xtest15.tga xtest20.tga |
You can see that a GIF file has been created for each of the original TGA files. We now combine the GIF files into a single animated GIF. For this we need yet another tool...
I have the "whirlgif" program stored under my own directory so the command line looks like this...
This command is simple. It calls the "whirlgif" program and uses the output file flag "-0" to specify the new animated GIF as "anim_demo.gif". It then directs the whirlgif program to collect the "x*.gif" files to make the animation. Since the "x*.gif" are numbered, "whirlgif" reads the files in numeric order as it compiles the animation.
Viewing the resulting animation is fairly simple with "xanim".
Sometimes you may want to construct animations by creating separate series of frames and combining them all at a later time. Here is a command I have used to do exactly that...
Let's look at this in a bit more detail...
| xpov | This is the call to the POV-Ray renderer on my Linux machine. |
| +h120 | Set the height of the frame images to 120 pixels. |
| +w160 | Set the width of the frame images to 160 pixels. |
| +i test.pov | Provide the name of the scene file we are animating. |
| +ki0.0 | Set the initial clock value to 0.0. |
| +kf2.0 |
Set the final clock value to 0.0. (This is necessary otherwise the clock runs only from 0.0 to 1.0 and we need the values over 1.0 in the mouse demonstration loop.) |
| +kfi0 | Set the initial frame number to 0. |
| +kff20 | Set the final frame number to 20. |
| +a | Use anti-aliasing while rendering images. |
Most of these we saw in the earlier demonstration. The ones that we use in creating multi-stage animations are...
| +ki0.0 | Set the initial clock value to 0.0. |
| +kf2.0 |
Set the final clock value to 0.0. (This is necessary otherwise the clock runs only from 0.0 to 1.0 and we need the values over 1.0 in the mouse demonstration loop.) |
| +kfi0 | Set the initial frame number to 0. |
| +kff20 | Set the final frame number to 20. |
By default the POV-Ray clock value runs from 0.0 to 1.0. Look at the translation in the example we've already seen...
The interesting points in this demonstration are the relationships between the declared location of the spheres and the translation parameters.
Lets look at the object definition for the blue sphere that is furthest back in the scene...
sphere { <-1,0,4> , 1
pigment { color Blue }
translate <clock,0,0>
}
|
First, notice that the sphere's location at <-1,0,4> places it one unit to the left of the origin on the X axis. Then the translate <clock,0,0> changes it's location in relationship to it's original location specification.
This means that as the clock value varies (remember, by default it changes from 0.0 to 1.0) it is divided into twenty parts...
if we specify +kff20 on the command line.
Since the demonstration animation shows four spheres, each at a different origination point and each travelling in a different direction we wonder how we can possibly cause a single sphere to travel the same vectors.
There are a few different ways to do this. One employs the #if construct and the other uses multi-stage animations. The multi-stage approach may be the easiest to set up so lets look at it first.
We'll use a single sphere and change the translate vector and render it four times while outputting frames 1-10, 11-20, 21-30, and 31-40.
For each successive rendering, we change the sphere's origin, color (for the purposes of this demonstration only) and translation vector as shown in the table below...
The command lines will then look like these...
| xpov +h90 +w120 +i anim_demo.pov +kfi1 +kff10 +oxtest +a |
| xpov +h90 +w120 +i anim_demo.pov +kfi11 +kff20 +oxtest +a |
| xpov +h90 +w120 +i anim_demo.pov +kfi21 +kff30 +oxtest +a |
| xpov +h90 +w120 +i anim_demo.pov +kfi31 +kff40 +oxtest +a |
The resulting image frames are all kept in the same directory and we use the mogrify and whirlgif commands as shown previously to output our animation.
POV-Ray 3.0 provides an additional way that allows us to control animations. It is through the use of the if...else construct.
|
#if (1*clock <= 1)
sphere { <1*clock,0,0>, 1
pigment { color Red }
}
#else
sphere { <1,1*clock,0>, 1
pigment { color Blue }
}
#end
|
Here we see the direction of motion change based on the clock value. By default the clock value runs from 0.0 to 1.0 but by specifying differently on the command line, we can control the clock variable and then make decisions based it's value. A command line that directs POV-Ray to use values beyond thedefault looks like this...
As you see in this command line, we specify the clock to have an initial value ("+ki0.0") of 0.0, as it would have by default. (Since this is the default starting value for clock we would not have had to insert this particular specification but it is included here for completeness.) we then specify the final clock value ("+kf2.0")as 2.0. In the body of our scene file we test the clock value in the if (1*clock < 1) and if it returns true, the translate vector is varied along the X axis. When the variation goes above 1, the else statement comes into effect and the values of the Y portion of the translation vector provide apparent motion in an upward direction.
You may also note that after the lateral travel along X, the value change along the Y axis begins with 1.0. This causes a jump from <1.0, 0.0, 0.0> to <1.0, 1.0, 0.0>and a jerkiness is seen in the motion of the sphere. We will ignore the fact that no object in nature would behave this way naturally. So if we want the sphere to lift in s smooth manner, we need to adjust the clock value as the Y value varies by subtracting 1 from it. Here is the results of just that...
|
#if (1*clock <= 1)
sphere { <1*clock,0,0>, 1
pigment { color Red }
}
#else
sphere { <1,1*clock,0>, 1
pigment { color Blue }
}
#end
|
|
#if (1*clock <= 1)
sphere { <1*clock,0,0>, 1
pigment { color Red }
}
#else
sphere { <1,1*clock-1,0>, 1
pigment { color Blue }
}
#end
|