Somtimes the best way to learn how to use a new software application is to just jump right in and play around in it. That is what we are going to do now. Open up POV-Ray and create a new ".pov" file with the name of "POV-Ray 101.pov" I strongly recommend you save this file and all of the others you create as you go through this tutorial in a special directory in your "My Documents" folder called "POV-Ray Tutorial" as that will make it easier for you to find files you are currently working on. You should now have a blank file with a name. Click on the green "Run" button on the button bar located below the menu bar. In a few seconds the program will create a new window and display the "scene" you have just created. It should look exactly like the image to the left. Pretty exciting, right?

The scene created by POV-Ray contains nothing because your scene file currently contains nothing. In spite of the lack of information currently in your scene file, the program was able to construct an image which it has saved to the same location as your current scene file. If you are using the windows version of this program, the image file will be named "POV-Ray 101.bmp" and can be viewed in any paint program. Another file that is created every time you click on the "run" button is a backup of the scene file before you made any changes. This file has the name "POV-Ray 101.pov.bak" and contains the contents of the scene file before you opened it up and made changes to it before clicking the "run" button. Before you go on, take a look at the contents of the "POV-Ray Tutorial" folder. You should be able to see both of the files I have just described as well as the original file for at current total of three. If you double click on the ".bmp" file, it will open up in your current default image viewer or editor program.

The purpose of the scene file is to describe your desired scene using a special "scene description language" which can be understood by the POV-Ray program. Like all languages, POV-Ray's "scene description language" has certain rules which must be followed in order for the program to propely understand what you want it to display. All written languages make use of symbols which must be arranged in a particular way to represent a meaningful message. Linguistics is the study of languages and from a linguistic perspective, all written languages have three things in common:

Because scene files in POV-Ray are simple text files, the semiotics of the scene description language is the ASCII character set. The characters you add to a scene file are analysed in a process known as "Parsing." The rules the program uses to "parse" the file are the syntax or grammer of the scene description language. As long as all of the characters you type into the file are arranged by the rules of syntax for the scene description language, the program can parse the file and then "render" a scene based on those characters. The first step to creating a scene is getting an idea for a scene to create and then translating that idea into the POV-Ray scene description language. The folloing little exercise will work us through this process and at the same time introduce us to the most fundamental syntax rules for POV-Ray. Our first idea for a scene will be simple. We want to make the scene red instead of black. Lets try telling the program this in normal English by typing (or copying & pasting) the sample code below into the scene file.

Make the scene red.

When you do this, you should notice that the POV-Ray editor window has automatically changed the color of the letters in the word "red". The rest of the text should still be black.  If you do not see this effect, click here, to fix this "problem" before you go on. As you enter text into the editor window, the program immediately begins parsing the text looking for characters and/or character combinations that it recognizes which have special meaning to POV-Ray.  By assigning different colors to the parts of the text it recognizes, the program can provide lots of immediate feedback on how well you are constructing the scene file. Each color indicates a different type or category of information. The letter combination "r","e","d" forms a pattern that POV-Ray recognizes as a "keyword". Keywords are displayed in the color purple as you can see in the sample below.

Make the scene red.

Now change the letter "r" in red to "R" and you will see the word is no longer recognized by the program so it is no longer purple. POV-Ray is very "pickey" when it comes to capitalization. This is called being "case sensitive" some artificial computer languages are, some are not. You need to be very careful when you are creating your scene files and make sure you spell words out precisely. In POV-Ray, keywords are always in lower case and the automatic color coding done by the editor window helps remind you of this.

Make the scene Red.

Change the text back to what we originally had and click on the run button. When you do this no image is created and the text is highlighted in yellow. When you click "run" the program tries to parse the scene file and stops at the first line where it encounters something which violates the syntax rules. The yellow line indicates where the program was unable to continue its parsing, but this does not always indicate the exact location of the syntax error that prevented fully parsing the file. When a syntax error is encountered, POV-Ray provides two other useful sources of informaition about the error to help you more easily locate it and fix it.

