Monday, July 16, 2012

Creating Terrains with POVRay



In this blog I will describe how to make some terrains with POVRay like those shown in the above image.  This is a simple way to make some great looking terrain maps for your campaign.  In order to do this you will need to get POVRay and install it.

The process takes two steps.

  1. Create a gray scale height map of the surface where white represents high and black represents low.
  2. Use the gray scale map to render a terrain surface.
Step 1. I will start out with a simple example and gradually make it more complex.  The first step will be to use the POVRay pattern bozo to create the surface.  Bozo is like a smoothly varying random surface.  An example of this is given by the following POVRay code:


camera {location <0,10,0> look_at <0,0,0>}

light_source {<0,100,0> rgb 1 shadowless}

plane {y, -1.0 pigment {bozo color_map {[0.00 color rgb <0,0,0>] [1.00 color rgb <1,1,1>]}}}


This code should produce an image something like the following.  I used the +FN option on the render to make the file a png graphic type file since POVRay does not do jpg.
I will explain the code briefly.  The first line generates a camera that is at a certain position (x,y,z) coordinates and is looking at a certain point in space.
The second line puts a light source at a certain location in space.
The third line makes a flat plane and colors it according to the bozo pattern.  The color map goes from black at values of 0 to white at values of 1.  rgb represents the color based on values of red, green, and blue going from 0-1.  For more info read the manual.

Step 2.  I will use this image to make a height field or terrain surface.

camera {location <0,2,.5>  look_at <0,0,0> angle 60}
light_source { <-2,7,2> color rgb 1}
global_settings { ambient_light rgb 1.5 }
background { color rgb 1 }

height_field {
    png "gray_terrain.png"
    smooth
    texture {pigment{rgb .5} finish { ambient 0.225 diffuse 0.75 crand 0.01975}} 
    translate <-.5, .1, -.5>
    scale <1, .5, 1>   
    rotate <0,0,0>
  }
The next code is used to generate the surface.  It should look something like the following at this point.
>

This one has a camera, a light source, some ambient light in the global settings, anything that is not an object is colored white by the background  statement.

The main object here is the height_field object.  It uses the png file created by the previous program.  I called my program gray_terrain.pov so the file it created was called gray_terrain.png.  This is going to use the png file indicated to make a gray height surface from it.
Not too impressive yet.  Next I will add a better pigment to get some better color.

camera {location <0,1,.5>  look_at <0,0,0>}
light_source { <-2,7,2> color rgb 1}
//light_source { <1,7,3>  color rgb .5}
global_settings { ambient_light rgb 1.5 }
background { color rgb 1 }

height_field {
    png "gray_terrain.png"
    smooth
texture {
  pigment {
    gradient y
    color_map {
      [.00 color rgb<.7,  .7,  .5>]
      [.40 color rgb<0,  .2,  0>]
      [.60 color rgb<.2, .5,  .1>]
      [.70 color rgb<.4, .4,  .3>]
      [.85 color rgb<.3, .2,  .6>]
      [.90 color rgb<.9, .9,  1>]
      [.95 color rgb<1,  1,   1>]
      [1.0 color rgb<1,  1,   1>]
    }
  }
    finish { ambient 0.225 diffuse 0.75 crand 0.01975 }
}
    translate <-.5, .1, -.5>
    scale <1, .3, 1>   
    rotate <0,0,0>
  }

This should give you something like the following:

Getting a little better.  Next I will make a more complex surface.
camera {location <0,10,0> look_at <0,0,0>}
global_settings { ambient_light rgb 10}
plane {y, -1.0 pigment {bozo turbulence .5 color_map {[0.00 color rgb <0,0,0>] [1.00 color rgb <1,1,1>]}}}


Added turbulence .5 (as well as adjusting the lighting).
camera {location <0,1,.5>  look_at <0,0,0>}
light_source { <-2,7,2> color rgb 1}
light_source { <1,7,3>  color rgb .5}
global_settings { ambient_light rgb 1.5 }
background { color rgb 1 }

height_field {
    png "gray_terrain.png"
    smooth
texture {
  pigment {
    gradient y
    color_map {
      [.00 color rgb<.7,  .7,  .5>]
      [.40 color rgb<0,  .2,  0>]
      [.60 color rgb<.2, .5,  .1>]
      [.70 color rgb<.4, .4,  .3>]
      [.85 color rgb<.3, .2,  .6>]
      [.90 color rgb<.9, .9,  1>]
      [.95 color rgb<1,  1,   1>]
      [1.0 color rgb<1,  1,   1>]
    }
  }
    finish { ambient 0.225 diffuse 0.75 crand 0.01975 }
}
    translate <-.5, .1, -.5>
    scale <1, .2, 1>   
    rotate <0,0,0>
  }

This is basically the same code as before, but with the new file.  And following is the resulting terrain.

plane { y, -1.0 texture {pigment {color rgbt <0,.2,1,.5>}} translate <0,1.08,0>}

To add some water add the above plane and use the translate 1.08 value to adjust the height of the water.



That is all there is to the basic terrain generator.  I will explain a few more things in upcoming blogs.

No comments:

Post a Comment