Anatomy of a Povray file for using Geomorph


The overall structure of a Geomorph / Povray scene file
The include files and the declared variables
The "" file
The basic objects required in a Geomorph / Povray scene file
The camera
The Sun and the light
The sky
The clouds
The water
The ground

The fog or haze

The height field
Adding other objects

See also the texturing guide.


Geomorph offers a few Povray scene file templates for rendering predefined landscapes with a minimum of work. However, Geomorph users looking for more freedom to design landscapes would probably want to edit their own scene files.

Mastering Povray is not easy, but it is not required to be an expert to get interesting results.

Modifying the Geomorph Povray templates is a good starting point. This page explains how they are built and what you should look for.

Actually, creating "good enough" landscapes requires only a subset of the Povray language. Texturing is probably the most important ingredient in achieving realism.

After reading this page, the Geomorph templates and the texturing guide, if you want to go further, I recommend that you glance through the Povray tutorial and the Povray reference available on You can also browse the Web to pick examples. Some links are mentioned in this page.

HintWhen you modify a Povray file executed from Geomorph, start Geomorph from a X console, so that you can read the Povray error messages.

The overall structure of a Geomorph / Povray scene file

A Povray scene file is a text file with the .pov extension.

We will use the mountains.pov file as example in this page, unless stated otherwise.

The file is arbitrarily divided in 3 parts:
  1. The first part contains include files and declared variables.
  2. The second part contains basic objects declarations
  3. The third part, after a row of *, recalls the basic objects in a summary manner.
In the third part, the row of * is not a Povray standard, it is only a way to improve legibility of the Geomorph scenes. This part allows the user to easily activate / unactivate the objects, or to translate, scale or rotate them, without having to browse the whole scene text, which could be quite long.

The include files and the declared variables

The "include" files are compliant but incomplete Povray definitions, which could not be executed stand alone. A scene file usually contains standard include files, found where the Povray software is installed (something like /usr/local/share/povray/include):

#include ""    // Standard Colour definitions
#include ""    // Standard Texture definitions
#include "" // Standard Povray skies

All text preceded by // is considered as a comment.

Geomorph also provides its own textures, copied from the directory where Geomorph is installed (/usr/local/share/geomorph/<version>/) to the "geomorph" user directory when install-user is run or the first time the user starts Geomorph:

#include ""    // Generated rockmap
#include ""
#include "" // This one is not used in mountains.pov

Version 0.40 and later

Now it is sufficient to include, which includes the three files. So the sequence is:

#declare rock_color = 0.5*(<0.72,0.66,0.4>) ;
#declare rock_turbulence=0.2;
#include ""

These files are stored in the user's private geomorph directory, so that he or she can adapt them.

Povray global variables are also usually declared at the beginning of the *.pov scene file, although they can be declared anywhere. For instance, mountains.pov contains these declarations:

#declare rock_color = 0.5*(<0.72,0.66,0.4>) ;
#declare rock_turbulence=0.2;
#declare rock_scale=0.05;
#declare rock_normal=1.5;
#declare sky_density=0.6;
#declare forest_color_density=0.8;
#declare water_density=0.35;
#declare fog_distance=10;
#declare fog_transparency=0.1;
#declare fog_altitude=0.15;

"rock_color" is used in "". "" provides "banded" gradient variations, based on the colour specified by "rock_color" (think about sedimentary rock).

The other variables are used in "" or in the current *.pov file, as parameters to the definition of the basic objects.

Most variables in Geomorph include files are not mandatory. When they are not set by the user, the include file sets a default value (check the "#ifndef" keyword in these files).

Naturally, a variable used in an include file must be declared before including the file, not after!

Let's say a word about Povray variables. There can be scalars (ex. 10, 0.1...) or vectors (<0.72,0.66,0.4>). The decimal separator must be a point. A vector means, depending on the context, the <x,y,z> coordinates, or the <red,green,blue> colours. Any scalar or vector can be replaced by a formula. For instance, 0.5*<1.0,1.0,1.0> is equal to <0.5,0.5,0.5> - it's useful for decreasing or increasing globally the density of a colour. The declaration must end with a semi-comma.

About <x,y,z> vectors, remember that X is the left - right axis, Y is the down - up axis, Z is the forward - backward axis.
The Povray axis