Make the scene red.

At the bottom of the main POV-Ray program window is the "status bar". As it's name indicates, it's purpose is to provide you with information about the status of the program. When a parse error occures, this is a good "second" place to look for information on what caused the error. In this case the following message is displayed on the left hand side of the status bar: "Parse Error: Expected 'object or directive', undeclared identifier 'Make' found instead"

What this parse error means, simply, is that the program has no understanding of the letters "M", "a", "k", & "e". It was expecting a group of characters it could recognize as being either an "object" or a "directive" (whatever those are). The best it can do with "Make" is classify it as an "undeclared indentifier" (whatever that is), highlight the line where it noticed the problem, and stop parcing the file so you can fix the problem.

If you cannot identify the syntax error by looking at the yellow highlighted line or the information provided by the status bar, a third source of help is the "Messages Tab". The Messages Tab will often contain more detailed error information providing you know where to look. To see the contents of the Messages Tab, just click on it's tab label (see above illustration). POV-Ray will list any Parse Errors or Warnings near the bottom of the Messages Tab Window right above the line which reads: "Total Scene Processing Times".

For the current version of the scene file we are working on, this error information consists of four lines of text:

  1. File: \\cs1\staff data\jamespatterson\My Documents\Classes\2008-2009\ACA2\POV-Ray Tutorial\POV-Ray 101.pov Line: 1
  2.  File Context (5 lines):
  3. Make
  4.  Parse Error: Expected 'object or directive', undeclared identifier 'Make' found instead

Line one gives you the file name and path where the error occured. It also tells you the line number where the error was found, in this case the one and only line in our file.

Line two gives you the "context" in which the error occures from the programms perspective. More on this later.

Line three shows the characters immediately responsible for the syntax error, in this case "Make".

The last line contains the same message as what you saw in the status bar.

Obviously, this is a little bit of overkill when it comes to trying to figure out why our current scene file failed to accomplish our stated goal of making the scene red instead of black. What may be painfully obvious to some readers of this tutorial will not be so easily understood by others. Taking a little time early on to learn or review some of the fundametal syntax rules which many artifical computer languages share will greatly reduce the occurance of "simple" errors which are the ones likly to frustrate novice users the most. We are now going to "fix" this syntax error by adding two slash "/" characters to the beginning of the only line in our current scene file.

//Make the scene red.

Same source code written using "standard" coding convention.

/Make the scene red.
//Make the scene red.
Make //the scene red.
Make the //scene red.
/*Make*/ the scene red.
background red
background{red}
background{<1,0,0>}	//Make
            the "scene" red.
background{<0,1,0>}	//Make
            the "scene" green.
background{<0,0,1>}	//Make
            the "scene" blue.
background{<0,0,0>}	//Make
            the "scene" black.
background{<1,1,1>}	//Make
            the "scene" white.
background{<1,0,1>}	//Make
            the "scene" magenta.
background{<1,1,0>}	//Make
            the "scene" yellow.
background{<0,1,1>}	//Make
            the "scene" cyan.

Code Description Here

#include "colors.inc"

global_settings {
  assumed_gamma 1.0
  // used in global_settings, sets the maximum ray tracing bounce
      depth (1 or more) [5]
  max_trace_level 10

}

// ----------------------------------------

light_source {
  <0, 0, 0>            //
          light's position (translated below)
  color rgb <1, 1, 1>  // light's color
  translate <-30, 30, -30>
}

// ----------------------------------------


/*plane { y, 0 pigment { color rgb <0.7,0.5,0.3> transmit
    0.75} }*/

/* Universal Constants */
// ----------------------------------------
#declare NA                = 6.02214179E23;        //Avagadro's Number in 1/mol
#declare R                 = 8.31472;                        //Universal
        Gas Constant in J/mol K 
#declare Tst        = 373.16;                        //Standard
        Steam-Point temp of water in kelvins
#declare Pst        = 1013.246;                        //Standard
        Steam-Point pressure of water in hPa
#declare k                = R/NA;                                //Boltzmann
        constant in J/K
// ----------------------------------------

#declare ALT = 0.0;        //Altitude above Surface
#declare LAT = 0.0; //Distance North/South
#declare LON = 0.0; //Distance East/West

#declare P = 0.0;        //Pressure
#declare T = 0.0;        //Temperature
#declare V = 0.0;        //Volume
#declare WV = 0.0;        //Water Vapor
#declare DP = 0.0;        //Dew Point
#declare RH = 0.0;        //Relative Humidity

//Converts a value in liters to cubic meters
// l = value in liters
// m3 = value in cubic meters
#macro l2m3(m3, l)
        #local m3 = l * 0.001;
#end

//Converts a value in Celsius to Kelvin
// K = value in Kelvins
// C = value in Celsius
#macro C2K(K,C)
        
        #local K = C + 273.15;
#end

//Calculates the Ideal Gas Volume of a gas based on temperature,
// pressure, and moles of a gas or number of molecules of a gas
// 
// V = Volume in liters
// T = Absolute Temperature in Celcius
// P = Pressure in kPa
// n = moles of gas (this value ignored if N is non-zero)
// N = Number of gas molecules 
#macro CalcIDGV(V,T,P,n,N)
        
        #local Ta = 0;
        C2K(Ta,T)
        
        #if(N)
                #local A = N*k*Ta;
        #else
                #local A = n*R*Ta;
        #end
                        
        #local V = A/P;
#end 

//Calculates Radius of sphere based on volume
#macro CalcRs_V(Rs,V)
        #local Rs = pow((3*V)/(4*pi),1/3);
#end

//Calculates the mole fraction of a component of a mixture
// Xi = The mole fraction of the component of interest
// Ni = Number of moles of the component of interest
// N = Total number of moles for the entire mixture
#macro CalcXi(Xi,Ni,N)
    #local Xi = Ni/N;
#end

//Calculates the partial pressure of a component of a gas mixture
// Pi = Partial Pressure of the component gas of interest
// P = Total Pressure for the entire gas mixture
// Xi = The mole fraction of the component gas of interest
#macro CalcPi(Pi,P,Xi)
        #local Pi = P * Xi;
#end

//Calculates the Saturation Vapor Pressure of Water Vapor over
    liquid water at given temperature
// SVPi = Saturation Vapor Pressure of Water Vapor at given temperature
// Tc = Temperature of air parcel in Celsius
#macro CalcSVPi(SVPi,Tc)
        // This formula uses the Goff Gratch equation 
        //(Smithsonian Tables, 1984, after Goff and Gratch, 1946) 
        //The results are only considered accurate in the temp range of
            -50 C to 102 C
        
        #local Ta = 0.0;        //Absolute air temperature in kelvins
        
        //convert celsius value to kelvin
        C2K(Ta,Tc)
        
        #local SVPi =        pow(
                10,
                (
                        -7.90298*(Tst/Ta-1)
                        + 5.02808*log(Tst/Ta) 
                        - 1.3816e-7*(pow(10,11.344*(1-Ta/Tst)) -1) 
                        + 8.1328e-3*(pow(10,-3.49149*(Tst/Ta-1)) -1) 
                        + log(Pst)
                )
        );
#end

//Calculates the Relative Humidity of a parcel of air at a given
    temperature
// RH = Relative Humidity
// PPi = Partial Pressure of Water Vapor at given temperature
// VPi = Saturation Vapor Pressure of Water Vapor at given temperature
// T = Temperature of air parcel
#macro CalcRH(RH,PPi,VPi,T)
        Pi = P * Xi;
#end

#local SVPi=0.0;
#local ParcelVolume = 0.0;
#local ParcelRadius = 0.0;
#local TestTemp = 0.0;                //in degrees celsius
#local TestPres = 101.325;        //kPa
#local m3                = 0;                //volume
        in cubic meters