The "" file

If you don't have a Display_gamma setting in your povray.ini file, and your Povray results are not too light and not too dark, you can skip to the next section.

From Geomorph version 0.23 and up, a "" file is shared by all Geomorph templates. The templates check if the file exists, and if so, include it.

This file, in version 0.40, contains only the assumed_gamma setting with the value of the Display_gamma setting found in the povray.ini file, if there is one. If not, contains only comments.

The gamma is an attribute of your display system. The Povray reference guide (see explains how to evaluate it.

The assumed_gamma variable works with the Display_gamma parameter in your .INI file (/home/<you>/.povray/3.6/povray.ini).

Povray adjusts the output density depending on the relationship between assumed_gamma and Display_gamma.

You don't have to use Dislpay_gamma and assumed_gamma if you are satisfied with the dentity of your output.

However, after a first install of Geomorph with 0.23, or an upgrade of the files in the /home/<you>/geomorph directory, assumed_gamma would be active. If you didn't specify Display_gamma in your povray.ini file, a 2.2 gamma is assumed by Povray, which is fairly high. Your landscapes would probably be too light.

Roughly, here is how to manage this:
The basic objects required in a Geomorph / Povray scene file

Creating a landscape generally requires:
Apart from the trees and similar objects, the clouds, the water, the ground and the fog or haze can be considered optional, even the sky if you want a black background!

The camera

The camera is declared this way:

#declare maincamera =
    location    <0,  0, -0.1>    // <X Y Z>
    angle     gl_angle
    up        y                  // which way is +up <X Y Z>
    right        aspect_ratio*x             // which way is +right <X Y Z> and aspect ratio
    look_at    <0, 0, 0>     // point center of view at this point <X Y Z>

It is recalled this way:

camera {maincamera
        translate <0+tr_x,0.05+tr_y,tr_z>
        rotate <rot_x,0+rot_y,0+rot_z> }

The variables gl_angle, aspect_ratio, tr_x, tr_y, tr_z, rot_x, rot_y and rot_z are declared in the include file. This file is generated from the active camera in the preview each time the "Render" button is clicked. A new file overwrites the actual one, so there is no point to edit it.

Here is an example of the file:

#declare gl_angle = 28;
#declare aspect_ratio =  1.3333300;
#declare tr_x = -0.0000000;
#declare tr_y =  0.0700000;
#declare tr_z = -0.9250000;
#declare rot_x = 11;
#declare rot_y = 0;
#declare rot_z = 0;

The Sun and the light

A scene usually has at least one light. However, a light has no dimension itself. It cannot be seen when the camera is directed towards it. We need to give it a shape with an other object.

In Geomorph Povray templates, the main light is given the shape of a sphere to simulate the Sun. So, in a backlit scene like a sunset, you'll see the sun disk, as seen on the example rendered from sunseta.pov at right.

Here is how the light is generally produced with Geomorph :

#declare light=<1,0.97,0.94>; // Light colour (<red, green, blue> components)
#declare sun= sphere {<0,1,0>,100
         pigment{rgb 3*light}
// Usually white, but can be coloured even with such a high brightness when some rgb components are null
         finish {ambient 1}
// The sphere colour would be produced by itself instead of by reflecting other light sources
#declare Sun =

  0*x // light's position (translated below)
  color rgb light  // light's color
  looks_like {sun} // Gives its shape to the sun

The Sun is translated in its position at the bottom of the file. In mountains.pov, the Sun is in the South West part of the sky:

light_source {Sun  translate <2000,2000,-1000>}

If you want the Sun to follow the camera (constant direction, independently of the height field rotation in the preview), you can rotate it with the camera parameters rot_x, rot_y and rot_z:

light_source {Sun  translate <2000,2000,-1000> rotate <rot_x, rot_y, rot_z> }

In sunseta.pov, the pigment for the Sun is rgb <1,0.8,0.7>, and it is translated at <-6550, 720, 15000>.

The sky

The sky is basically a colour gradient on the Y axis (vertical). Povray provides a sky_sphere declaration for this purpose. A gradient is a kind of "pigment" in the Povray language. The gradient is applied on the sky_sphere object. An example coming from mountains.pov is shown at right (X rotation=355°, angle of view = 55°). So, in a Geomorph template, the sky could be declared in 2 steps:

#declare sky_gradient =
        pigment {
            gradient y
            color_map {
                [0 color rgb sky_density*<0.8,0.8,1>] // Pale hazy skyline
                [0.15 color sky_density*(<0.1,0.3,1>)] // Beginning of clear blue
                [1.0 color sky_density*(<0.1,0.2,1>)] // Clear blue

In the example provided, the blue plane at the bottom is not a plane at all. It's simply the top of the gradient (value 1.0), contiguous to the beginning (value 0.0, the "pale hazy skyline").

After the * row, the gradient could be recalled like this:

sky_sphere {pigment {sky_gradient scale <1.0, 1.0, 1.0> }
    pigment {clouds scale <1.0,0.4,1.0> rotate <0.0,-10,0.0>}} // The next section explains the clouds

A "scale" statement with no effect (values set to 1.0) is provided for editing convenience. The Y value can be increased to widen the hazy band on the skyline (say, <1.0, 2.0, 1.0>. There is no point scaling on the X or Z axis, because this is a gradient on the Y axis.

In most Geomorph templates, the sky_sphere is specified directly, without a #declare directive.

The clouds

There are 2 ways to specify basic clouds.

In both ways, the clouds are provided by a pigment with a transparent background, superimposed on the sky sphere.

You can add a pigment to the sky sphere, or define the pigment in a plane.

Plane version

Sky sphere version

Frequently the plane gives more convincing results.

In mountains.pov, the clouds are applied to the sky sphere:

#declare clouds =
        pigment {
                turbulence 0.2
                color_map {
                [0.4 rgbt <0,0,0,1>] // The "t" in rgbt refers to "transmit" - this colour is transparent and without any tint
 //              [0.7 rgbt <0,0,0,1>] // Replace the preceding line with this one for smaller clouds
                [0.95 rgb <0.7,0.7,0.8>] // Sudbued blueish white
                [1.0 rgb <0.7,0.7,0.8>]
sky_sphere {pigment {sky_gradient scale y*1.0}
    pigment {clouds scale <1.0,0.4,1.0> rotate <0.0,-10,0.0>}}

The granite keyword refers to a pattern showing random noise. On a small scale, it gives a grainy structure which can be used to imitate granite. On a large scale, the grains make believable clouds.

The clouds are scaled up on the X and Z axis, for more realism. Otherwise, they would look like strange cumulus, very close to the observer. When using a plane structure, this scaling is generally not required.

The rotate command is used to place the more interesting area of the sky where you want it in the picture.

The plane structure is used in desert.pov.

When using the plane structure, expect to scale up the texture by a significant amount, for instance 20000, or even 100000. Also, a texture on a plane does not react to the light as it does on a sky sphere. You'll probably need to increase the ambient parameter to emphasize the clouds. Neither structure reacts realistically to the light, at least not like real clouds would.

See also the F. Lohmüller tutorial for creating "good enough" clouds. In this other link, Gilles Tran explains how to create incredible clouds, if you can afford hours and hours of rendering.

The water

The basic water is simply a plane with a transparent and bumpy texture.

//    Dark water
#declare water = plane {y, 0
    texture {
        pigment {color rgbt<0.0,water_density*0.15,water_density*0.35,0.2>}
       normal {bumps 0.1 translate clock scale 3*<2.5,1,1> rotate <0,-30,0>}
       finish {specular 0.9 roughness 0.05
             reflection .5 ambient 0.1 diffuse 0.3 }

Notice the "t" component of the colour, specifying the transparency. Notice also the water_density variable, specified in the first part of the scene file.

There are other ways to render water. See the examples provided by Fr. Lohmüller. Some people also use isosurfaces, Christoph Hormann shows here how this method compares to others. Water can even be created from a Geomorph height field, if you can choose the point of view and the structure of the image so that the finite nature of the height field is not visible.

The ground

A ground plane improves the look of some scenes. For instance, a ground plane with a wavy sand textures makes an interesting sea bottom or a desert ground. In the desert case, the ground plane creates the skyline.
There is no ground plane in mountains.pov, but you can find one in desert.pov (shown) or in sea_and_rocks.pov.

The syntax is similar to the water plane one:

#declare sea_bottom = plane {y, 0 }

... recalled by this declaration, after the * row:

object {sea_bottom texture {shore_granite}}

These 2 lines could be replaced by:

plane {y,0 texture {shore_granite}}

The fog or haze

Most landscapes benefit from a light fog (haze).

Haze and fog are both rendered with the "fog" command, using the "ground fog" type. The difference between haze and fog is only a matter of height, density and distance from the observer.

In mountains.pov, the haze is specified this way:

#declare Haze =
  fog_type   2   // Ground fog, 1 being a uniform fog
  distance fog_distance
  color      rgbt <0.6,0.6,0.8,fog_transparency > // Blueish haze
  fog_offset fog_altitude
  fog_alt fog_altitude
  turbulence 0.8

Notice the variables fog_distance, fog_transparency and fog_altitude, declared at the beginning of the file.

This fog is recalled after the * row by this command:

fog {Haze}

When debugging a scene, it is convenient to comment this line (// fog {Haze}) to speed up the rendering.

The height field

When you click on the Povray button, the height field you are editing is written in the file test.png. All the Povray templates provided with Geomorph call this file. Most of the time, you won't have to care about it.

In version 0.23 of Geomorph, only one height field can be inserted in the scene from the GUI, using test.png. However, you can edit the .pov file to place additional height fields by hand. Reasons for which you could want more than one height field include managing contiguous terrains with very different shapes and textures, for instance a sandy beach and the rocks behind. You could also want to "fill" the skyline in the background with another height field (see also this page for this technique), or superimpose a height field with water to simulate ponds (a "water field"?).

This is how the main height field is declared in the Povray templates provided by Geomorph:

#declare hf =
    png "test.png"
       smooth // Nicer!
    scale < 1.0, 0.3, 1.0 > // See explanations in the text
    translate <-.5, 0.0, -.5> // We center the map in the scene

Version 0.40 and later

The height field should now be declared like this:

#declare hf =
    png main_terrain

"main_terrain" is a variable created in It contains the name of the current height field file, if it has been saved, or test.png, if not. The file also declares variables containing secondary height fields, like "water_map", "background_map", "ground_map" and "crater_map", for some scripts requiring them.

Why use a scale of < 1.0, 0.3, 1.0>? A height field is generated in a 1 x 1 x 1 box. The scale command decreases the height of the box to 0.3, otherwise the height field would seem unnaturally high.

The translation is required to center the height field, otherwise the "South East" corner of the map would appear in the center.

The "#declare" directive allows to recall the height field by using this syntax: "object {hf texture{my_texture}}", at the end of the pov file:

object {hf scale <1.0,1.0,1.0> translate y*0 texture {forest_rock_snow translate y*-0.35 scale 0.7 } }

Notice that the height field and its texture can be scaled and translated separately. Naturally, a scale of 1.0 and a translation of 0 have no effect. These commands are given for convenience, to show rapidly what parameters could be modified during the scene tuning.

Texturing the height field, as said, is probably the most important step in achieving realism. A full page is devoted to the textures offered by Geomorph.

Examples of scenes with more than one height field

Use of a distant height field to "fill" the skyline

Use of a "water field"

Adding other objects

External modellers can be used to add objects to a Geomorph / Povray landscape.

Povtree is a Java interface to the "tomtree" Povray script. It outputs a tree in an include file, which can be huge if you include twigs, leaves and flowers. For instance, the naked tree used in this Geomorph landscape required a 3.8 MB file. Including the file requires these lines in a modified desert.pov file:

#include "" // The output from Povtree
(pov file body)
object {TREE translate <0.55,0.3,-1.5> scale <0.2, 0.23, 0.2>}

The resulting tree structure is #declared as TREE in

There is also Jpatch, which is a Java program for designing objects with an arbitrary shape and to output them in Povray include files. It seems to be inspired from sPatch, a Windows program I found addictive a few years ago.

Both programs require the Sun Java virtual machine, v. 1.4 or more, which, not being a "free" environment like in "freedom", must be downloaded by users of most Linux distributions.

Placing an external object on the height field surface represents a lot of trial-and-error work, but it is a nice exercise for mastering the Povray coordinate system ;-).


Written in May 2005, modified in January 2007

Contact:    Patrice St-Gelais

Back to the documentation index Logo