CalcSVPi(SVPi,TestTemp)
CalcIDGV(ParcelVolume, TestTemp, TestPres, 1, 0)
l2m3(m3,ParcelVolume)
CalcRs_V(ParcelRadius,m3)

//text display properties 
#declare FONT = "crystal.ttf";
#declare THICK = 0.001;
#declare SCALE = 0.125;

union{
        //display Saturation Vapour Pressure
        text {
          ttf             // font type (only
              TrueType format for now)
          FONT,  // Microsoft Windows-format TrueType font file name
          concat(str(SVPi,0,-1)," hPa"), // the string to create
          THICK,          // the extrusion depth
          0               // inter-character
              spacing
          translate y*2
          pigment{Green}
        }
        
        //Display Ideal Gas Volume in liters
        text {
          ttf             // font type (only
              TrueType format for now)
          FONT,  // Microsoft Windows-format TrueType font file name
          concat(str(ParcelVolume,0,-1)," liters"), // the string to create
          THICK,          // the extrusion depth
          0               // inter-character
              spacing
          translate y*3
          pigment{Green}
        }
        
        //Display ParcelRadius in meters
        text {
          ttf             // font type (only
              TrueType format for now)
          FONT,  // Microsoft Windows-format TrueType font file name
          concat(str(ParcelRadius,0,-1), " meters"), // the string to create
          THICK,          // the extrusion depth
          0               // inter-character
              spacing
          translate y*4
          pigment{Green}
        }
        
        scale <SCALE,SCALE,1>
        translate -y * 0.8
        translate -x * 0.5
}

#declare MSCALE = 0.01;

cylinder { <0, 0, 0>, <0, 1, 0>, MSCALE pigment{Yellow transmit 0.5}}
 
box { <0, 0, 0>, <1, 1, 1> pigment{Yellow transmit 0.75}}

#declare CH = pow(m3,1/3);
box {
        <0, 0, 0>, <CH, CH, CH>
        pigment{Red transmit 0.75}
        translate -y*CH/2
        translate -x*CH/2
        translate -z*CH/2
}

#declare RadiusVal   = ParcelRadius; // (0 < RadiusVal) outer sphere of influence on other components
#declare StrengthVal = ParcelRadius; // (+ or -) strength of component's radiating density

// create a smooth blobby shape
blob {
  // threshold (0.0 < threshold <= StrengthVal) surface falloff
      threshold #
  threshold StrengthVal*0.5
  sphere { < 0, 0, 0>, RadiusVal, StrengthVal scale <1,1,1>}
  sphere { < -RadiusVal*1, 0, 0>, RadiusVal, StrengthVal scale <1,1,1>}
  sphere { <  RadiusVal*1, 0, 0>, RadiusVal, StrengthVal scale <1,1,1>}
  sturm
  scale 2//
  pigment{Blue transmit 0.5}
}

sphere {
        <0,0,0>,
        ParcelRadius
        pigment{White transmit 0.75}
}/**/
                                           
sphere {
        <0,ParcelRadius,0>,
        MSCALE*1.25
        pigment{Red transmit 0.25}
}/**/

sphere {
        <0,ParcelRadius/2,0>,
        MSCALE*1.25
        pigment{Red transmit 0.25}
}/**/

camera {
  location  <0.0,0,-(1 * 2.25)>
  look_at   <0.0,0,  0.0>
}

Code Description Here

global_settings {max_trace_level 50}

#include "colors.inc"
#include "metals.inc"

#include "pencilparameters.inc"
#include "Collar.inc"

// create a regular point light source
light_source {
     0*x                  // light's position (translated below)
     color rgb <1,1,1>    // light's color
     translate <10, 10, -100>
}

background {Gray25}

// perspective (default) camera
camera {
     location  <0.0, 0,-2.75>
     look_at   <0.0, 0,  0.0>
}

     /****************************************************** This section
         creates the metal eraser holder for the pencil ******************************************************/    

object {
        Collar
        //rotate x*90
        translate -y*(CLength/2) //keeps collar in center of screen//
        pigment {P_Brass4}
        finish {F_MetalE}            
}

Code Description Here

#include "pencil.inc"
#include "paperclip.inc"
#include "thumbtack.inc"

global_settings {
       radiosity {
                pretrace_start 0.1
                pretrace_end   0.02
                count 400
                
                nearest_count 5
                error_bound 1
                recursion_limit 3
                
                low_error_factor 0.5
                gray_threshold 0.0
                minimum_reuse 0.015
                brightness 1
                
                adc_bailout 0.01/2
        }/**/
        
        photons {
                count 20000
                autostop 0
                //media 300
                jitter .4
        }/**/
        
        assumed_gamma 2.2       //adjusts
            for monitor "brightness"
}

light_source {
        <60, 60, -60>
        1
        spotlight
        radius 2
        falloff 6
        tightness 10
        area_light <7, 0, 0>, <0, 0, -7>, 5, 5
        adaptive 1
        circular
        jitter
        point_at <1.5, 0, 0>
        photons {
                refraction on
                reflection on
        }
}/**/

// create a regular point light source
/*light_source { 0*x // light's position (translated below) color
    rgb <1,1,1> // light's color translate <100, 100, -100> }*/

// perspective (default) camera
camera {
        location  <0.0, 6, 0.0>
        look_at   <0.0, 0.0, 2.0>
        rotate x * -35
}

#declare SurLoc = -PBRadius*1.04;      //location of "surface" on y axis
//Surface for the pencil to rest on
plane {
        y,
        SurLoc
     pigment {color White}
}/**/

union{
        object {Make_Pencil(38,Sharp1, 0, Yellow)
                rotate x * 0
                
        }
        
        object {Make_Pencil(40,Sharp2, 1, Green)
                rotate z*45        
                translate x * -0.5
        }
        
        object {Make_Pencil(40,Sharp3, 2, Blue)
                rotate -z*45        
                translate x * 0.5
        }

        object {Make_Pencil(0,Sharp0, 1, Yellow)
                rotate z * 15
                translate x * -0.5
                translate y *  0.75
                
        }
        
        object {Make_Pencil(0,Sharp0, 1, Yellow)
                rotate z * -15 + 270
                translate y * (PBLength + ELength + CLength+ 0.5)
                translate x * 5.5 
        }

        rotate x*90
}/**/

Make_PaperClip()
#declare PClip1 = object{
        PaperClip
        rotate x*90
        rotate y*90
        //translate -z * 0.125
        translate  y * (SurLoc + WireRadius)
}               

PClip1

object{
        object{
                PaperClip
                rotate y * (90 - 0)
                //translate x * (-0.5 - PBRadius)
                translate y * (Length4 + WireRadius)
        }
        rotate z * -73
        translate y * SurLoc
        translate z * 4.75
        translate -x * 4
}

object{
        object{
                Make_ThumbTack(Green)
                ThumbTack
                rotate -y * 33
                translate x * TBR
        }
        rotate z * 95
        rotate y * 66
        translate y * SurLoc
        translate x * 4.75
        translate z * 4.25
}

object{
        object{
                Make_ThumbTack(Blue)
                ThumbTack
                rotate -y * 55
                translate x * TBR
        }
        rotate z * 95
        translate x * -1.75
        translate y * SurLoc
}        

object{
        object{
                Make_ThumbTack(Red)
                ThumbTack
                rotate -y * 72
                translate x * TBR
        }
        rotate z * 95
        rotate y * 125
        translate x * -0.75
        translate y * SurLoc
        translate z * 7.25
}

object{
        object{
                Make_ThumbTack(Clear)
                ThumbTack
                rotate -y * 28
                translate x * TBR
        }
        rotate z * 95
        rotate y * 299
        translate x * 3.25
        translate y * SurLoc
        translate z * 1.5
} 

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here

Sample code here

Code Description Here