This is a beta version. Please report any typos/mistakes, especially in the scene files. The POV-Ray Tutorial LEGAL INFORMATION This tutorial may be distributed and used free of charge, povided the following rules are obeyed. The file povtut95.zip must be kept as it is, containing all the files and may not be distributed in anything other than its entire unaltered state, with the single exception below. The file povtut95.zip, any of the files within in, or any part of those files may not be included in any other packages, on any media, including paper, without the permission of the author. No charge may be made for any part of povtut95, except for a nominal fee covering the cost of the media. Where it is inconvenient to distribute the entire package, and the distributer only wishes to distribute the document for a particular machine/software package, the distributer must include a text file stating the ommissions made. In almost all circumstances I will be only too happy to allow these files to be distributed as part of other packages, commercial or otherwise, but you MUST get my permission. If you think something needs altering, please send your comments to me. Do not distribute altered forms of this file. On with the show. How to pay for this tutorial This is simple. There is no charge. However, there is no way I or anyone else can produce public domain material of a high standard, unless you, the user says what needs to be improved. Please say what you think of the tutorial. Anything from general comments to pointing out typos (especially in the actual scene files). Even if you gave up after the first few pages, please tell me why! I can be emailed until june 1995, or you could even send a postcard to me, J.Peterson, 4, West Hill Place, Brighton, E.Sussex, BN1 3RU, United Kingdom. Once again, please tell me what you think. Why you need this tutorial. No-one ever said POV-Ray was the easiest program to use. It comes with a great many very powerful features, as well as a thick manual to tell you how to use them. The manual is fine for finding out how to create any one of the many objects that POV-Ray supports, but it leaves you a bit helpless when it comes to creating a whole scene, filled with many different objects of different sizes, and different textures. There is also the problem that many things are easier said than done. The syntax for a height_field, for example, is not that complicated, but most people come up with a tiny pathetic looking jagged lump in the middle of the screen on their first attempt, and often give up with frustration after not getting much further. This tutorial is primarily aimed at people who have tinkered with POV-Ray, but ran up against a brick wall when it came to either handling the complex functions, or incorporating the simple ones into one complete scene. However, that is not to say more experienced POV-Ray addicts will find nothing new here. If you have been using POV-Ray for a long time, you’ll probably be aware of the existence of a whole mass of third party add-ons. Programs have been written (almost all freeware or shareware) that will generate those baffling script-files for you. Anything from complete wire-frame GUI modellers, to modest command line utilities, is out there to help keep you away from the humble the editor and the script-file. This is, however, a mixed blessing. It may seem that a graphical display of your scene is always preferable to a confusing mass of text and jargon, but, to be blunt, it isn’t. If you don’t believe me.... read on! Of course I’m not suggesting all those tools are useless, indeed their existence makes POV- Ray all the more useful. But you will find them easier to use, and you will find POV-Ray as a whole easier to use, once you are familiar with the script file. Getting to that point needn’t be a painful process, and if you follow this tutorial through, you should be able to consider yourself pretty knowledgeable about the details and workings of POV-Ray and able to spend time on the fun, creative, side of raytracing, and not the ‘staring at the scriptfile trying to see why what is on the screen is not what you want to be on the screen’ side of it. How to use this tutorial Although aimed at those who have dabbled in raytracing, this tutorial does not require any knowledge of POV-Ray or any other raytracing program. It does require familiarity with your computer and it’s operating system, and also a knowledge of a text editor, including the cut/paste functions. The text editor doesn’t have to be anything fancy -- in fact it must not be a word-processor. Things like formatting, and fonts and paragraphs and tabs are not wanted. Just plain old ASCII text. The msdos edit program works just fine, as will the windows app. notebook. I can’t speak for Mac’s, and UNIX user’s will do fine with ee, vi, emacs, or asedit. The tutorial is linear. That means you start at the beginning and read through to the end. If you are an experienced user you may not want to bother rendering the very simple scenes at the beginning, but be sure to read through them anyway, as they contain information that will be useful later on. It is not a good idea to rush through as fast as possible so that you can see what the finished scene looks like! When you have reached a good breaking point, it’s probably a good idea to put the tutorial down, and do something else. If you are a beginner, it is a good idea to practice things as you go. Once you have typed in a section of example text, make a back up copy, and start messing around with it!! See what things do. Better still, see if you can guess what things do before you render the scene. When you are bored messing around... go back to the tutorial and see what is next! I designed the main scene for this program using an Intel 486dx66 with 8 megs ram. I would not recommend using a 386, as the rendering times will start to get prohibitive. Any 486dx should be OK. I did not use windows at all. If you want to, allocate as much memory as possible to POV-Ray. As well as POV-Ray and its standard include files (if you don’t know what they are... you’ve probably got them, so don’t worry) you’ll need two more programs. One to convert the .tga (‘targa’) files that POV-Ray produces to something like a .gif file, and one to display the .gif file. If you are using windows, the excellent paint shop pro program does both these things, and more besides. If you are using DOS, Dave’s Targa Animator will do the conversions, and any number of things will display, including image fun, the program I used. These programs are probably available from the same place you got this, or got POV- Ray. For more information see the appendix. What you will not need; you don’t need a knowledge of physics. A reasonable level of mental arithmetic, or a pocket calculator may come in handy. Graph paper is not necessary, but the back of an envelope could be useful. Getting used to three dimensions Look at the bottom left hand corner of you monitor. If your monitor isn’t on your desk, grab a dictionary, and look at its bottom left hand corner. That corner is called 0,0,0, Naught, naught, naught. It is the middle of the universe, and everything in POV-Ray is given a position relative to that. There are three edges that meet at that point, and they all have names, too. x, y, and z. X is the one that goes across the front, parallel to the keyboard. Y is the one that goes up. Z is depth, the mildly confusing one, and it goes away, or back, heading toward that untidy bundle of wires. If you’re using a dictionary, z is the spine. Keep looking at that corner. All those edges are going away in the positive direction. That means simply, if an object at 0,0,0 (the corner) moved it the positive x direction it would slide along across the front of the machine. If it moved in the positive z direction, it would slide back away from you. Positive y is up. Negative y is down. Negative x is off towards the left. Negative z is towards you. Your head, then is up from that corner, so positive y, right a bit from that corner, so positive x, and nearer to you from the corner, so negative z. In POV-Ray everything always goes in the order x y z. so in inches, for example, your head is at, perhaps 6,5,-15. That means 6 inches to the right of the bottom left corner of your monitor, five inches higher than it, and 15 inches toward. ‘Toward’ like that sounds odd, but people have different ideas about in and out. Does out mean coming out of the screen at you... or going out away from you? So I’ll say positive x is simply away, and negative x is toward. If you want a handy way to visualize these dimensions, get your left hand, and point the index finger at the screen of your monitor, or at the wall opposite. That is z . Stick your thumb up. There’s y. Now put you middle finger out to the right. There’s x. Now all this may seem very simple, because it is, and it may seem that it would be a whole lot simpler to just draw a picture showing three axes, but it isn’t. A piece of paper can only ever be two dimensional, and trying to plan your 3d scenes on a 2d surface usually leads to more confusion than before. By dealing with objects one at a time, we can usually imagine the three dimensions in our heads just fine. When in doubt, stick your left hand out, as above. We’ll be dealing with these dimensions constantly, and I know you are itching to get something on the screen, so we’ll move on now. POV-Ray Basics Before we can get going, there are a couple of essential things. First of all, if you haven’t already done so, grab the POV-Ray manual, and flick through the first few pages concerning command line parameters, then come back to this. Gosh.. there are lots of them, aren’t there? This means two things, as a rule. Firstly, you won’t need to know about most of them, secondly it’s going to be a pain typing all that lot each time we render, isn’t it. As for what they all do, the manual will tell you that, and I’ll deal with the more complicated ones later. As for typing them in each time, you don’t really need to. Instead we use batchfiles, or their equivalent. Since there are differences according to the kind of computer you are using, I’m not going to go into any detail here. The manual has some suggestions for way of doing it. I simply have a batchfile that runs POV-Ray with the appropriate parameters, then invokes a gif converter, and then the viewer. I then have several similar batch files for different size renders. I almost always use the +d or display option, since it is often possible to tell before the scene finishes rendering whether it is hopelessly wrong or not. For this reason, I always use the +x option, so I can abort it halfway through. When working I do not often use any resolution greater than 320 by 200. For basic construction I use 160 by 100. I’ll occasionally suggest that you do a ‘good’ render, with anti-aliasing, perhaps at 640 by 480, otherwise how you choose to render the sample files is up to you. If you are squinting it is time to use larger renders. As a note, the buffers should be set to about 100 with +b100. This means POV-Ray won’t try to write every single line of the picture to disk as it renders it, and this will speed things up. With POV-Ray there may be a file povmod.exe. If there is, run it by typing povmod povray and accepting all the default settings it offers. First scene. Create a file with the following in it: #include "colors.inc" #include "textures.inc" #include "shapes.inc" object{light_source{<-10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } Be sure to use capital letters where I do, as POV-Ray is case sensitive. Save this as a file called tpl.pov. Tpl stands for template, and this is going to be the start of every other POV- Ray file we do. Keep a copy of tpl.pov safe somewhere, and add the following onto the end, starting on a new line. object { sphere {<0,0,0> 1 texture{ pigment{color Red} finish {Shiny} } } } Now save this as simple.pov (be careful not to save it as tpl.pov, we don’t want a sphere in that file) and render away. It’s about the simplest scene you can do, so it doesn’t need an amazing high quality render. That was pretty, wasn’t it? Right, now let’s examine the little file that produced it. I’ll be looking into this in tedious detail, so if you have previous experience of POV-Ray, go ahead and skim over this. The first thing we see are three lines with #include “filename.inc”. The #include command in POV-Ray works very simply. When the program is reading through the file and sees that, it stops reading, and starts reading through the file specified in the quotes. When it comes to the end of that new file, it goes back to reading the original file where it left off. By convention, the files specified in #include statements end in .inc, for include. The advantages of this are that we do not have to constantly re-type often used text. We can simply store it in a .inc file, and have it included at the start of the program. If you want, you can #include files inside .inc files. This can, however lead to problems, since you could not then tell just by looking at the main .pov file which other files were needed. So what is in this file colors.inc? In POV-Ray colours are specified with three values, one for red, one for green, one for blue. Each value can be from 0 (none of that element present) to 1 (all of it present) thus color rgb<.8,.1,.8> would be a sort of purple, with lots of red and blue, but little green. Colors.inc simply includes many statements, declaring an English word, like White, to stand for a little chunk of POV-Ray code, like color rgb<1,1,1>. If all the values of red green and blue are set at one, the colour is white, if all of them are at 0, it is black. Don’t worry about the exact syntax for a colour just now. All the ones in colors.inc can be written with just the English word (don’t forget the capital!). The file textures.inc contains more complex things, whole textures, specified as a single word. Note, that since textures include colours, the line #include “colors.inc” must come before #include “textures.inc”. Otherwise the file textures.inc would be using words like Red and DarkGreen without POV-Ray knowing what they meant. The file shapes.inc contains fairly complex definitions of shapes, and I’d stay well clear of it if I were you. Just make sure it’s in there at the start of the file. There’s also a shapes2.inc file that contains hideously complicated mathematical things, but there’s no need for that right now. After that we get onto the light_source. Let’s have another look at it. object{light_source{<-10,5,-10> color White}} Almost everything in POV-Ray can or has to be an object. Because it is not easy to remember when something doesn’t have to be an object, I tend to make everything one. All it means is an extra set of brackets {}. an object is a single thing. It looks like this. object {shape or light_source}. Although POV-Ray notices capital letters, it doesn’t usually mind about spaces or line breaks (when you hit the return key). so object{whatever} is just as good as object { whatever } So first we open an object, with object{ .Then we want a light_source. That is simply an umm... source of light. It is like a bare bulb floating in space, emitting light in all directions. However, you cannot see it!! The light comes from an infinitely small point, there is no bulb... it is a magical source of light. The light will light up other objects, but the source of the light is not visible. It seems rather odd, but there we are. You could of course add your own bulb, but not right now. So. object{light_source{ what next. We need to say a number of things about this light. What colour is it? How bright is it? Where is it?. First we have to do where it is. A location in POV-Ray is specified by three numbers called vectors, referring to the x y and z axes in that order. It’s worth knowing that they are called vectors, because when POV-Ray gives you an error message, you’ll know what it’s talking about. These vectors are put inside a pair of these things; <>. Always. Remember how we found the position of our head, relative to the corner of the monitor. Do the same thing with the light, and the point 0,0,0. In this case, 10 units to the left, 5 up and 10 toward, or for POV-Ray <- 10,5,-10>. Next the colour. Because we included colors.inc this is easy, just say color followed by the color; color White. Now for light sources, color and brightness are the same thing. A dim light would simply be coloured grey, and a glowing red light coloured red. So that’s it. All we have to do is close the brackets. Now for the camera. camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } You can’t see anything without a light and a camera. I hope this is fairly obvious, but it makes a HUGE difference where the camera is. The all-important point 0,0,0, the center of the POV-Ray universe is an entirely abstract proposition. For us to understand these things it helps to have a reference point. I just used the bottom left corner of the monitor. For practical POV-Ray purposes, I use a point a few units inside the center of the monitor. That way, when I create objects at location 0,0,0 they ought to appear in the middle of the screen, in the middle distance. How do I make the abstract point 0,0,0 appear there? Well, it’s all down to where I put my camera. You’ll notice first of all that the location of the camera is at 0,0,0. You also see that I have got translate <0,0,-5>, which moves it -5 in the z axis. So the camera is now standing back a little from the origin (the name of point 0,0,0). If we kept in right at the origin, then any object placed there would be ontop of the camera, leading to all sorts of terrible problems, like not being able to see anything at all. So I have my camera standing at 0,0,0 (It hasn’t been translated yet.. that’s the last thing we do). Where is it pointing? Well, that is specified by the look_at word. It this case point 0,0,1, which means it is looking forward. The next three things, direction, up and right, are a bit obscure, so we’ll come back to them later. Finally, after I’ve set all the other things, I can put my camera where I want it. Don’t worry if you’re confused by any of this, It all gets explained later. I just want you to know there is purpose to it all. Finally, you may have noticed that all the camera information is NOT contained in an object statement (to be contained in a statement simply means to be surrounded by the brackets). That’s because camera’s can’t be objects. I’ve no idea why not, but since you only ever need one of them in the scene, it doesn’t matter too much. Now, onto the real things. object { sphere {<0,0,0> 1 texture{ pigment{color Red} finish {Shiny} } } } Right. First of all we are talking about a thing floating in space, so it’s an object. object { And this particular object is a sphere object{sphere{ And what do we need to know about a sphere? First of all, as always, where is it? In this case, right at the origin, 0,0,0. When making spheres, the location refers to the center of the sphere, and we want it’s center to be at 0,0,0 object{sphere{<0,0,0> Don’t forget those <>. Then what? How big is this sphere. Again, all we need is one number for radius. NOT diameter. Radius. I’ll say one more time. Radius. Now this number is not talking about the x y or z axes and so is not a vector, and so just sits there all by itself. POV- Ray calls these numbers ‘floats’. I call them numbers, but, again, in error messages it will tell you all about floats. They are called floats, because the decimal point floats around. Well, that is to say it can come after the first real number as in 3.00 which is the same as 3, or it can come before it as in 0.000345. What this means to you, is that these numbers can be fractions. It wouldn’t be much of a program if they couldn’t be. The important thing is to NOT use any <>. So.... object{sphere{<0,0,0> 1 Next we need a texture. Not simply a colour, as for the light, but information about colour, shininess, bumpiness, transparency, and so-on. We are not going to worry about that yet. Just type it in. And remember.. close off all the brackets. In my example above, I closed off each bracket on a new line. That is simply to help keep track of them all. It certainly isn’t necessary for simple things like a sphere. Later it will be more important to be neat. So. Your first POV-Ray scene file. If you had any problems getting it to work, check that you typed everything in carefully, including all punctuation and capital letters. It is just possible that you will need to type at extra comma after the vector for the sphere’s position, like this; object{sphere{<0,0,0>, 1 If you don’t need to , don’t add one. Well, I can’t say I haven’t catered for you complete beginners now, so we’ll move on to textures, and some more of the basic shapes, or ‘primitives’ used in POV-Ray. Textures Let’s look at the structure of a texture statement. It contains, basically, three other statements, Pigment, Finish, and Normal. The last of these may seem a bit odd - normal controls any lumps and bumps on an objects surface.. like the little dents in an orange, or a golf ball for example. We’ll be looking at it last. First we’ll look at pigment. pigment{color rgb} This is the basic format for a pigment statement. You might be asking why we need to have the word pigment in there at all, why we don’t just specify the color. Well, the pigment can contain more than one color, for example a polka-dot pigment, or a checkered pigment, but for now we’ll just have one. Each number stands for a value of red, green and blue, and can be between 0 and 1. edit simple.pov so that the line pigment{color Red} reads pigment{color rgb<.2,.2,.8>} Then render the scene again. Amazing. Put in whatever values you like and see what colors you get. When you get bored doing that... read on. Finish statements control the way an object reflects light. A dull object reflects light fairly evenly over its surface, with a smooth change from a pale tint where the light hits it to a dark tint where the shadow falls. A shiny object, such as a pool ball, has a little bright dot, called a highlight, where the light hits it. A very shiny object, such as a chrome tap will even reflect other objects in the scene. All of these properties are specified with the brackets of the finish statement. In simple.pov the finish statement simply has the word Shiny in. That is because in the file textures.inc, POV-Ray is told that the word Shiny stands for a set of parameters that define a shiny object. There are a number of such definitions, you can try rendering the scene (now you’ve found your favourite colour) with the word Dull replacing the word Shiny. So the line should now look like finish {Dull} Instead of that little dot, there is a large, smooth highlight. The first thing we’ll look at in finishes is how to control that highlight. POV-Ray provides two separate methods of doing this. One uses the phong keyword (Named after professor Phong, who did pioneering work on computer graphics in the 1970’s, in case you were wondering), and the other uses the specular keyword. Phong is easier to use, specular can give more realistic results, but is less predictable. There are two parts to phong. First of all phong followed by a number from 0 to 1, which controls how bright the highlight will be, secondly phong_size, which controls how big the highlight will be. So our finish statement now looks like this finish {phong .9 phong_size 40} Note that POV-Ray has a default value for the phong_size, 40, and if you are happy with this, there is no need to specify it. The default value for phong is 0, and so you need to specify something if you want any kind of highlight at all. If you look about your room, you’ll see that objects with soft highlights also have large highlights, so in general a high phong value, for a bright highlight needs a big phong_size value for a tight little spot, and vice-versa. Yes, that’s right a BIG phong_size means a SMALL highlight. Daft, if you ask me, but there we are. Try to think of bigger value phong_size means more shiny. Well, it’s time to experiment. As a rule useful values of phong are anything from 0 to 1, and useful values of phong_size anything from about 10 to 200. The manual gives phong_size 40, the default as being equivalent to a plastic surface. See what you think. If you hit on a particularly good combination, you may want to write it down next to a word like ‘pool ball’ or ‘satin finish’ or whatever, so you can quickly come up with your own materials. It’s worth doing quite a lot of experimenting with this, so go to it. The other method I mentioned uses the specular keyword. This is similar to the phong word and needs a value between 1 and 0. When using this word, the equivalent of phong_size is the keyword roughness, which also uses a value between 1 and 0. However the useful range for roughness is about 0.1 to 0.001. Basically, the larger the roughness value, the rougher the surface will be, and the larger the highlight. Again, it usually a good idea to couple high specular values (bright highlights) with low roughness values (smooth surface/tight highlight). When using this method, some combinations can produce utterly useless and unrealistic results. Try some values of your own. Where things get a bit tricky is when we add the diffuse keyword. This accepts a value between 0 and 1, and rather than controlling the little highlight, it controls the diffuse reflection from the object, the smooth wash of colour across it’s surface. The value given in fact specifies what percentage of light hitting the object will be reflected in this manner. Since most of an object’s surface is visible by virtue of diffuse reflection, rather than by the little highlight, we want this value to be fairly high. The default value is 0.6, and you don’t often want to change it a great deal. However, change the finish statement so it looks like this, finish{diffuse .3 specular .8 roughness .005} and render the scene to see what happens. Well, everything got darker. If only 30% of the light hitting the object is reflecting off its surface, it is not going to show up as well. The moral of that story is to keep diffuse above about 0.45, in normal situations. There are occasions where a lower value is nice, for example when the surface is acting like a mirror, and reflecting other objects, but we’ll look at that later. If an object is supposed to be dull, or rough, it can be nice to increase the diffuse value. Compare these two examples finish{diffuse .6 specular .15 roughness .02} finish{diffuse .85 specular .15 roughness .02} There are several more things we can change in the finish statement, but we’ll get on to those later. Now we’re going to put some more objects in the scene. The sphere is the simplest object in POV-Ray, it only needs a location for it’s center, and a radius. The cylinder is the next simplest and probably the most useful. It needs a location for each end, and a radius, like this object{cylinder{<0,0,0> <0,2,0> .5} } Remember that the information for each end comes in <> because it is talking about the axes. Remember that the size of the cylinder is the RADIUS!! . Here then, is a cylinder going from point 0,0,0 to point 0,2,0. The second point is simply two above the first point, so our cylinder is sticking up in the air, along the y axis. It is half the diameter of the sphere. Of course since it is two units high, and the radius of our sphere is one unit, the bottom of the cylinder is buried inside the sphere, but that is OK.. we just won’t see it. OK, now add the line above onto the bottom of the file simple.pov. Of course there is one more thing you have to do, and that is add a texture. I’ll let you do that yourself. Remember how many you brackets you need, look at how we did the sphere if you want a reminder. You can put the texture information either inside the object brackets and outside the cylinder brackets, like this object{cylinder{<0,0,0> <0,2,0> .5 } texture{stuff} } or inside the cylinder brackets, like this object{cylinder{<0,0,0> <0,2,0> .5} texture{whatever} } } For simple things like this, it makes no difference. Oh, and use a colour other than red. Done that? and it worked? great. If it didn’t work, here’s a hint texture { pigment {color rgb} finish{ phong/specular/roughness/etc.} } The bit I always get wrong, is remembering that pigment needs curly brackets {} and color needs rgb<> . If you are getting error messages and want to know about them, have a look in the appendix. Well, frankly, I think our sphere and cylinder are a bit on the chunky side. They need to slim down a bit. We could use the scale word to do that, but that’s a dangerous beast, so we’ll just edit the radius of each one. Halve the radius in each case, and have a look at what you get. If you are a bit lost now, here is how your cylinder should be defined object{cylinder{<0,0,0> <0,2,0> .25} texture{pigment{color Yellow} finish{Shiny} } } If you have a different texture for your cylinder and it works OK, that’s fine. Right. Now let’s have this cylinder sticking out below the sphere as well. We can do that by changing the place where it starts. That’s currently at 0,0,0, inside the sphere. Change it to <0,-1,0> The sphere has I diameter of .5 (after we halved it), so you should see a .5 unit length of cylinder sticking out below the sphere. .5 units visible below the sphere + .5 units hidden inside the sphere adds up to 1 unit below the origin. Basic maths. There are three ways of changing an object apart from it’s basic parameters. These are translate, rotate and scale. All of them are fundamental to designing scene in POV-Ray and need to be understood pretty much perfectly. That’s not a problem, though, especially since the first one, translate, is as simple as anything. It looks like this translate where each of the numbers is an amount along the three axes z,y and z in that order. The only thing to remember is that this is not giving a new position for the object, it is moving it a certain amount from it’s old position. So, if an object starts at 5,5,5 and gets translated by 2,3,-6 it will end up at 7,8,-1. Why? Well. It starts off at 5 on the x axis. Taking our bottom left corner of the monitor to be 0,0,0 that’s, say, under the center of the screen. It gets translated a further 2 along the axis, so now it is at 5 + 2 = 7 units along the axis. Its y position was 5 too, or about halfway up the screen, let’s say, and it got moved another 3 units up the screen, so now it would be near the top at 8. In the z axis it was moved negatively. Remember the negative z axis extends towards you from the monitor. It was at 5, but was moved by -6, so now it is at -1. To see how this works in practice add this just inside the final bracket of the cylinder object translate<-.5,1,0> and render it. Did it move for you too? :-) Now try this one instead. translate <.2,0,-1> Notice that it appears to have gotten bigger, because it moved into the foreground. A negative z translation moves things toward you. Now is a good time to play around with a few translations of your own. Keep the values small, or else you might translate it right out of the field of view. It is of course possible to have many translate commands for the same object, but it starts to get difficult to keep track of things. Translating by <5,5,5> and then again by <3,-8,-.5> equals one translation of <8,-3,4.5>. A note on notation. You can write a translate command like this translate x and it is the same as this translate <1,0,0> You don’t need the <> when you specify a letter. You can also do this translate y*5 (or -5) which is the same as translate <0,5,0> (or <0,-5,0>) but you can’t have more than one letter at a time, so translate x*3 y*2 won’t work. Time to move on. Set your translate back to 0,0,0 (you could delete it, which would have the same affect, but we are going to be using it again soon, so there’s no need). The next function is rotate, and this is trickier. The rotate command rotates an object about the specified axis, by the specified amount in degrees. So, rotating something in the x axis will spin it about the x axis, as if it were a space-ship orbiting. Imagine a sphere at point <5,5,0>. In reference to your bottom left hand corner of the monitor, that’s sitting on top of your screen, in the middle, about to fall off onto the keyboard, yes? And we are going to rotate it about the x axis. Imagine a rod going straight from the sphere to the x axis (the bottom edge of the monitor) and held rigidly in place to the object, and to the axis. Now imagine pulling the sphere down toward you, or pushing it away. That is rotation on the x axis. Suppose the rod went from the object to the side of the monitor. You could move it round and round in a circle like a helicopter blade, above your screen. That is y axis rotation. Finally, stick your arm out in front of you (try not to punch through the screen) with a pen clenched in your fist. Your arm is the z axis, and as you twist it the pen is rotating in the z axis. Of course there are two directions you can rotate around anything. Normally we speak of clockwise and anti-clockwise, but that isn’t really very helpful. A clock’s hands may go clockwise when we look at them from the front, but if we stood behind the clock they would be going anti-clockwise, so in POV-Ray we speak of positive and negative rotation. To find out which direction this is, hold your left hand up in a fist, with you thumb sticking out. Point the thumb along an axis, in the positive direction, i.e. up for the positive y axis. The way you fingers curl is the way an object will rotate. Stick you thumb away from you, in the positive z direction. Your fingers curl anticlockwise, so the command rotate <0,0,45> would rotate something 45 degrees anticlockwise. Stick you thumb to the left, horizontally. That is the negative x direction, and your fingers show the direction something would move after the command rotate <-30,0,0>. I’ll grant that all this can be tricky to hold in your head, so let’s rotate our cylinder and see what happens. Add the line rotate <0,0,90> right after the translate statement, and just inside the last set of brackets. Render and see what happens. Try different values, positive and negative, but only rotate one axis at a time, leaving the other two with 0’s in. If you use rotate by <90,0,0> you will be looking at the bottom of the cylinder, head on. There are two problems with rotate. Firstly, it rotates around an axis, and not around the center of the object. This means the object will not rotate ‘in place’ unless it happens to be at the center. Since when someone says “Can you rotate the monitor a little” they mean you to rotate it in place, about itself, rather than rotate it about the corner of the room, it is usually a good idea to create objects on the origin, point 0,0,0. If you forget this, you can rotate an object, expecting to see your cube spin around so that a different side is facing you, and instead it goes flying miles out of you scene. Reason number one to create object at the origin. If you want them somewhere else later, they can always be translated there! Secondly, if you translate something 5 units along the x axis and then 5 units down, this will have exactly the same effect as translating it five units down, and then translating it five units across, along the x axis. With translate, it makes no difference which order you do things. With rotate it makes ALL the difference. Imagine our little sphere perched on top of the monitor, in the middle. Rotate -90 degrees in the x axis, and it is still in the middle, but now at the level of the bottom of the monitor, and hovering over the keyboard. From there, rotate 90 degrees in the y axis. It swings round, still at the same height, but sticking out over to the left of your screen somewhere. Now suppose you did the y rotation first. That would put it just at the left hand edge of the monitor, at its original height, hanging out over the keyboard. Then the x axis rotation would bring it smashing down below the desk somewhere. We’ll do something similar with our scene now. Replace the rotation statement with this rotate z*90 As you see we can use letters when specifying rotation in only one axis. This rotates us by 90 degrees around the z axis. Render this. Now add another rotation, like this rotate y*-45 Render this, and see the final position of the cylinder, pointing left and towards us. Now swap those two round, so you have rotate y*-45 rotate z*90 and render that. See the difference? In the first example the rotation around the z axis moved the cylinder so that it was no longer aligned straight up and down the y axis. The rotation around the y axis, therefore, moved the cylinder around towards the camera. In the second instance the y rotation simply spun the cylinder around in place, and did not move it at all, so that the z axis rotation effectively happened alone. Important When using the notation rotate <10,20,30> POV-Ray will perform the rotations in the order they come..... x, then y, and then z. So, in the example above it would be impossible to achieve the desired affect in a single statement. We wanted the z rotation to come first, and when using <>‘s it always comes last. For this reason, it is often a good idea to use the letter notation. OK. Now go back to our translate statement and make it translate <1,0,0> See how that changes the effects of rotations. Play about rotating and translating to your heart’s content. Next come more objects, and more on textures, and the evil scale command. Your file simple.pov should now look like this. If it doesn’t, change it so it does. #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" /* The file t2.inc is going to include all the new textures that you will create. */ object{light_source{<-10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } object{sphere{<0,0,0> .5 texture{Basic} } } object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } I’ll first of all mention two things that speed up editing .POV-Ray files. Firstly, you can comment out text in a scene file by putting two backslashes in front of it, like this // POV-Ray will ignore anything on the same line following the slashes If you want to comment out a big chunk you use /* and */ . Anything between the slash/stars will be ignored. /* all of this and this and even this will be ignored */ but this won’t be! You can use this for adding comments to a scene file, or for temporarily removing something. You’ll see above that I’ve temporarily removed our rotate commands. Another thing is the #declare command. This command defines a chunk of script, such as a shape or texture, as a single word. The word can then be used in place of the script. We’ll be doing this in a moment. First make sure that you have added a new line in simple.pov that #includes t2.inc. See in the listing above. Now create a new file called t2.inc, t2 for textures 2. This will contain one word definitions of textures. Our textures are already cluttering the simple.pov file with brackets, and the more complex textures have many more brackets, and take up a lot of space, so we don’t really want them in our file. Put this in the file and save it. #declare Basic= texture{pigment{color Red} finish {Dull} } #declare Basic2= texture{pigment{color Yellow} finish {Shiny} } A note on syntax. Basic and Basic2 are both textures. Although the word texture comes after the = sign, you need to write texture{Basic} in your scene. Just putting Basic in won’t work. Also, Although it is not essential to use a capital letter for things that are #declared, it is a very good idea, as that will tell you at a glance that it is not something POV- Ray knows about by itself. Also note that in simple.pov I #included the file t2.inc AFTER the other files, since as you can see it uses words like Red and Shiny that need to be #declared previously. #declare can of course be used for objects, and we’ll do that now. Change this part of simple.pov object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } to this #declare Rod= object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } You’ll notice I didn’t add any brackets when I added the #declare. When you are #declaring shapes, the shape must be inside an object. Since I (almost) always put shapes inside objects anyway, that’s not a problem. If you render this scene. There’ll be no cylinder in it. #declare tells POV-Ray to make a note that the object Rod is a cylinder of such and such dimensions. It doesn’t tell it to go ahead and draw one. What we need to add is this line. object{Rod} Notice again, just putting Rod in the file by itself won’t work. It needs to be stated as an object. Now that we have done this, we can easily add more cylinders. Add these lines object{Rod rotate z*-90 texture{Basic2} } object{Rod rotate <-90,0,0> texture {Basic2} } And render that. Brilliant! A dull red sphere at the origin, with glossy blue cylinders extending along the positive axes. The one extending away along the x axis has its short end facing us. Now then. I think these four objects make a rather nice abstract thingy. I want to be able to treat them all as one lump. Well, that’s easy. Make another object that contains them. Simply add the words object{union{ before the first object, the sphere, and two } }’s after the last object. Two close brackets, because we opened two, on for the new object, and one for that mysterious word union. But wait!!! We don’t want that #declare statement trapped inside an object. This calls for a bit of text editing! Use cut and paste to move the text for the sphere down near all the object{Rod}’s. Just above them is fine. Things should be looking like this rest of file above here (Don’t put this line in the file :-)!! #declare Rod= object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } object{union{ // This is the new object we are making object{sphere{<0,0,0> .5 texture{Basic} } } object{Rod} object{Rod rotate z*-90 texture{Basic2}} object{Rod rotate <90,0,0> texture{Basic2}} } //end of the union }// end of the object So as you see, an object may contain other objects. When this happens, we have to use a word to say in what way all these little objects are to be combined into one big object. The simplest way is in a union. To specify that, all we do is put union{ .... } with the shapes in question between the brackets. A union simply treats all the shapes as if they had been welded together. They don’t actually have to be touching, but they will just sit there fixed where ever they are. This is really useful. If we wanted to move all those objects left a bit, all we have to do now is give one translate command to the object that contains them in union. Otherwise we would have to add a translate statement to every one separately. Let’s #declare this funny shape as something called FirstShape. Add the words #declare FirstShape= just before the object{union{ . You can add them on the same line, or the line above, it doesn’t matter. And now we’ll need to put this new object in the scene. Of course in one sense it’s already in the scene because it has been #declared, but we haven’t actually yold POV-Ray to draw the FirstShape when it renders, so at the end of the file add object{FirstShape translate <0,2,0> } which include a translation, and so will also move the whole thing up a bit. Render to make sure that works. A bit too high if you ask me. Change the translate to <0,1,0>. That’s better. Time for something new. We are going to look at textures in more detail now, but we need an object to display them on. We’ll use a box, like the one below, but we don’t want our first little shape getting in the way, so comment it out if the file. This is easy, because we only need to comment out one line. Just put two backslashes before the line specifying FirstShape, like this. FirstShape is still defined, because we are still #declaring it, but POV-Ray will not bother drawing it in the scene when we render. // object{FirstShape translate <0,1,0>> } Then below, add this object{box{<0,0,0> <1,1,1> scale <1,1,1>} texture{Basic2} } The box primitive is also quite simple. The two vectors in <>‘s specify two corners. The first corner is the one that is nearest, lowest, and leftmost. In other words the bottom left near corner of the box. The next number is the opposite corner, and should have higher values for all the axes. If you can’t picture the diagonally opposite corner of a box in your head, don’t worry. Just go one axis at a time. So this box has one corner at the origin. To find the next corner we go one right, one up, and one back. So this is a cube (all sides are equal length, one) going from 0,0,0 to 1,1,1. Then it gets scaled. Oh horror. The scale command makes things bigger if the values after it are greater than 1, and smaller if they are less than one. The dimensions of an object are multiplied by the values in the scale <>‘s . So scale <.5,.5,.5> makes something half the size. Scale <6,6,6> makes something six times as big. This is OK, so far. Scale can also use different values for different axes, so if a sphere is scaled by <1,2,1>, it will be stretched vertically, and look a bit like an egg, or a rugby ball. It’s y dimensions are doubled, and the others stay the same. This is really quite handy. If you have a cylinder going from 0,0,0 to 0,0,5 scaling in the z axis will simply make it longer or shorter. But scale in the x axis, and it will stretch out in a curved slab, like an airplane wing. There’s a catch. Scale is done in relation to the origin, not the center of the object. So we have a sphere at <4,1,0> radius 2. We scale it by <2,2,2> . Is this the same as giving it a radius of 4? Do we get a sphere at <4,1,0> radius 4? Do we hell. We get a sphere at <8,2,0> radius 4. Scale scale’s an object AND ITS DISTANCE FROM THE ORIGIN. Therefore on objects that are not centered at the origin, it acts like a translate command at the same time. This can lead to all sorts of problems, and is very rarely useful, since the same effect can be achieved far more simply by the translation command. Basically, never use scale on objects not at the origin. Now render our box with scale <2,2,2> and see what happens. See that? The box got twice as big, but it expanded away from its corner at 0,0,0 to fill up the top right hand bit of the screen. We don’t want that. So we need to get the center of the box, not its corner, to be at the origin. That’s easy enough. Change it to this. object{box{<-.5,-.5,-.5> <.5,.5,.5> scale <2,2,2> } texture {Basic2} } You see the boxes original dimensions are the same. From an x position of -.5 to and x position of .5 is still a total length of 1, only now the origin falls halfway along. The same goes for all the other axes, so the center of the box is now at the origin. When we scale now the box grows equally in all directions. Because we are looking at the box face on it looks like a boring blue square. Let’s rotate it a little so we see a corner. After the scale command, but inside the last bracket, of course, add a rotation that will rotate the box 45 degrees around the y axis, and -45 degrees around the x axis. Try and guess what the box will look like before you render it. This is what we will be testing textures on. T2.inc is our textures file, so open this up, and we’ll look at a complicated texture. At the bottom of the file, type in the following #declare Stripes= texture{ pigment{ gradient x color_map{ [0.0 color White] [0.2 color Red] [0.4 color Blue] [0.6 color Yellow] [0.8 color Black] } // end of color map }// end of pigment finish{ Dull } } Now change the texture of the box in simple.pov to Stripes and see what happens. Just put the word Stripes in like this ..... texture{Stripes} ... Oh... If you haven’t managed to get that rotate command working, here’s what your box should be looking like now. object{box{<-.5,-.5,-.5> <.5,.5,.5> scale <2,2,2> rotate <-45,45,0>} texture {Stripes} }// end object Let’s go through that texture file. The really new thing here is that we have more than one colour in the pigment. When you have more than one colour, you need to put them in a color_map, which is such an important thing it gets its own set of brackets. Don’t forget them. A color_map contains a list of colors that fill one unit of space. That means that our series of stripes will repeat every unit. This one unit can be divided up with as many different colors as you like. Where a color comes is specified by the number between 1 and 0 before the word color. That color continues until the place where the next color is specified. Look at the map above. At point 0 the pigment is white; move along and by point .2 it is red. Between these points the color will blend smoothly from one to another. By point .4 it has changed to blue. When it gets to the last point, .8 it has become black. It now stays black, and jumps back to white for the next unit of space. You can see this happening at the left hand corner of our cube. It does not go smoothly back to white. This pattern repeats itself indefinitely. You can also see that the pattern spreads out in both directions from the point 0,0,0 in the center of our cube. The word gradient x, before the start of the color_map specifies what these stripes do. In this case they change along the x axis. Change this to gradient y and see what happens. The stripes now change along the y axis. Try it with z, too. The shadowed side of our cube is a little dark to see these textures clearly. We could add another light, shining from a different direction, but instead we’ll use the ambient keyword. Ambient goes in the finish statement, and accepts a number from 0 to 1. This uniformly brightens the surface of an object, in an attempt to simulate ambient lighting. Ambient lighting is simply the result of light reflecting from objects and going on to illuminate other things in the scene. It would take far to long for POV-Ray to calculate this properly, so the ambient keyword adds uniform light to an object, as if it were bathed in the dim reflected light of the objects around it. It is set at a default of .2 Set it to .5 like this }// end of pigment finish{ Dull ambient .5 } } and see what happens. Fine. Now supposing you don’t want you colors blending smoothly into each other. If you have the same color at the beginning and end of a section, this won’t happen. Change the color_map of Stripes to the one below. color_map{ [0.0 color White] [0.39 color White] [0.4 color Red] [0.59 color Red] [0.6 color White] [0.79 color White] [0.8 color Blue] } // end of color_map Textures, as I hope is somewhat apparent from what you’ve see so far, are three dimensional. They are not patterns stuck or painted on to an object, but are materials from which an object is carved. Because of this, they can be scaled, rotated, and translated. Set the gradient back to gradient x . This gives us a row of stripes. If we add a scale command to scale down the texture, the stripes will all get closer together. However at this point it matter where you put the command. Let’s look at our box again. object{box{<-.5,-.5,-.5> <.5,.5,.5> scale <2,2,2> rotate <-45,45,0>} texture {Stripes} }// end object The object transformations (the collective name for scale, translate and rotate) affect everything in the same brackets as them, including any sets of brackets. Here is a silly example of what I mean. {Apples { oranges } {Bananas { peaches rotate<3,4,5>} translate <10,0,0> } scale <.5,2,1> } The scale command is in the outermost set of brackets, and so affects everything. The translate command affects Bananas, in the same bracket, and peaches, but not Apples, who are outside the brackets. Rotate only affects peaches. Oranges, like Apples, are only affected by the scale command. In the box above, then, the scale and rotate commands only affect the shape of the box. If I added a transformation just before the last bracket, i.e. inside the object brackets, it would affect the box and the texture. If I added a transformation inside the texture brackets, it would only affect the texture. So now we are going to shrink our texture, without shrinking the box, like this texture {Stripes scale <.5,.5,.5>} There. You can now see lots of stripes. Of course there is far more you can do than simply have the color_map repeating in bands along a given axis. There are several pattern keywords that can replace the gradient word. The most often used of these are marble, wood, and the oddly named bozo. These are all defined in the manual, in section 5.4.1.3.4. First of all we’ll look at marble. With gradient, when you get to the end of the color map, at location 1, it jumps back to location 0. With marble, when it reaches the end, it starts working backwards from 1 to 0, then 0 to 1 for the next bit, then 1 to 0 and so on. Change the word gradient x to marble, and then render the scene. Try all the different patterns, and see what you get. Note the difference between wood and onion, for example. When you’ve got bored or confused doing that, change back to marble and read on. The real power of color_maps comes with the pigment modifiers. These all work to stir up the color_map and create a more interesting texture. They belong outside the color_map brackets, and inside the pigment brackets. Edit t2.inc and change the Stripes texture to this #declare Stripes= texture{ turbulence .4 // octaves 6 // omega .9 // lambda 1.3 } finish{ Dull ambient .5 } } It’s that turbulence word that we’re interested in. Add the others below it, but leave them commented out for now. Turbulence simply stirs a color_map up. The higher the number after it, from 0 to 1, the more it stirs it up. Try rendering with some different values. Exactly how it stirs things up is quite complicated, and can be modified by the three other words. Octaves indicates how many times the original band of color will be displaced from it’s starting position. If the value is 2, the band of color is stirred once, and then that band is stirred up again. As you can imagine, after only a very few octaves, the thing would look a complete mess. Add Octaves 6 and see what we get. Well.... That wasn’t so messy was it? That’s because each octave the color is stirred a little bit less. The omega value controls how much this will be. An omega of .5 (the default) will mean the second octave only stirs things up half as much, the third, only a quarter as much, the fourth only on eight as much, and so on. Because of this, after about octave three or four, subsequent octaves hardly make any difference at all. Of course if we raise the omega value to 1, each octave will do the same amount of stirring. Try it and see the resulting chaos. You could set omega to be more than one, if you wanted. That leaves lambda. This determines the randomness of the turbulence. The higher the number, the more random. Numbers can be anything, but 0 to 4 seems to be the useful range. It’s hard to say what effect this actually has on the texture, but high lambda values seem to give more jagged, less swirly patterns. Well, we’ve looked at some basic shapes and textures. We are now going to create an abstract scene with some of this stuff in. The scene will include the funny shape we already did in simple.pov, and also some more. We’ll be using some of our own textures, as well as some of POV-Ray’s predefined textures, so we need to keep t2.inc. Make sure simple.pov looks like this #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } #declare Rod= object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } #declare FirstShape= object{union{ object{sphere{<0,0,0> .5 texture{Basic} } } object{Rod} object{Rod rotate z*-90 texture{Basic2}} object{Rod rotate <90,0,0> texture{Basic2}} } //end of the union }// end of the object //object{FirstShape translate <0,1,0>} We’ll keep FirstShape commented out for now, and get rid of the box we used for testing textures. First thing to add to our scene is a floor. For this we’ll use a plane, like this object{plane{y,-2} texture{Chex} } A plane is defined in two parts. First the normal, which indicates which axis the plane crosses. The y axis sticks up, so a y plane is horizontal. Think of the normal as being a pin stuck in the plane, at right angles to the plane. The pin will align itself with whatever axis we specify. Don’t think of a plane as a piece of paper. Planes are infinitely thick, and extend away from that pin forever. So a -y plane is still horizontal, but upside down, extending upwards forever. Because planes are thick, like this, it is possible to be inside one, which is obviously not helpful. The second number shows how far along the axis the plane is translated, to start with. Of course a plane can be translated like any other object with the translate command, but to begin we must specify something, even if it is only 0. Here we have -2. This moves the plane -2 along the y axis, or in other words, two down. If the axis was given as -y, then -2 would move that plane two up. It is best to stick with simple positive axis planes for now. This plane, then forms a floor, two units below the origin. It has a texture, Chex, which we will define now. Open the file t2.inc and type in this texture #declare Chex=texture{pigment{checker color White color rgb<.3,.45,.7>} finish{diffuse .6 specular .5 roughness .005} } You can render simple.pov now, and see a checkered texture. If you want a full explanation of how the checker feature works, look in the manual. Now add this object to simple.pov object{difference{ object{box{<0,0,0> <2,2,2>} texture {PinkAlabaster} } object{sphere{<1,1,1> 1.5} texture {White_Marble} } // sub object } // end difference }// end main object And look at that. The sphere shape has been removed from the box. The difference word will remove from the first object following it, all subsequent objects. If I added any other objects within the difference brackets, after the box, they would all be cut out from the box. The texture of an object that is cut away from something is left on the new surface that is revealed. If you don’t want this to happen, the texture needs to be in the very outermost brackets of the main object, rather than in one of the sub objects. However this is not ideally placed. Just inside the closing bracket for the main object, put this scale<.5,.5,.5> rotate y*-30 translate <-2,-2,-1> The scale makes it half-size. The rotate swings it 30 degrees around the near left corner of the box, which is next to the y axis, and so moves the box away from the camera a little. The translate moves it to the left hand side of the scene, where I want it, down to floor level (remember the plane is two below the origin) and finally toward the camera a little. object{cone{<0,.5,0> .5 <2.5,0,0> 0} texture{Tan_Wood scale<.25,.25,.25>} rotate y*10 translate <-.6,-2,3.9> } Now add this object. The cone is similar to the cylinder, except that you specify a radius for both ends. If one radius is a zero, it will look like a cone coming to a point at that place. Notice in our cone above that the first end is .5 above the origin, and has a radius of .5, which means the bottom edge of the cone will have a y value of 0. The other end the cone has a y value of 0, too, so the bottom edge of the cone will lie flat along the floor. Note that the texture has been scaled down to fit the cone. I think we need more light in the scene, so add this at the top near the other light source. object{light_source{<100,80,-10> color White}} This light comes from the far right, and quite high up. It’s getting boring rending that top half of blackness in the scene. What we need is a sky. We’ll start by doing a sky texture, in t2.inc #declare DaySky= pigment {bozo color_map {[0.0 color rgb<.5,.5,.5>] [0.3 color rgb <.6,.6,.6>] [0.55 color rgb<.4,.4,.9>] [0.75 color rgb<.3,.3,.85>] [0.99 color rgb<.6,.6,.9>] } turbulence .3 } The color map contains a few greys for clouds, and some blues for sky, in no particular order. Bozo is the preferred pattern for sky scenes, as it creates little blobs of color, like clouds. Turbulence is set arbitrarily at this point. To test it out add this to the simple.pov file. object{sphere{<0,0,0> 1000 } texture{DaySky scale<100,100,100> }} The huge sphere will go around the scene, and we will be looking at its inside. The texture is scaled up to fit the sphere, but is still much smaller. Render this and have a look. There’s no need to render the whole scene, just the sky. It looks a bit un-sky like. We can get a more realistic shape into the clouds by stretching them. Change the scale parameters to <100,20,100>. This will effectively make the clouds flatter, by not scaling them up so much in the y axis. Have a look. I think those clouds are too dark. Change the first two colors in the color_map to <.6,.6,.6> and <.7,.7,.7>. Also, I want the clouds to be a bit more raged round the edges. We can do this by making more octaves, and increasing the omega value, so that the turbulence calculations go on to greater depth, as it were (believe me :-). Add the words octaves 5 and omega .7 right after the turbulence word. Brill. Looks great. But the clouds are just a touch on the small side, so in simple.pov scale the texture by <150,30,150>. There we are. But a blue and white sky clashes with a blue and white checked floor, so go into t2.inc and change the texture Chex by replacing the blue and white colors with different ones. Anything you like. Time for more shapes, and more textures. Add these lines to simple.pov object{FirstShape scale <.5,.5,.5> translate <0,1,0>} object{torus{.7,.15 texture{Reflect} rotate x*90 } translate <.5,-1.15,2>} object{cylinder{<0,0,0> <0,2.5,0> .3} texture{Glass} translate <2,-2,1.6> } First, we uncomment FirstShape, and scale it down a little. Then we put in a torus. The torus us a funny thing. It’s a doughnut shape, and only has two parameters, the radius of the hole, from center to the middle of the dough, and next the radius of the dough, from the middle of the dough to the edge of the dough. These radii are called greater and lesser respectively, and the radius of the whole thing is equal to both of them added together. The torus is always centered at 0,0,0 and lying flat on the ground, with the y axis sticking up through the hole, and must be translated to the right part of the scene. The texture Reflect we’ll look at in a minute. The cylinder should be easy by now. The glass texture is in textures.inc if you want a look. We need to make some changes to t2.inc, like this #declare Chex=texture{pigment{checker color rgb<.7,.3,.3> color rgb<.3,.45,.3>} // finish{phong .8 phong_size 10} finish{diffuse .6 specular .5 roughness .0001} normal {bumps .5 scale <.15,.5,.15>} } #declare Reflect=texture{pigment{color rgb<1,1,1>} finish{reflection 1 diffuse .2 specular .3 roughness .002} } First I have added a normal statement to the Chex texture. Don’t worry if your pigment isn’t the same as mine, it doesn’t matter what colors you have. The normal affects lumps and bumps on a texture’s surface. It doesn’t actually model the lumps, but adds extra shadows to the surface, as if it were lumpy. Very simply, you choose what kind of lumps you want, from ripples to dents to bumps to wrinkles (see the manual for definitions) followed by a number from 0 to 1 that indicates how much of them you want, or how lumpy the surface should be. Normal can be scaled and translated and rotated as a separate element in the texture, so for long striated ridges, you could stretch your lumps in one axis, for example. I want little bumps, so I have scaled them down, but notice I left them quite large in the y axis, so that they stick up out of the ground. The Reflect texture introduces us to mirror like reflection. The greater the number after the reflection word, the greater the amount of light reflected by the object. Numbers from o to 1 are acceptable. Notice that diffuse has been reduced for this, as this gives a better surface. Remember that the light sources are invisible, so that in real life a chrome surface would have highlights where the light_source is reflected, but in POV-Ray it would not. Because of this we still need a specular keyword to add highlights. Well, there’s a basic scene for you. A sky, the ground, some objects and CSG shapes, and some textures, realistic or otherwise. If you categorised yourself as a beginner, or as someone who was not entirely sure what is going on, now is a good time to stop, and do scenes like this on your own. Change things in this one, mess about with it as much as you like, but save the original, as listed below. Render this original in at least 640x480 resolution, with anti-aliasing turned on. We’ll be using the image in the ‘big one’. If you are already experienced with basic POV-Ray, then the work begins here! SIMPLE.POV #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} object{light_source{<100,80,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } #declare Rod= object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } #declare FirstShape= object{union{ object{sphere{<0,0,0> .5 texture{Basic} } } object{Rod} object{Rod rotate z*-90 texture{Basic2}} object{Rod rotate <90,0,0> texture{Basic2}} } //end of the union }// end of the object object{FirstShape scale <.5,.5,.5> translate <0,1,0>} object{plane{y,-2} texture{Chex} } object{difference{ object{box{<0,0,0> <2,2,2>} texture{PinkAlabaster} } object{sphere{<1,1,1> 1.2} texture {White_Marble} } } //end difference scale <.5,.5,.5> rotate y*-30 translate <-2,-2,-1> }// end main object object{cone{<0,.5,0> .5 <2.5,0,0> 0} texture{Tan_Wood scale<.25,.25,.25>} rotate y*10 translate<-.6,-2,3.9> } object{sphere{<0,0,0> 1000 } texture{DaySky scale<150,30,150> }} object{torus{.7,.15 texture{Reflect} rotate x*90 } translate <.5,-1.15,2>} object{cylinder{<0,0,0> <0,2.5,0> .3} texture{Glass} translate <2,-2,1.6>} T2.INC #declare Basic=texture{pigment{color Red}finish{Shiny}} #declare Basic2=texture{pigment{color Blue}finish{Shiny}} #declare Stripes= texture{ pigment{ wood color_map{ [0.0 color rgb<.7,.6,.55>] [0.6 color rgb<.7,.6,.55>] [0.7 color rgb<.7,.5,.4>] [0.75 color rgb<.7,.5,.4>] // [0.6 color White] // [0.79 color White] // [0.8 color Blue] }//end of color map turbulence .07 octaves 2 omega .5 lambda .5 } finish{ Dull } scale<.2,.2,.2> } #declare Chex=texture{pigment{checker color rgb<.7,.3,.3> color rgb<.3,.45,.3>} // finish{phong .8 phong_size 10} finish{diffuse .6 specular .5 roughness .0001} normal {bumps .5 scale <.15,.5,.15>} } #declare DaySky= pigment {bozo color_map {[0.0 color rgb<.6,.6,.6>] [0.3 color rgb <.7,.7,.7>] [0.55 color rgb<.4,.4,.9>] [0.75 color rgb<.3,.3,.85>] [0.99 color rgb<.6,.6,.9>] } turbulence .3 octaves 5 omega .7 } #declare Reflect=texture{pigment{color rgb<1,1,1>} finish{reflection 1 diffuse .2 specular .3 roughness .002} } Planning the scene I want the main scene to include as many of the frequently problematic elements of POV-Ray as possible. Height_fields are far and away the most problematic, and these lend themselves to outdoor scenes. However, raytracing generally does not lend itself to outdoor scenes, certainly not if realism is the aim, rather than surrealism. In the end I decided on an indoor scene set in a house with a big window, so the outside could be seen. We need a room, with a window, and past the window we need a landscape. We also need to fill the house with furniture. The window will be more or less central, and so the scene doesn’t appear simplistically symmetrical, an adjoining wall will be visible on the left. On this wall we will hang a picture of the scene simple.pov that we have been building. On the right, in the foreground I need a little display cabinet for all the POV-Ray things we’ll be putting in. I think in fact, a marble pedestal in the foreground, and on it the apparatus for an experiment with light, which is what raytracing is all about. In order to avoid vast scene files, everything but the room itself will be declared as a separate object in an include file, and simply brought into position in the main scene file. But first we need to get ourselves the basic room, with window. Two obvious ways of doing a rectangular room come to mind. First we could have the difference of a big oblong and a little oblong, leaving a big, hollow oblong, into the sides of which we can cut out the window shape. Alternatively, we can have four box shapes, each of them walls, with the window cut out of one of them. I decided on the box shapes only after beginning the scene with the former method, and getting into difficulties adding things like skirting boards and picture rails. So, grab a copy of tpl.pov, the template file, and make it look like this #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include “t2.inc” #declare Camera1= camera{ location <0,0,0> direction <0, 0, .51> up <0,1,0> right <1.33,0,0> look_at <0,0,0.001> } object{light_source{<720,1800,1000> color White}} object{light_source{<0,4,0> color rgb<.5,.5,.5>}}// a dim light camera {Camera1 translate <-.8, 1, 0>} #declare WindowFrame=object{union{ box{<0,-.01,0> <1.5,2.5,.3>} object{ cylinder{<0,0,0> <0,-.3,0> .75} rotate x*-90 translate y*2.5 translate x*.75 } }//end union texture {WallTex}// to leave the edges of the window the same as the walls scale<1,1,1.5> // expanded to cut out skirting board, later on. }//end object #declare BackWall=object{ box{<-.2,-.2,-.2> <5.2,5.2,0> texture {WallTex} } } #declare SideWall=object{ box{<-.2,-.2,.-2> <0,5.2,4.2> texture {WallTex rotate y*-90} } } #declare Floor=object{ box{<-.2,-.2,-.2> <5.2, 0,4.2>} texture{WallTex} } #declare Room=object{ union{ object{Floor} difference{ union{ object{BackWall } object{BackWall translate <0,0,4.2>} object{SideWall } object{SideWall translate <5.2,0,0>} // object{Floor} had to move so. } object{WindowFrame translate<1,0,3.85>} }// end difference translate <-2.5,0,-2> }//end union }//end object object{Room} Save this as scene.pov. Confused? You should be! OK. Don’t worry about things like the camera and the lights and so forth, just look at the walls. There are two kinds of wall, Backwall, which is long, and Sidewall, which isn’t. The walls start at -.2,-.2,-.2, because they are .2 units thick, and we want the inside of the walls to be along the axes. The walls also overlap, rather than just meeting at the corners. Look at the object Room. The SideWall is translated across, by the length of the BackWall, to be the other sidewall. The BackWall is translated away, by the length of the side wall, to be the front wall. Note that it is this translated version of the BackWall that we see, in our picture. Now look at the object WindowFrame. This is in two parts, a box, and a cylinder. Let’s look at this in detail. #declare WindowFrame=object{union{ box{<0,-.01,0> <1.5,2.5,.3>} object{ cylinder{<0,0,0> <0,-.3,0> .75} rotate x*-90 translate y*2.5 translate x*.75 } }//end union texture {WallTex}// to leave the edges of the window the same as the walls scale<1,1,1.5> // expanded to cut out skirting board, later on. }//end object The box goes from 0,0,0 to 1.5,2.5,.3 . It is 1.5 high, therefore, and 2.5 wide. This is simply a good window size, in my opinion. It is .3 deep, because the walls are .2 deep. Huh? Well, if I had made it .2 deep, that should be a shape big enough to cut out of the walls, shouldn’t it? Well, no. In POV-Ray differences there must always be a tiny overlap, or there will be a strange film left over the area where there should be a hole. .3 should be ample margin. You’ll also notice that the box starts at 0,-.01,0 or slightly below the center. Again, for the same reason. If it didn’t there would be a funny mess on the part of the floor by the window, because there would be an odd mixture of wall and nothingness. There always has to be this overlap, and it is this that accounts for many of the odd numbers cropping up. So there are two shapes in the window frame. The box, and in union with it, a cylinder. The cylinder is .3 high. You’ll recognise this as the depth of the wall. It has a radius of .75, so a diameter of 1.5, the same as the width of the box. It is then rotated in the x axis, so that its height becomes it’s depth. It is translated so that its center is level with the top of the box. It is then translated right by the same distance as its radius. Why? Well, the corner of the box is in 0,0,0 (almost), but the center of the cylinder is on 0,0,0, so it sticks out .75 either side of 0,0,0. move it .75 to the right, and it will extend 1.5 to the right of 0,0,0. The scale simply stretches it in the z axis, so when things are stuck onto the walls later on, such as a picture rail and skirting board, we can be sure that the window will cut these out too. Otherwise, the picture rail would run right across the window! Very odd. Half of the cylinder extends into the box, but that makes no difference. Imagine putting a record (remember them ? ) halfway into its sleeve, so the hole was half covered. This is the shape we are making, only in our case not flat like a record, but thick to cut out a window shape from a wall. It doesn’t matter about having one half of the cylinder in the same place as part of the box. The whole shape gets cut out of the wall in the end. Great. So we have a rectangle with an arch on top. This shape can then be cut out of the wall. Of course we could have used a half-cylinder balanced on top of the box to make the same shape, but calculating the difference function to make a half cylinder takes up POV-Ray calculating time. In fact, a test scene I used took 49 seconds to render. The same scene using a half cylinder (the difference between a cylinder and a plane bisecting it) took 55 seconds, over ten percent longer. Difference calculations are time consuming, and should be avoided if possible. Look at the main object Room. It is a union of two objects, the floor, and another object, itself a difference. The floor should be fairly self explanatory. The difference is the difference between the walls (I union), and the window frame. Why is the floor separate? Because otherwise I ran into problems with the difference function leaving garbage behind. There are also some new textures here. Add these to t2.inc The values that I’ve commented out are simply alternative finishes. There’s no need to type them in. #declare WallTex=texture{pigment{color rgb<.8,.76,.6>} finish{diffuse .85 specular .25 roughness .001} } #declare PaintTex=texture{pigment{color rgb<1,1,1>} // finish{phong 1 phong_size 20} finish{diffuse .5 specular .8 roughness .009} } #declare WinTex=texture{pigment{color rgb<.95,.95,.95>} finish{phong .8 phong_size 30} // finish{diffuse .3 specular .9 roughness .001} } #declare FloorTex=texture{pigment{checker color White color rgb<.3,.45,.7>} // finish{phong .8 phong_size 10} finish{diffuse .6 specular .5 roughness .0001} scale <.3,.3,.3>} These are some textures for the walls and paint work. Notice the diffuse on the WallTex to give a matte look. Don’t worry about these too much, most of them will be changed later. When you’ve updated t2.inc, you should be able to render the scene. Once you can see what we are talking about things should be easier. Notice the light coming in through the window; this is from the first light in the scene, the brighter one. The room is lit by the dim light. You’ll notice that the Room object is translated by -2.5 in the x axis and by -2 in the z axis. This will bring the center of the floor to the point 0,0,0. This is simply useful when we come to position furniture. We’ll have an idea where to put it. The camera is then translated to get the most balanced view... a purely artistic consideration. Now might be a good time to render and have a look. There are obviously some things missing. Firstly the window needs some bars to divide it into separate panes of glass, and then one big sheet of glass. In both cases the shape doesn’t matter. We can position a huge sheet of glass inside the back wall, and it will only be visible in the window space. The bars need to be centered on the window space, even though they can extend into the wall. There’s no need for an exact fit, but they must be cetntered and symmetrical. Add this near the top of the file, before the window is #decalred (only type the parts in a different font, of course). #declare BarsY= union{ cylinder{<.5,0,.17> <.5,5,.17> .03} cylinder{<1,0,.17> <1,5,.17> .03} } The BarsY are those going up and down in the y axis. The x values are positioned relative to the window frame, which runs from 0 along to 1.5 in the x axis, so these bars will divide it into thirds. The y values run from floor (0) to ceiling (5). They are thin, at radius only .03 The z value moves them to the outside part of the wall. The wall is .2 thick, remember, so these bars will be set .17 back from the inside face of the wall. #declare BarsX= union{ cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*.5} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.5} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*2} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*2.5} } The BarsX run across the window frame. The cylinder statements define horizontal cylinders that are lying at y=0. Note that they extend .5 either side of the WindowFrame, just for safety. By that I mean there is no reason to make them fit the window exactly, they may as well extend into it. Note the z value is the same. They are then translated up from lying at y=0, to fill the window space. #declare WindowGlass=object{ box{<-1,-1,0> <2,5,.0015>} texture{Basic2}} Note that the box starts well either side of the frame, and is really thin, just like a sheet of glass! The texture is set to Basic2 to speed up rendering, as calculating the effect of glass is complicated. POV-Ray accurately works out how glass reflects and refracts light, but this takes a long time, for test renderings we can use an opaque texture and imagine how it would look with glass. #declare Window=object{union{ object{ BarsY } object{BarsX } object{WindowGlass translate z*.17} } texture {WinTex} } Note that the WindowGlass is translated out to the same z position as the center of the window bars. So we have added objects for the bars and glass. Remember these objects are all still based around the origin. We now have to add them to the big room object, and when we do, remember to translate them all 4 units along the z axis, to where the back wall is. The Window is going to go in the main union, at the beginning, not the union with walls in, or else the window frame would cut out not only a hole in the wall ..... but in the bars and glass, too, and we’d be left with nothing. #declare Room=object{ union{ object{Window translate<1,0,3.99>} object{Floor} difference{ union{ object{BackWall } object{BackWall translate <0,0,4.2>} object{SideWall } object{SideWall translate <5.2,0,0>} // object{Floor} had to move! } object{WindowFrame translate<1,0,3.85>} }// end difference translate <-2.5,0,-2> }//end union }//end object If you like you can change the WindowGlass texture from Basic2 to Glass, and see how we are doing. Notice the increase in time taken to render the scene. Some people would stop here, thinking they had a pretty good room. But there are some things missing. First of all, we need skirting boards, and picture rails. Secondly, I think there is something artistically lacking in the grid of bars in the window. The bars are easy to adjust, so we’ll do them later. Skirting boards are going to be a bit tricky, so pay attention! Type in these definitions before the definitions of the two walls. #declare Skirting=object{union{ box{<-.2,-.2,-.2> <5.2,5.2,0> translate<0,-4.9,-.04>} cylinder{<0,.3,-.2> <5.2,0.3,-.2> .02} texture{PaintTex} }//end union } The object Skirting has two parts. The first you will recognise as being a box exactly like the wall that it is going to run along. This box is then translated down by -4.9 , so that the top of the box will be visible near the bottom of the wall. The top of the box is at 5.2. It is translated down by 4.9 (5.2-4.9=0.3). The floor is at 0. So how much is visible above the floor? .3. It is then translated in the z axis by the amount we want it to stick out from the wall. Now the skirting object is going to get attached to the BackWall object, and as we know, in the scene we see the BackWall object translated 4 units away into the z axis. Supposing you are the camera in this scene, standing on the letter ‘b’ of your keyboard. Put your hand on edge, palm toward you on top of the spacebar. This is where the BackWall is defined as being, and then a copy of it is translated to where the asdfghjkl;’ keys are, which is the bit you can see. But notice that when your hand is resting on the spacebar it is the knuckle side that faces into the room, and when it is moved away, it is the palm side that faces into the room. So although we are adding this Skirting object to the wall that is hidden, behind the camera, we want the skirting attached so that it will be visible on the translated version of the wall. So.... we translate the skirting so that is nearer the camera than the wall... in the -z direction. .04 is a good amount.. just a little wider than the window bars. There is also a cylinder that runs along the top of the skirting board to make it a bit more interesting. In the x axis it goes from 0 to 5.2, the length of the wall. It is at .3 in the y axis... its center at the top of the skirting board. It is at .2 in the z axis, which of course means its center is at .2. So it is half buried in the wall. It has a radius of .02, half the width of the box. So, one half is buried in the wall, of the visible half, on half is buried in the box object. We are left with a quarter cylinder visible, nicely smoothing the join between wall and skirting box. Note that the cylinder is half the width of the box, so it does not meet flush with the visible face of the box.. this is intentional.. it simply makes a more interesting shape. Skirting1 is the skirting board for the sidewalls, and is the same in principle. #declare Skirting1=object{union{ box{<-.2,-.2,-.2> <0,5.2,4.2> translate<0.04,-4.9,0>} cylinder{<0,.3,0> <0,.3,4.2> .02} texture{PaintTex} }//end union } Here, the object Skirting1 will be attached to the SideWall object. The skirting box is a copy of the SideWall box, translated to the right by .04, to extend into the room. The cylinder runs along the top, as before. The skirting board is a different texture to the walls. We now need to add these to our walls, so make a small change in the wall definitions like this #declare BackWall=object{union{ // This is the wall BEHIND the camera box{<-.2,-.2,-.2> <5.2,5.2,0> texture {WallTex} } object { Skirting } }//end union } #declare SideWall=object{union{ // this wall is visible on the left box{<-.2,-.2,.-2> <0,5.2,4.2> texture {WallTex} } object{ Skirting1 } }//end union } Great. Render away, and see what you think. It you like, replace the texture of the window glass with the texture ‘Clear’. This will give a small error when POV-Ray parses the scene, which can be ignored, and will give you an idea of what the window looks like. Speaking of the window, those bars were no good at all. They look grid-like and boring, don’t they? Well, change the BarsX definition to this #declare BarsX= union{ cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*.7} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.4} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.9} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*2.4} } I’ve made the first and second bars further apart, to leave a larger gap at the bottom of the window. While we are on the subject of bars, a little note on bounding. In POV-Ray everytime a ray is traced, in other words everytime a pixel is calculated, the computer calculates whether or not it hits each object. So when POV-Ray is calculating the pixels at the very bottom of the scene, that are part of the floor, it still asks itself each time “does this ray hit window bar1? does this ray hit window bar2 ? etc. etc.” You don’t need many objects in a scene before things start getting slow. One way we can speed things up is to include lots of objects inside a bounding box. For every pixel, POV-Ray looks to see whether the ray hits a boundung box. If it DOESN’T, then POV-Ray won’t bother to see if it hits any of the objects inside the box. So if we put all our window bars in one box, POV-Ray only has to work out if a ray hits all those bars if the ray hits the bounding box. You have to make sure, of course, that the box is big enough. If you say that all our window bars are contained inside just this little box in the top part of the window, POV-Ray will only draw bars in the top part of the window. POV-Ray version 2.2 has various tricks for working out its own bounding boxes, but these tricks have little effect on complex #declared objects, particularly if there are difference or intersection calculations involved. Since a bounding box has to be attached to one object, we are going to turn the two objects BarsY and BarsX into one object WinBars, like this #declare WinBars =object{union{ object{BarsY} object{BarsX} } bounded_by{box{<0,-.01,0> <1.5,5,.3>}} //extends to ceiling } And also chage the Window object to #declare Window=object{union{ object{WinBars} object{WindowGlass translate z*.17} } texture {WinTex} } Bounded_by requires its own set of brackets, inside which you can put any of the POV-Ray primitves like sphere,box,or cylinder. This is a box that is the same size as the WindowFrame object, but extends up to the ceiling, to make sure those bars that fall inside the curved upper part of the window are also drawn. My test scene, that was taking 49 seconds to render, with this change takes 42 seconds to render. In case you were wondering, for the development of the scene at this point I used renderings of 128x80, with the display turned on. I rarely bothered viewing the output file... if it looked wrong while it was rendering, I aborted and went back to the editor. After I’d decided something looked ok, like the skirting board, I’d do a 320x200 render with anti- aliasing, and go and make a cup of tea or something. Well, there’s just one more thing that we need, and that’s a picture rail. For now, the picture rail is just going to be a cylinder buried in the wall at an appropriate height. The very same cylinder we put on top of the skirting board, as it happens. #declare PRail=object{ cylinder{<0,2.3,-.2> <5.2,2.3,-.2> .02} texture{PaintTex} } Dead simple, this. It runs from 0 to 5.2, along the length of the back wall. It is 2.3 up. It is set back by -.2 because you remember our walls have their inside edges at 0, and this is going on the outside edge of BackWall, since in the translated copy of BackWall (the one the camera can see) it is this side that faces us. Believe me! #declare Prail1=object{ //that’s Prailone not praill (with two L’s) cylinder{<0,2.3,0> <0,2.3,4.2> .02} texture{PaintTex} } Even easier. At a height of 2.3, this runs the length of the SideWall. We now just have to add an extra object to our wall definitions. Add Prail to the BackWall object and Prail1 to the SideWall object. I’m sure you can do that on your own. OK, so there is one very last thing, the roof. This will never appear in the picture, and is just to keep outdoor lights from shining down into the room. It looks like this #declare Roof=object{box{<-.2,4.1,-.2> <5.3,4.1,4.2>} texture{WallTex}} It is a slab that covers the room just above the height of the ceiling light. You need to add this object to the definition of the Room object, inside the same union as the Window and the Floor. Finished. For now. This would be a good time to turn your WindowGlass to something transparent (the texture Glass, defined for you in textures.in would do nicely) and render away at 640x480 or some such hi-res setting. Look back through the tutorial and make sure you understand what is going on. Below is a listing of how your scene should look at this point. #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" #declare Camera1= camera{ location <0,0,0> direction <0, 0, .51> up <0,1,0> right <1.33,0,0> look_at <0,0,0.001> } object {BrightLight1 scale <1, 1, 1> translate <720, 1800,1000>} object {Light1 scale <1, 1, 1> translate <0, 4, 0>} camera {Camera1 translate <-.8, 1, 0>} #declare BarsY= union{ cylinder{<.5,0,.17> <.5,5,.17> .03} cylinder{<1,0,.17> <1,5,.17> .03} } #declare BarsX= union{ cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*.7} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.4} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.9} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*2.4} } #declare WinBars=object{union{ object{BarsY} object{BarsX} } bounded_by{box{<0,-.01,0><1.5,5,.3>}}//extends to ceiling } #declare WindowGlass=object{ box{<-1,-1,0> <2,5,.0015>} texture {Clear}} // set to something opaque for quick rendering #declare Window=object{union{ object{WinBars} object{WindowGlass translate z*.17} } texture {WinTex} } #declare WindowFrame=object{union{ box{<0,-.01,0> <1.5,2.5,.3>} // minus y value to prevent membrane //error object{ cylinder{<0,0,0> <0,-.3,0> .75} rotate x*-90 translate y*2.5 translate x*.75 } }//end union texture {WallTex} scale<1,1,1.5> // Scaling to cut out skirting }//end object. #declare PRail=object{ cylinder{<0,2.3,-.2> <5.2,2.3,-.2> .02} texture{PaintTex} } #declare PRail1=object{ cylinder{<0,2.3,0> <0,2.3,4.2> .02} texture{PaintTex} } #declare Skirting=object{union{ // Goes on the wall BEHIND the camera box{<-.2,-.2,-.2> <5.2,5.2,0> translate<0,-4.9,-.04>} cylinder{<0,.3,-.2> <5.2,0.3,-.2> .02} texture{PaintTex} }//end union } #declare Skirting1=object{union{ box{<-.2,-.2,-.2> <0,5.2,4.2> translate<0.04,-4.9,0>} cylinder{<0,.3,0> <0,.3,4.2> .02} texture{PaintTex} }//end union } #declare BackWall=object{union{ // This is the wall BEHIND the camera box{<-.2,-.2,-.2> <5.2,5.2,0> texture {WallTex} } object { Skirting } object {PRail} }//end union } #declare SideWall=object{union{ box{<-.2,-.2,.-2> <0,5.2,4.2> texture {WallTex rotate y*-90} } object{ Skirting1 } object{ PRail1} }//end union } #declare Floor=object{ box{<-.2,-.2,-.2> <5.2, 0,4.2>} texture{FloorTex} } #declare Roof=object{box{<-.2,4.1,-.2> <5.3,4.1,4.2>} texture{WallTex}} // just above the ceiling light. #declare Room=object{ union{ object{Roof} object{Window translate<1,0,3.99>} object{Floor} difference{ union{ object{BackWall } object{BackWall translate <0,0,4.2>} object{SideWall } object{SideWall translate <5.2,0,0>} } object{WindowFrame translate<1,0,3.85>} }// end difference translate <-2.5,0,-2> // to bring center of room to 0,0,0 }//end union }//end object object{Room} Furnishing the room We now need to add some things to our room to liven it up. We are going to hang a picture on one wall, but that is only a small thing. It you look at the window frame, it looks rather artificial, the way it is just cut out of the wall, especially where the skirting board suddenly stops. In a real house the skirting board would go around the corner into the window bay, but that is too hard to model, for the sake of a little realism. So I think we need to break up the line of the cut-out. For that, I think two pillars (classic raytracing objects) are going to be put on the corners of the window bay. The pillars are going to be reallly quite complicated, so they won’t be the first things we’ll do. Instead we’ll get to work on the picture to hang on the wall. This is really just an exercise in using image_maps, but we’ll need a picture frame and a few other bits and pieces too. The image map is the hard part, I’m afraid, so we’ll do that first. Open up a new tpl.pov file and make it look like this #include "colors.inc" #include "textures.inc" #include "shapes.inc" object{light_source{<-10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } #declare Picture=object{ box{<0,0,0> <2.5,2.5,.1>} texture{pigment{ image_map{gif “simple.gif” } // the word gif specifies file type } finish{phong .3 phong_size 5} } Render this and have a look. Well.. The first thing we notice is that the picture appears more than once. An image_map in POV-Ray by default stretches from 0,0,0 to 1,1,0. Since our box goes beyond this, the image just repeats itself. By default an image will duplicate itself to cover the whole surface of the object in one unit sized tiles. There are solutions to this. You could scale the image_map (ie scale the texture) to fit the box, or shrink the box to a one unit size, or use the once command inside the image map brackets. The once command does not, alas, automatically fit the image to the object, it simply stops repeating the image after the first time... useful for say putting an image map of a label onto a wine bottle, when you only want the label appearing once. For us, the best thing to do is scale up the image_map to fit the box, by adding the command scale<2.5,2.5,1> inside the last bracket of the texture. There is no point scaling in the z direction as we shall see, so leave it at 1 Great. But this thing is square, and as you remember, the original image was not square, it was either 320x200 or 640x480, or even 800x600, depending on what you rendered it as, but either way, not square. Since in POV-Ray images are always squeezed to a square from 0,0,0 to 1,1,0 we are going to have to do some resizing. It just so happens that the height and width ratio of a standard svga picture is 1.333 : 1 So we will scale the whole object (both the box and the image on it, in other words) to this size. But first, we make the important decision to move the picture so that the center of the picture, rather than the bottom left corner, lies on the origin. #declare Picture=object{ box{<0,0,0> <2.5,2.5,.1>} texture{pigment{ image_map{gif "simple.gif" } // image_map gets its own brackets } finish{phong .3 phong_size 5} scale<2.5,2.5,1>} //End of texture translate <-1.25,-1.25,0> // bring center to point 0,0,0 scale<1.33,1,1> // this scales both image and box } // end of object object{Picture} There we are then. The finish I have here is simply a dull look, with little highlighting (small phong value) and what there is spreading over a wide area (small phong_size). This ought to look basically OK. If it doesn’t then it is not too important, since it is only an abstract picture. We now want to have a look at this object from an angle, to demonstrate an important point of image_maps, so rotate the picture by adding the command rotate y*70 immediately after the second scale command. This will rotate the picture around the y axis, right? Hold up your left fist with thumb sticking up, and your fingers curl the way it will rotate, yes? Good, try it, rendering at 320x200, and look what happens at the edge of the box. See that? the image sort of goes through the box. POV-Ray does not stick an image on as if it were a label. Instead it makes each pixel in the image you use into a long thin oblong stretching back in the z direction, so when we look at the edge of the box, we see the sides of the far right hand column of these boxes. If this isn’t clear, increase the z length of the box by changing it to, for example box{<0,0,0> <2.5,2.5,2> OK. Get rid of the rotation, and set the box’s z dimension to .01 rather than .1 Next we need something to mount the painting on, before we frame it. This simply needs to be a larger square that puts a coloured border around the image. Since we wisely moved our image to the center, the mounting object can simply be a box the same size as the image’s box, and scaled up slightly. Because it is in the center, the scale command will expand it equally in all directions, making a nice even border all the way round. Make a new object like this #declare Mount=object{ box{<-1.25,-1.25,0> <1.25,1.25,.01> This box is also 2.5 on a side, but with the bottom left corner at -1.25,-1.25,0 , which, as you can see results in the center of the box being at 0,0,0 The box is so thin in the z direction, we can simply ignore it, and treat it as if it were a flat sheet. scale <1.33,1,1> //same as the picture.... scale <1.2,1.2,1> // ...only now a little bigger all round You see the first scale command here only stretched in the x axis, to change the shape of the mount so it is the same as the shape of the image. The next scale command then scaled that new same-size-as-the-image shape so that it was a little larger on the sides (scale x values up) and the top and bottom (scale y values up) Of course there is no point scaling in te z axis, we don’t really need the mount to be thicker than the image. texture{pigment{color rgb<.7,.7,.1>} finish {phong 1 phong_size 13} } } translate z*.0001 //to make the mount just behind the picture } object {Mount } The mount is also translated back a fraction, so it does not cover the picture. Exquisite. The frame is next. The frame is going to be a simple black square affair, but we can’t make it quite as easily as the mount, because the mount and picture have to be set back in the frame. If you look at a picture frame, the edges extend infront of the picture. The picture is inside the frame rather than stuck on top of it. So, we start with a box a little bigger than the mount, to give the frame size, but with thickness in the z direction. We then cut out a chunk from the middle, exactly the same size as the mount. We can then move the frame towards us without covering up the picture and mount. You’ll see what I mean when you type this in and render it. #declare Frame=object{difference{ box{<-1.35,-1.35,0> <1.35,1.35,.1>}// .1 bigger on each side box{<-1.25,-1.25,-.001> <1.25,1.25,.1>}// cutout same size as mount } // end of difference texture{pigment{color Blue} finish{reflection .5 specular .3 roughness .003} } scale<1.33,1,1>// to be same as picture scale <1.2,1.2,1>// to be same as mount translate z*-.07 // move frame forward } object {Frame } Notice the shape to be cut out (the second box in the difference) is very slightly bigger in the z direction. It sticks out toward us a little tiny bit. This is to avoid the membrane effect when differencing things that share a surface. The blue texture is temporary, since black doesn’t show up against a black background. We now have our three objects. We want to make then one object for convenience, and to use a bounding box. Get rid of each of the single object statements, and add this object at the bottom #declare Painting=object{union{ object{Frame} object{Mount} object {Picture} } bounded_by {box{<-1.35,-1.35,-.001> <1.35,1.35,.1> scale<1.33,1,1> scale <1.2,1.2,1> translate z*-.07 } } } object{Painting} The bounding box is simply a box the size of the frame, translated into the right place. So this is our picture. We want to put this in the room, so we need to make it into a .inc file. This means taking out all the lights and camera’s and all the unwanted things like the .inc files we used for this. Change you file so it looks like the one below and save it as piccy.inc #declare Picture=object{ box{<0,0,0> <2.5,2.5,.01>} texture{pigment{ image_map{gif "simple.gif" } } finish{phong .3 phong_size 5} translate <0,0,0> scale<2.5,2.5,1> } translate <-1.25,-1.25,0> scale<1.33,1,1> } #declare Mount=object{ box{<-1.25,-1.25,0> <1.25,1.25,.01> scale <1.33,1,1> scale <1.2,1.2,1> texture{pigment{color rgb<.7,.7,.1>} finish {phong 1 phong_size 13} } } translate z*.0001 } #declare Frame=object{difference{ box{<-1.35,-1.35,0> <1.35,1.35,.1>} box{<-1.25,-1.25,-.001> <1.25,1.25,.1>} // to remove error } texture{pigment{Black} finish{reflection .5 specular .3 roughness .003} } scale<1.33,1,1> scale <1.2,1.2,1> translate z*-.07 } #declare Painting=object{union{ object{Frame} object{Mount} object {Picture} } bounded_by {box{<-1.35,-1.35,-.001> <1.35,1.35,.1> scale<1.33,1,1> scale <1.2,1.2,1> translate z*-.07 } } } Remember to change the Frame color to Black, and make sure there are only #declared objects, not any objects in the scene. Good. Now get ahold of your scene.pov file and add the line #include “piccy.inc” to it, under the last #include statement there. Then go all the way to the bottom and add this object{Painting scale <.5,.5,.5> rotate y*-90 translate <0,0,0> } This last line includes the object Painting, scaled and rotated. The object Painting, as we know is about 2.5 units on a side, almost half as big as the whole room!!. Obviously it is going to need some scaling down, and of course the scale command always comes first. Also, when we were designing the painting, we had it facing us, in the z direction, so we could see it. Since we want it to lie flat against the wall, it will need to be rotated so that it is parallel with the side wall. Finally it will need to be translated into place. The rotation above is correct, but the scale and rotate are wrong. Try experimenting (with educated guesses) until the picture is positioned properly. Below is a guide on how to go about doing this. Comment out the line in scene.pov that makes the object Room appear in the scene. To begin, we just want to check that the painting is even in the field of view, let alone in the right place. Keep the object too big at first. If you can see part of it then you can get the positioning correct, and then worry about size later. THINK where it ought to be. The center of the room is at 0,0,0 and we need the painting hung on the left wall, near the corner, so it will need to go left (negative x) and away (positive z). Once you have got it somewhere near the left wall, render the Room object together with the Painting, to get things lined up. There is no need to render the whole scene each time. The POV-Ray command line option +ec (for End at Column) followed by a number will cause POV-Ray to only render each line as far as a certain number of columns. Try about +ec100 when using 320x200 resolution. To give you an idea, it took me about 15 minutes to get it in position, rendering on a pentium 60. When you get bored, or when you succeed, go on and see what I came up with. Of course there is no ‘right’ place for it, but use what I use, as it will make a difference later on. This is what I settled for. object {Painting scale <.15,.15,.15> rotate y*-90 translate <-2.49,1.5,1.4>} The scale value I arrived at by trial and error. The rotation we have discussed. We know that the center of the room is 0,0,0 and that the room is 5 units wide, so the left hand wall is at -2.5. by left hand wall, I mean the inside (visible) edge of the wall, so if we put the painting at the same place, it will be buried in the wall. Accordingly, It is placed just out from the wall, a fraction. The y and z amounts were simply trial and error. That’s the secret to POV-Ray (so now you know). I know you can’t wait to do the great outdoors, so that is what will come next. Essentially, the landscape outside will be a height_field, positioned just outside the window. Of course if we were doing the whole scene to scale, it should be an enormous great heightfield, positioned miles and miles from the windows, but there is no real need to keep the mountains to scale with the room, since in POV-Ray, unlike real life, there is no way to tell the difference between a big object far away and a small object nearby. Human eyes can work these things out with a combination of stereoscopics and intuition, but POV-Ray has only one camera and can’t see things in stereo. Height_fields A heightfield works like this. An image is examined, and each pixel in it made a point in space, so that the picture (a grid of pixels) becomes a grid of points. Each point is then moved up a varying amount according to it’s color (we’ll see how POV-Ray does this in detail, later). Then, the mesh of points is made ‘solid’ by connecting triangles between the points. By solid, I mean opaque - a height_field is still two dimensional, rather like an infinitly thin wrinkled piece of paper. It is worth knowing more exactly how POV-Ray does this. Firstly, as with an image_map, whatever the size of the image used, povray squashes it to a 1unit square. POV-Ray then examines the image file. The image file has something called a pallette, which is a list of all the colours used in that picture. These colours are numbered. In a gif file there are 256 colours, numbered 0 to 255. The higher the number, the higher the point in the heightfield. Number 0 is converted to a point with a y value of 0, and number 255 has a y value of 1. Thus the height_field fills a space about equal to a one unit cube. No problem, you think. Sadly, the way an image file numbers it’s pallette colours is often far from sensible. This is ESPECIALLY true of images generated in paint programs. this means that it is not easy to look at an image and see what the height_field will look like. Accordingly, many people when first using POV-Ray rush into Paintbrush and make some little doodle, and then expect to see it magically made 3d. If only it were that easy. You see, supposing your paint program has the color Black as pallette number 1 rather than 255, and supposing you background color is number 0. That’s not going to leave much of a height_field, the difference between 0 and 1. In fact, as it is, your height field will go from a y value of 0 in some places, up to a y value of 0.003 at the highest places!!. The long and the short of it is, don’t try and hand draw height_fields unless you know what you are doing. Programs such as fractint make pictures with nice neat palettes than move evenly from shade to shade, and if you have that program, fractals generated with the plasma algorithm make fine height_fields. If you don’t have that program, just use POV- Ray. Make a rendering of a flat plane with a texture, and use that as a gif (or targa) for your height_fields. The texture Jade works rather well, for a starter. I would use that method here, but different computers make textures slightly differently, owing to the way the random number generator works. That doesn’t matter too much just for textures, but it would be confusing if I was using a different height_field from the one you were using. So we’ll use the gif plasma3.gif, which should be in the samples directory of your povray directory. If not, it has been included in this package too!. Grab a copy of the tpl.pov file and make it look like this. #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} #declare Camera1= camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,0> } camera{Camera1 translate <0,0,-5>} #declare Terrain=object{height_field{ gif "plasma3.gif"} texture {Basic} } object{Terrain} Our height_field will be an object called Terrain. The only information given to POv- Ray here is that the file type is a gif, and is called plasma3.gif. You always have to say what type of file you will be using first. Call this file mounts.pov and render it. A small off-center lump. This is actually our heightfield filling a cube of space from 0,0,0 to 1,1,1. What we need to do is stretch it with the scale command, but first, of course, we need to put it in the center, so the scale command doesn’t move it. Change the last line to look like this: object{Terrain translate<-.5,-.5,-.5> scale <20,1,20>} The scale moves the center of the height_field to 0,0,0, and the scale stretches it in everything but the y direction. As a rule of thumb, if you are using heightfields for mountains and such, the y value is about 10-30 times greater than it needs to be. We could use scale<0,.02,0> to shrink the y value, but we would end up with a very small height_field. Anyway, render it now and see what happens. Oh Horror. The height_field has eaten the camera. We scaled it so much that the camera is now inside it somewhere. To remedy this situation, we move the camera back by changing line 15 to : camera{Camera1 translate <0,0,-15>} That moves us -15 in the z directionm which is toward you, out of the screen, so to speak. Although we scaled the height_field by 20 units, it is in the center, so it will expand 10 units in each direction, and there is no need to move the camera 20 units back. Try that and see what happens. Not a great improvement is it? We are looking at the height_field from sideways on, and it doesn’t look like much. You’ll notice a light strip near the top, where th light just catches it. It’s a very good idea to have the light source high up in the y axis when working with height_fileds, or else they start to look the same from underneath as they do from above, and pretty soon you have no idea what is going on! Anyway, the problem is we are going to have to look down onto the heightfield to see it properly, so the camera needs raising. If the camera is above the height_field, it doesn’t need to be so far back, so change it’s position to this: camera{Camera1 translate <0,3,-10>} And there we have it... beautiful rolling downland. Suppose you want mountains? No problem, just boost the y value by changing the scale from <20,1,20> to <20,3,20>. If you render this at 320x200 you will notice that the scene is in fact made of from hundreds of little triangles. This can be used to good effect, but it is far from realistic for our purposes. Luckily there is a way to get rid of them. Add the word smooth in the height_field statement like this #declare Terrain= object{height_field{gif "plasma3.gif” smooth} texture {Basic}} This will make POV-Ray calculate smooth triangles instead of flat ones. It takes longer but gives a better effect. Try it and see the difference. Not perfect, but worth the effort. We now want to find a good part of the height_field to use as our scenery. The window in the scene isn’t all that big, so it doesn’t have to be anything huge.. just a nice shape somewhere. This is a bit of a problem. I could move the camera around looking for a good angle, but in the main scene I’m commited to using the camera already there. Instead we can move the whole heightfield around. There is no point being to precise since I am going to have to re- adjust everything when it gets incorporated as part of the main scene, but for now have fun translating the heightfield around, and rotating it in the y axis. The other axes will tilt the heightfiled... probably not a good idea at this point. Also, try using different scales to get different effects. Below is what I finally settled on. object{Terrain translate <-.5,-.5,-.5> scale <20,4,20> // fairly bumpy rotate <0,-90,0> rotate x*-20 // this tilts the whole thing towards you translate <-3,0,-3>} The first rotate command simply spins the height_field around so I’m looking across it in a different direction. The second one tilts it up by 20 degrees, which makes it seem much more mountainous. Note that the order of these rotations is important. You can remove the second one and see the difference (but don’t forget to put it back in). What we need now is a mountainy texture. Open up t2.inc, our textures file and put this in: #declare MountTex=texture{ pigment{ granite color_map{ [0.0 color rgb<.2,.3,.1>] [0.3 color rgb<.2,.3,.1>] [0.3 color rgb<.4,.4,.2>] [0.6 color rgb<.2,.5,.3>] [0.8 color rgb<.4,.35,.2>] } turbulence .4 lambda .9 } finish{diffuse .9 specular 0 brilliance 1 metallic} } Why this texture? Well, you can’t really have one texture for mountains. They are covered in boulders, streams, snow, rock, trees, and too many things like that to describe in a mathematical texture. Ideally, I would grab a paint program and do a nice image map, but that isn’t what we’re interested in here. So instead I thought general green/brown sort of effect would do. We are using granite type color mapping because it produces patches of color (rather like bozo only more jagged) not stripes or swirls. The turbulence and such are pretty arbitrary. It’s hard to work out how they will affect granite textures (easier for marble textures) and there is only limited scope in randomly trying values. If you want to try some of your own, go right ahead. More important here is the finish. No shinyness on these mountains, it all get’s diffusely reflected, giving a matte look. The word metallic might look a little odd in there. All it does is make any highlights the color of the object, not the color of the light source. In other words, a shiny red thing with a white light will usually have a little white spot for the highlight. With the metallic keyword, it would have a pale red (pink) spot instead. This texture is used without any scaling. You may think it needs to be scaled down a little, in which case you should add the scale command in the file mounts.inc rather than the file t2.inc. That’s almost it, but not quite. We need to start thinking about putting this in the scene. You can’t have the mountains just hanging in nothingness. We could use another height_field for the low ground around them, perhaps, or else put them so near the window, or so big that they fill it right up. Instead, we are going to resort to an old cliche (for once) and embed them in a bright blue sea. We are also going to make a new object to incorporate all these rotations and transformations. This mounts.pov file needs to be made a mounts.inc file for use in scene.pov. It should look like this in its final form. The lights, camera’s and #includes are commented out for the .inc file /* #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} #declare Camera1= camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,0> } camera{Camera1 translate <0,3,-10>} */ #declare Terrain=object{height_field{ gif "plasma3.gif" smooth} texture {MountTex} } #declare Mountains=object{union{ object{Terrain translate <-.5,-.5,-.5> scale <20,4,20> rotate <0,-90,0> rotate x*-20 translate <-3,0,-3>} plane{y,.15 texture{Water scale<2,2,2>}} } } The plane is a y plane, that is with its normal sticking up along the y axis. It is translated up a bit, to leave some mountain showing above it. It uses the Water texture found in textures.inc, scaled a bit larger (to make the ripples larger). The object Mountains can be thought of as a flat plane with a bunch of hills sticking up out of the middle. Time to move it into scene.pov, but first you might like to uncomment the camera etc. and have a look at the Mountains object in it’s own right. You’ll need to add the line object{Mountains} of course. Positioning this is much easier than doing the painting, since the position does not have to be nearly as exact. But, we do have to remember that our outside light in scene.pov is a long way from the center. Accordingly, if we put the mountains near the house, the light will actually be behind them, and they will be very dark. So they need to be positioned at about 1000 in the z direction. They will need to be scaled up accordingly, too. Once again, start off by commenting out the room and any other objects, until you can see the mountains in the center of the screen, and quite small. Then add in the room object, and use the +ec +sc +sr +er switches when rendering, to just render the part of the room with the window. When you think you’ve got it, have a look at what I used. object{Mountains scale<50,100,50> translate<0,-20,900>} Notice that they are also lower than the room. This makes the islands stand out more from the mountains behind. The island are of course just the tops of the mountains where they rise above the water. I have doubled the y scaling, which makes them look almost too mountainous to be real, but surrealism is fun too. You can leave the scaling at <50,50,50> if you prefer. I have not translated them all the way back as far as the light, so the light is shining behind them a little. This makes the shadows a bit more distinct. Ok, so they look odd with a black sky, but that’s good enough for now. Now we are going to have a brief look at cameras. Why? because as I was developing the scene, I started to get serious perspective problems. You may have noticed something odd in the way the squares on the floor seem to get longer in the foreground. That is because the camera we are using is in effect a fisheye lens. Let’s take a look at scene.pov again. #declare Camera1= camera{ location <0,0,0> direction <0, 0, .51> up <0,1,0> right <1.33,0,0> look_at <0,0,0.001> } [Our lightsources defined here] camera {Camera1 translate <-.8, 1, 0>} It’s the direction word that is important here. There is a positive value in the z axis of the direction vector (the vector just being those three numbers inside the <>‘s). The fact that it is the z axis simply means that the z axis is going to be the one that goes into and out of the screen. Some programs, especially CAD programs have the y axis going into and out of the screen, and the z axis going up and down. If we wanted to be like that, we would have direction <0,.51,0> but, we don’t, do we? In any case, if I were you I’d keep it in the z slot at the end there. More important is it’s value. A value of 1 is ‘normal’. Normal is meant to mean ‘like the unaided human eye’ although the field of view seems to be less. Values greater than 1 result in a zoom lens effect, like a telescope. Values less than 1 result in a fisheye or wideangle lens effect. .5 is about as fisheyed as you can get without hopeless distortion of foreground objects. We can see just how all this works by adjusting the camera in our scene. First though, we’ll move it back to the back wall of the room, keeping the distance value the same, to see what happens. Change the camera line to look like this, and render the scene. camera {Camera1 translate <.8,1,-2>} Look at that.. you can see the whole room!!. Now change the direction value in the definition of Camera1 to this direction <0,0,.6> See that? Now play around with the value to see how we can zoom in and out of the scene. Good isn’t it? When you are finished with that set the value to .91, and you’ll see that we are almost back were we started, but with much more realistic perspective. We have moved the camera back, and changed the distance value, to end up with the same field of view, but better perspective. Now, if you were rendering your room with the painting hanging in it, you’d notice that it’s looking a little out of place there. We’ll need to change it’s location again. Instead of trial and error, I’ll cheat and tell you where to put it. Change the line object {Painting scale <.15,.15,.15> rotate y*-90 translate <-2.49,1.5,1.4>} to object {Painting scale <.3,.3,.3> rotate y*-90 translate <-2.49,1.3,1>} What we’ve done is double the size (scaling down by half as much) and moved it towards us (translated by only 1 in the z direction, not 1.4) and moved it down. Ok, that’s that sorted out. Next, we move on to some serious constructive solid geometry. The next thing we have to do is start adding some furniture to the room. The edge of the window is looking distinctly bare. Just having a cutout isn’t very interesting, so we need something to liven the place up. We’re going to add two pillars either side of the window, to break up that harsh line. Pillars are easy to define on their own, and of course we only have to design one of them to have two objects, since we can just add as many pillar objects as we want. The scene file for the pillars looks rather daunting, but read the comments before and after each little piece, and everything should turn out fine. Start off with the tpl.pov file, as usual, and make it look like this: #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object {light_source <10, 5, -10> color White} object {light_source <5, 15, -10> color White} #declare Camera1= camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> } camera{Camera1 translate <1,4.5,-4>} This simply sets up a couple of lights and a camera. The camera is positioned up a little, because the pillar will be tall, and we want to see more than just the base of it. The first part of this pillar that we are designing is a decorative ring of spheres and cones that will go around the top. The pillar will be a square pillar, so we need four of everything, once for each side. The first thing then, is a row of spheres and cones stretching away along the z axis. This will be the left hand side of the pillar. It is called DecL for DecorativeLeft. #declare DecL=object{union{ cone{<0.1,-.05,.2> .05 <0.1,.05,.2> 0} The first cone goes from -.05 to .05, starting with a radius if .05, and ending in a point (radius 0). Its radius is half as much as the height, which makes it a fairly fat cone. It’s x position is .1 to the right of the origin, leaving a little gap. Think of this cone as just a touch to the right and behind the bottom near left corner of your monitor, with its’ center along that bottom edge. Now we’ll have some more cones stretching away towards the back of the monitor. cone{<0.1,-.05,.4> .05 <0.1,.05,.4> 0} cone{<0.1,-.05,.6> .05 <0.1,.05,.6> 0} cone{<0.1,-.05,.8> .05 <0.1,.05,.8> 0} Here we have more of the same, only the z values progressing higher in jumps of two, getting further away. There are four cones in all. The spheres are going to be just the same, with their centers at y=0, only they will fit in between the cones, so their z values will be the odd numbers, not the even numbers. The file continues.. sphere{<0.1,0,.1> .05} sphere{<0.1,0,.3> .05} sphere{<0.1,0,.5> .05} sphere{<0.1,0,.7> .05} sphere{<0.1,0,.9> .05} } } There are five spheres, like the fingers of a hand, and four cones between them, in the gaps. The first and last spheres are at z=.1 and z=.9 respectively. This is .1 away from the next unit, the same spacing as the whole line from the z axis (x=0). The first sphere is just .1 inside and to the right of your bottom left corner of the monitor there, and the last one is the same amount to the right and just inside the back left lower corner. Now we have this row, it won’t be too hard to copy it three times so that a row of little objects runs across the front, back and right hand sides of your monitor. Then we’ll have a little ring of decoration to put around our pillar. The right hand side is easy. All we have to do is translate the left hand side across. Note that we only go .9 across, to leave that .1 gap all around. #declare DecR=object{DecL translate x*.9} Now, it’s that .1 gap that causes us problems for the next one. To do the front, you’d think we just want to rotate the origin al by 90 degrees around the y axis. But the corner of our row isn’t exactly on 0,0,0. First then, we move the row back to the origin with a translate command, then do the rotation, and then translate again, to get our 0.1 unit border back. #declare DecF=object{DecL translate <-.1,0,-.1> //back to origin rotate y*90 //easy rotation translate <.1,0,.1> } And finally, another simple translation for the back. #declare DecB=object{DecF translate z*.9} #declare DecRing=object{union{ object{DecL} object{DecR} object{DecF} object{DecB} } } And then make all four sides into one object. A ring with the left near corner (almost) at the origin, and stretching 0.5 up and down either side of the x axis. If you like you can make an instance of this object (we’ve only #declared it, not yet put it in the scene) and render to see what it looks like. Try rotating it about a bit to get a sense of it in all three dimensions. Now the next thing is quite similar. A little border of four cylinders to make a different sort of ring around the pillar. The difficulty is that cylinders don’t join very neatly at the ends. What we need is a cylinder that has been cut down with a nice 45 degree corner, so that it fits into a square. We’ll make one of these, and call it Bevel. #declare Bevel=object{intersection{ cylinder{<0,0,0> <1,0,0> .1 translate z*.1} Here is a simple cylinder one unit long, radius .1. The translation moves it back .1, so that it’s outside edge lies on the axis, rather than it’s center. Imagine it being created so that the back edge of you keyboard (don’t worry, we’ll go back to using your monitor in a minute) ran through its center. It is then moved back so that it just touches the back edge of the keyboard, as if it had been placed against it. This is very important. Why? Well, read on. plane{z,0 rotate y*-45 } plane{z,0 rotate y*45 translate x*1} You’ll have noticed that we are dealing with an intersection object here. The final object will be that which lies inside all the ones specified. So far that’s just a cylinder. Now, place your left hand, palm toward you along the back edge of your keyboard. Move you hand to the left a little, until the back left corner of the keyboard digs into your palm. Your hand now represents a z plane. The z axis here is the left hand edge of the keyboard, and it runs straight through your hand. Rotate you hand by -45 degrees in the y axis, so that you fingers move away from you. Great, there’s the plane as it appears in the scene file above. Now then, anything from your palm, toward you will be included in this intersection object, and anything else will be excluded. Now just imagine that cylinder with its left end aligned with the left edge of the keyboard, and its near edge alighned with the back edge of the keyboard. Why, that plane is going to neatly chop off the corner. Now suppose the cylinder had its center aligned with the back edge of the keyboard... There would be a little bit of the left hand end that was inside you palm, and would get included. No good at all. The second plane is rotated in the other direction, and then moved over to chop off the right hand end of the cylinder. Imagine then we now have a cylinder with bevelled corners. } bounded_by{cylinder {<0,0,.1> <1,0,.1> .11}} } And last of all a bounding cylinder to speed up rendering. Note that it is a little larger than the Bevel object, just for safety. For the final object, go through each rotation/translation in your head, and make sure you understand. Because this is no longer symetrical, copying it into the other three positions will be a bit trickier. #declare Border=object{union{ object{Bevel} That’s the original one, which will be the front part. object{Bevel rotate y*90 translate z*1} This will be the left hand one, rotated and then moved back into position. object{Bevel rotate y*180 translate <1,0,1>} This is the back one. object{Bevel rotate y*-90 translate x*1} And this is the right hand one. Finally it will be scaled, but first moved so that the origin is in the center of the four edges (the first translate) and afterwards moved back so that the near left corner is at the origin. The scale command reduces the y value of the ring, simply because it looks better when it’s been squashed, and the x and z scalinf expands the ring outwards, so that is goes beyond the square stretching from 0,0,0 to 1,0,1 . The Main pillar itself will be essentially an oblong with a square cross section with a one unit side. The DecRing fits around this rather like a ring on a finger, so we want this ring to be wider than the pillar. translate <-.5,0,-.5> scale<1.2,.7,1.2> translate<.5,0,.5> } } Now would be a good time to actually build the pillar itself, and have a look at all this in the flesh, as it were. #declare Pillar=object{union{ box{<0,0,0> <1,5,1>} This is the main partr of the pillar, a simple box stretching from the floor, at 0, to five units above the floor. box{<.1,5,.1> <.9,5.75,.9>} This box is the next section, where the DecRing will go. It carries on from a height of 5, up to a height of 5.75, but it is narrower than the first part. This little box will actually fit inside the DecRing, and the DecRing will fill up the gap, so it is flush with the main part of the pillar. object {DecRing scale <1,7,1> Scaled to by 7 to fill up the .75 unit height of the space set aside for it. We defined it as only .1 high (stretching .05 up and down, remeber? ). But of course the scale is scaling it in both directions, away from 0,0,0. Now we need to move it up so that the center of the DecRing is in the center of the space provided for it. So... translate y*5.375 } Then, to make a nice join with the rest of the pillar, a little border above and below the DecRing. The top of the first part of the pillar is at a height of 5. We need the border just below that, so that the top of the border is at 5. Remeber the border is #declared with its center at 0. Then we want another instance of the border at the top of the DecRing. object {Border translate y*4.9} //bottom of the DecRing minus its own hight object {Border translate y*5.8} } bounded_by {box{<-.25,-.01,-.250> <1.25,6.3,1.25>}} // last box co-ord from //topPiece, extra room for Border, etc, firsty co-ord eliminates //problems } Now add the line object {Pillar texture{Basic}} and we can see what it looks like. Two problems spring to mind. firstly, there is no top to our pillar, it just sort of ends. Secondly, the big lower section looks very plain compared with the intricate bit at the top. The solution to the second problem comes first. All we need to do is subtract grooves from the main pillar to give an effect of fluting. It will just give it a bit more texture and variation. Add these lines BEFORE the declaration fo the Pillar object. #declare Flute=object{union{ cylinder{<.2,.5,0> <.2,4.6,0> .05} sphere {<.2,.5,0> .05} sphere {<.2,4.6,0> .05} } } Here we have a thin cylinder that stretches from .5 to 4.6 Note that this is shorter than the main pillar from which it will be extracted. It would look odd if the fluting ran right to the floor, and right up to the top. On the end of the cylinder are two spheres. This will give the fluting smooth ends. #declare Fluting=object{union{ object{Flute} object{Flute translate x*.2} //first on is .2 left, so this ends up //at .4 left object{Flute translate x*.4} object{Flute translate x*.6} } bounded_by{ box{<0,0,0> <.85,4.65,.1>}} } Here we have a row of four of these going across the face of the pillar from an x position of .2, where the first one was #declared, up to .8 (.2 translated by .6 = .8). This leaves a .2 border on either side of the one unit box that is the main pillar. Finally this row is bounded by a narrow box, that is .1 thick to contain the cylinders diameters, and goes to .85 to include the flute at .8 AND it’s radius of .5, and goes up to 4.65 to include the top of the cylinders (4.6)AND the .05 radius of the spheres on the end. The box doesn’t really need to start at 0,0,0 (it could start at .15,.15,0) but better safe than sorry. You may have noticed that the flutes extend -.05 in the z direction, and yet the bounding box only starts at a z value of 0. This does indeed cut off half the flutes, but then that half is not the bit that will be subtracted from the main pillar, so it makes no difference. It is only the part that starts at 0 and goes back that will be taken out from the Pillar, since the Pillar only starts at 0,0,0. Now that we have done this, we’ll need to subtract them from the front of the main pillar. Change the Pillar definition to begin like this... #declare Pillar=object{union{ difference{ box{<0,0,0> <1,5,1>} object{Fluting} } box{<.1,5,.1> <.9,5.75,.9>} etc etc etc Slightly harder is the top part of our pillar. I am thinking of a shape that widens at the top, rather like an upside down pyramid, only with curved sides. We need to start with a big block, and then take the curved shapes away from it to make it narrower at the bottom. #declare TopPiece=object{difference{ box{<-.25,5.75,-.25> <1.25,6.3,1.25>} // some straight left at top // note 5.75 start of curve Here is a block starting at 5.75 where the DecRing ends, going up to 6.3. It is .25 larger on each edge, making its total width 1.5. Below are four cylinder that will be taken away from the block for each of the four sides. The cylinders have a radius of .5, and their centers all have a y value of 5.75, where the bottom of the block is. They are all translated .5 away from the block. This means that there will be .25 shaved off the base of the block, which as we know is .25 bigger on each side than the main Pillar. The net result is that the base of this block is flush with the main Pillar. All will be clear when you render it, believe me! cylinder{<-10,5.75,-.25> <10,5.75,-.25> .5 translate z*-.25 } //front cylinder{<-10,5.75,1.25> <10,5.75,1.25> .5 translate z*.25} //behind cylinder{<-.25,5.75,-10> <-.25,5.75,10> .5 translate x*-.25} //left cylinder{<1.25,5.75,-10> <1.25,5.75,10> .5 translate x*.25} //right } bounded_by{box{<-.25,5.75,-.25> <1.25,6.3,1.25>} } } We now need to add this object to the Pillar definition, like this: #declare Pillar=object{union{ difference{ box{<0,0,0> <1,5,1>} object{Fluting} } box{<.1,5,.1> <.9,5.75,.9>} object{TopPiece} object {DecRing scale <1,7,1> translate y*5.375 } object {Border translate y*4.9} //up to bottom of cutout minus its own //height object {Border translate y*5.8} } bounded_by {box{<-.25,-.01,-.250> <1.25,6.3,1.25>}} /* last box co-ord from topPiece, extra room for Border, etc, first y co-ord eliminates problems */ } And we have added a bounding box for the whole big thing. Now it is time to include this in our scene. First, comment out any #includes and camera and lights, and any lines that actually render objects, and save this file as pill.inc. If you’re not sure, you can look in the appendix to see the final version of the file.Then add the line #include “pill.inc” near the top of scene.pov, and add these two lines at the bottom: object{Pillar scale<.2,.37,.2> translate <-1.6,0,1.75> texture {PaintTex}} object{Pillar scale<.2,.37,.2> translate <-.1,0,1.75> texture {PaintTex}} // translate x value -1.5 for width of window frame // pillars scaled down, but stretched in the y axis to make them taller. Then if you render scene.pov you will see how much better that looks! Now that our room is looking more respectable, we can add some more interesting lighting. We need a spotlight to light up our picture. If the spotlight is on the opposite side of the picture, we will get a nice beam running across the scene. Spotlights in POV-Ray don’t actually have visible beams. When you see the beam of headlights at night, what you are seeing is a cone of light reflected from particles of dust in the air. If we were completely mad we could model a zillion tiny dust particles and fill the room with them; alternatively we can employ a little deception. Read on to find out just how. Before we do the spotlight beam, however, we need to model the spotlight itself. This won’t be a terribly complex affair, just enough to look reasonable. It will be essentially a cylinder (hollow) with a few flaps (like film studio lights) and a bracket to fix it to the wall. The only difficulty might be in orienting it in the main scene. We must be careful, therefore, to make it so that it can be rotated and tilted easily. Otherwise getting it to point at the picture will take forever. The basic light, then, will be defined as a cylinder pointing right along the x axis, with the closed end at 0,0,0. The closed end will be rounded off with a sphere. Open up yet another copy of tpl.pov and start editing it to look like this: #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} object{light_source{<10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } The Body will be the difference between a cylinder rounded off with a sphere, and another, slightly smaller, cylinder rounded off with a sphere. Net result; a hollow cylinder rounded off with a hollow sphere. The textures are temporary, but notice that the first (big) part has a blue texture, and the second part (that is taken away) has a white texture. The result is something blue on the outside and white on the inside. The blue colour is arbitrary. The white will help give the idea of light inside the object. #declare Body=object{difference{ object{union{ cylinder{<0,0,0> <1,0,0> .25} sphere{<0,0,0> .25} } texture{pigment{color Blue}finish{Dull}} } object{union{ cylinder{<0,0,0> <1.1,0,0> .2} //difference probs sphere{<0,0,0> .2} }texture{pigment{color White}finish{Dull}} } } bounded_by{cylinder{<-.25,0,0> <1,0,0> .25}} } And then the whole lot in a bounding cylinder. Notice that the bounding cylinder runs from -.25 to 1 to incorporate the radius of the sphere who’s centre is at 0. Feel free to render the scene at any time. Indeed if you are on a fast machine, it is worth rendering every time you make a change to the scene. The next change we will make, is to add some vents, like little slits, in the body of the light. This is partly for realism- you may have noticed powerful spotlights get very hot and need cooling vents to allow air circulation- and partly for another altogether more devious reason, which I won’t reveal until later. However, all we really need now is a ring of narrow boxes that will be taken away from the main body, like this: #declare Vents=object{union{ box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}}} box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}} translate x*.2} box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}} translate x*.4} } } The location of these boxes may be a little hard to work out, but think of it like this. The cylinder for the body, viewed from above extends from 0 to 1 in the x axis, and from -.25 to .25 in the z (and y) axes. The first box extends from .14 to .15 in the x axis. In other words it is very narrow, extending only a little way along the length of the light. In the z axis it goes from -.15 to .15, and so keeps some way inside the edges of the cylinder. The height, finally, extends far beyond the cylinder in either direction. When this shape is cut out of the main body, it will leave a slit in both the top and bottom of the cylinder. Since this object is white, the sides of the slit will be white too. The other boxes in the Vents object are simply copies of the first, moved further down the length of the light. The best way to see what this looks like is to render it. We need to subtract the Vents object from the Body object, which is easy since the Body object is essentially a difference object. Add this to the definition of the Body, just inside the last bracket: object{Vents} Render that and have a look. I do hope I don’t need to tell you that the #declare for the Vents object needs to go BEFORE the #declare for the Body object, since the Body object now includes the Vents object. If you accidentally typed it in after the Body object, you’ll have to move it. When you’ve finished rendering that to have a look at it (I suggest having a look from various angles) we can start work on the flaps that will go on the end. All they are four very thin boxes, like sheets of metal, that will perch on the open end of the light. First we make one box to represent one very thin sheet. #declare Flap=object{ box{< 0 ,0 ,-.25> <.01,.30,.25>rotate z*-45 translate<.95,.25,0>} } The first flap we do is the top one. It is defined from the origin, even though it will eventually be at the other end of the body. This is, of course, because we will want to rotate it. So, a box starting at -.25 in the z direction. This is in line with the edge of the cylinder, extending .25 out from the x axis. Look at the bottom near left corner of your monitor. Move .25 towards yourself. That’s the starting corner for the box. Now we look at the second corner. The change in the x axis is very small. This is the thickness of the sheet. It is .3 high, and of course the far corner is in line with the far edge of the cylinder at .25. Then the key part, which is the rotation. At the moment the flap sticks up at right angles to the spotlight, which looks a bit odd. We are going to rotate it so the top comes down to the right, and it is partially closed. Finally, it needs to be put in the right place. First, it slides to the right so that it is at the lit end of the spotlight (it would look very silly other wise), and secondly it goes up by .25. Why? Because the outer edge of the light is at .25 (radius .25, remember), and our flap is currently sitting at 0, for rotation purposes. If we didn’t move it it would be inside the cylinder. To take a look at this we’re first going to create a new object called SpotL: #declare SpotL=object{union{ object{Body} object{Flap texture{pigment{color Yellow}}} } } object{SpotL} Render the scene now, to get an idea of what this Flap object is doing. We need three more of these flaps to make it look right, each one on a different side. Add this new object. #declare Flaps=object{union{ object{Flap} object{Flap rotate x*90} object{Flap rotate x*180} object{Flap rotate x*270} texture{pigment{color Yellow}} } } Note that if you want to change the openness of the flaps, you need only change the one rotation value in the object Flap, to change how open all the flaps are. Change SpotL so that it includes the object Flaps instead of the object Flap, and we have a more or less finished spotlight. All we need is a bracket to fix it to the wall. This can be a very simple affair, since it will be mostly hidden by the light itself. #declare Bracket=object{union{ cylinder{<0,0,0> <0,-.5,0> .07} This cylinder runs from 0,0,0 (near the back of the spotlight) downwards... a vertical post cylinder{<0,-.5,0> <-1,-.5,0> .07} This runs from the bottom of the post back to -1 in the x direction, where the wall will be. sphere{<0,0,0> .1 scale <1,.7,1> translate y*-.5} } This sphere sits at the intersection of the two cylinders to tidy up the join. It has been squashed to make it a more interesting shape. Because of the scale command it has to be defined at the origin and then translated down to where the two cylinders meet. texture{pigment{color Blue}finish{Dull}} } The pigment is arbitrary. We now need to make a subtle, but key, alteration to the object SpotL. We will be wanting to position this spotlight in the scene so that the end of the bracket sticks into the wall. But then we will need to rotate the spotlight itself independently of the bracket. When you install a spotlight in your home you bolt its bracket square to the wall, and then swivel the spotlight to the correct position. You don’t keep the light neatly lined up with its bracket and then bolt the bracket to the wall at a funny angle. We will do the same as you would in your house. The SpotL object needs to think of the body and flaps as independently moveable things. Change it to this: #declare SpotL=object{union{ union{ object {Body } object {Flaps} rotate z*0 // up/down rotate y*0 // across } object{Bracket} } translate x*1 //to make the end of the bracket at 0. } We have added another union inside the main union, and the rotate commands only apply to this one, not to the whole object. I have also added the bracket object as part of the SpotL object. You’ll have noticed of course that the spotlight rotates around 0,0,0 as it should. But because of this, the end of the bracket is at -1 in the x axis. This doesn’t really matter, but when we position the light in the room, we’ll want the end of the bracket to neatly line up with the wall. For that it would be nice if the end of the bracket were at 0, so the whole object is finally translated to the right. This translation comes after the rotations, so rotations take place at 0,0,0 and are then translated to the right, which is hunky-dory. It’s time to move the light into our scene. We want to turn this into an include file, so comment out all the #includes, cameras, lights, and instances of objects, and save the file as spotty.inc. The astute amongst you may have noticed that there isn’t actually any light in our spotlight yet, but that will come in good time. Open up the file scene.pov, add the line #include “spotty.inc” Under all the other include statements. At the very end of the file add the line: object{SpotL rotate y*90 scale<.3,.3,.3>translate<1.3,2.6,2>} The rotate is of course very necessary, since we originally defined our light facing right, and we are putting it on the back wall. The rotate makes the light face straight at us, and so the bracket sticks out behind at right angles to the back wall. We can now rotate the light by editing spotty.inc. Indeed, since it wants to be pointing at the picture on the left hand wall, it will need to be rotated a good deal. First, render scene.pov so you can see just where we stand. I suggest you go and make a cup of coffee or something and then come back to this. Well, the spotlight is facing straight at us, and the picture is on the left hand wall. so the light will have to be rotated by almost 90 degrees to the left. That’s the normal (positive) y rotation. The light is also a little higher than the picture, so it will have to be tilted down, a rotation of a few degrees. This will be a z rotation, because the light is defined looking right. It only looks straight at us because of an extra little rotation when we stated it in the scene.pov file. It does, of course, matter which one of these we do first, and we do the x rotation first. If you can’t see why this is, try a little experiment. Put you elbow on the desk so it sticks up. Point your finger at you chin. The finger represents the direction of the spotlight. Without poking yourself in the mouth, bend you arm toward you so that you finger points down. That’s the tilt. Then twist your wrist over to the left. That’s the turning. Your finger is pointing down and to the left. Now, return to the original position and point you finger over to the left again. (If you’re trying this in the office you should be getting funny looks by now. There are already some folks here in the computer lab looking at me and whispering.) Then , when you bend you elbow, the finger just moves toward you in an arc. It doesn’t really point down. Ok. enough of these games. In spotty.inc you remember we typed in two lines for angling the light in the SpotL object. Change them to look like this. rotate z*10 // up/down rotate y*85 // across The net effect of this should be apparent if you render the scene. You can do that now if you like, or, wait and add some actual lights to our light, which is what we do next. We are going to use a feature of POV-Ray that allows spotlights to be easily implemented. Theoretically you can make a spotlight just by putting a normal light inside a cylinder with a mirrored interior, but due to the way POV-Ray calculates rays, this won’t work too well. We are going to make an object called Bulb which we’ll add to the object SpotL. In spotty.inc add these lines before the definition of SpotL. #declare Bulb=object{light_source {<.8,0,0> color White spotlight point_at <1,0,0> radius 7 falloff 11 tightness 50}} Let’s take a look. The light_source is placed at <.8,0,0> which is just inside the mouth of the spotlight. The end of the spotlight is at 1,0,0. It is a white light, normal brightness. Then comes the word spotlight which tells POV-Ray to make the light into a beam that has the following properties. point_at is the point in space the beam should be directed at; it is often nice to simply give the co-ordinates of the object to be lit, and save the trouble of aiming the beam. Since we have to position the actual spotlight thing, as well as the lightsource, this won’t help us much. Instead we want the beam to come straight out of the spotlight in line with the cylinder body of the light, so point_at is simply any point directly in front of the spotlight. radius is the radius of the beam of light. Imagine the beam as essentially triangular. this number is HALF the angle at the pointy end of the triangle where the light starts. Refer to the manual for more information on why this is. Anyway, the triangle of light defined by the radius will be all coloured white, the color of the light_source. It will produce a spot of light, literally. Real spotlights usually have blurred or faded edges, which is where falloff comes in. falloff is another angle defining a triangle. Again, it is HALF the angle at the top of the triangle. The outer edge of this new triangle will not be lit at all. The inner part will be lit fully. Thus the falloff radius defines how wide the area of fade around the spotlight’s ‘spot’ should be. tightness indicates how quickly the light should move from full power to no power within the falloff area. More tightness means a tighter spot, less means a fuzzier one. So.... Add the Bulb object to the SpotL object like this: #declare SpotL=object{union{ union{ object {Body } object {Flaps} object {Bulb} etc...... etc.. and render away. Marvellous. A spot of light not quite pointing at the picture. If you like you can play around with those two rotations until it comes out right, or alternatively you can type in the values -20 (for up/down) and 80 (for across). Now alot of people would leave it right there, but not us. Many people think of the beam from a spotlight as being actually visible, not just the spot where it hits an object. In real life this effect is caused by the light reflecting from dust in the air. POV-Ray can’t model this effect, but we can cheat, by simply putting a cone of our own in the same place as the beam of light. It will of course have to be an almost transparent cone. In spotty.inc make a new object Beam, somewhere before the object SpotL. #declare Beam=object{cone{<.2,0,0>0 <100,0,0>16.5} texture{pigment{color rgbf<1,1,1,.95>}finish{ambient 1}} no_shadow } What have we here? A cone going from the spotlight out in front. It goes way out in front, since it must meet up exactly with the wall, and so must extend past the wall. It starts from near the back of the spotlight, since it would look unnatural to have the very sharp pointy end of a cone visible as the spotlight’s beam. The radius of the base of the cone is 16.5. Cones in POV-Ray are defined by the radius of their bases, whereas spotlights are defined by the radius of their upper angle. We want the cone the be the same size when it hits the wall as the spotlight spot. This can be worked out with either trigonometry, or trial and error. I promised not to use calculators in this tutorial, so 16.5 is the number I arrived at from trial and error. The texture is the important bit here. the color is defined with rgbf instead of just rgb, and has an extra number. The f stands for filter and determines how transparent the color is. In this case almost completely. The ambient 1 is also important, since other wise the cone appears lighter where the other lights in the scene hit it. Very odd indeed. Finally it is given the no_shadow keyword. This word is included in the object (not in the texture) and simply means that object will not cast a shadow in the scene. Now put this object in SpotL underneath the object Bulb. See what you think of that. Be warned... the Beam will greatly slow down rendering time, and should probably be left out, like the window glass, until the final rendering. And now for the coup de grace. An extra bulb that will cast lovely rays of light through the little cooling slits we put in the spotlight’s body. #declare Bulb1=object{union{ object{light_source {<.2,0,0> color White }} cylinder{<.7,0,0> <.71,0,0> .24 texture{pigment{color White}} } } } This is simply a point light source in the back of the main cylinder. However, if we only did that, the light would shine out of the front of the cylinder and make a big bright spot on the wall, messing up our nice spotlight. For this reason there is a little cylinder that blocks off the front of the spotlight from the back where the slits are. The cylinder is white to fit in with the interior of the spotlight. It’s radius of .24 is just less than the outer radius of the main cylinder (.25), so we may be sure it will completely block of the cylinder, without sticking out the sides. It is placed at .7. The Bulb is at .8, so it will still be able to shine out. Bulb1 is at .2, so it’s light will be blocked. Simplicity itself. Add Bulb1 to SpotL, and render away. Ok. One final niggling little error. The interior of the spotlight is white. But the spotlight light source doesn’t actually light the mouth of the spotlight, so it looks too dark. We need to change the definition of the Body object in spotty.inc to have a white texture with a higher ambient value, so it will glow, as if it were lit. #declare Body=object{difference{ object{union{ cylinder{<0,0,0> <1,0,0> .25} sphere{<0,0,0> .25} } texture{pigment{color Blue}finish{Dull}} } object{union{ cylinder{<0,0,0> <1.1,0,0> .2} //difference probs sphere{<0,0,0> .2} *************CHANGE THIS LINE BELOW********* }texture{pigment{color White}finish{ambient .7}} } } bounded_by{cylinder{<-.25,0,0> <1,0,0> .25}} } The final listing of spotty.inc can be found in the appendix. Next, we’ll have a bit more fun with textures, before the grand finale, so to speak. Well, what we need to add to the room is a little table which will support a couple of stands. The stands are going to be complex CSG affairs, but the table need only be quite simple. What will make all the difference is the texture, or rather textures that we use. POV- Ray has a feature known as material mapping that can be used to give a single object multiple textures. Essentially, it takes an image file (such as .gif or .tga) and looks at the palette numbers of the colours used. It then maps the image to an object the same way as for an image_map, but substitutes a different texture for each different colour in the picture. Because of this, when using material maps, as when using image maps, it is best to start with the object filling the space between 0,0,0 and 1,1,1, since this is where POV-Ray places the image map or material map. Using tpl.pov as a template, make a file called table.pov and type in the following. #include "colors.inc" #include "textures.inc" #include “t2.inc” #include "stones.inc" object{light_source{<0,100,-6> color White}} object{light_source{<50,5,-100> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,1,-4> } #declare Table=object{box{<0,0,0> <1,1,1>} texture{material_map{gif "matmap.gif" texture{Stone22 scale<.5,.5,.5>} texture{Gold_Metal} texture{Stone12 scale<.5,.5,.5>} texture{Stone4 scale <.5,.5,.5>} texture{Stone14 scale <.5,.5,.5>} } } translate <-.5,-.5,-1> scale <2,2,.1> } object{Table } I hope from rendering this you get an idea how the material map works. It is well worth making a note of which textures are getting used for which colours on the gif. Comment the scene file like this. It is just possible that the palette values you have are not the ones that I worked with. If this is the case, your image map may look a little different. texture{material_map{gif "matmap.gif" texture{Stone22 scale<.5,.5,.5>}//red texture{Gold_Metal}//blue texture{Stone12 scale<.5,.5,.5>}//green texture{Stone4 scale <.5,.5,.5>}//cyan texture{Stone9 scale <.5,.5,.5>}//black } What we are going to do next is make a texture for the central part of the image. In order to show up the gold coloured writing as well as possible it should be a dark colour, like black. Add this texture to the end of t2.inc #declare BlackStone= texture{ pigment{ granite color_map{ [0.0 color rgb<0.2,0.2,0.2>] [0.25 color rgb<0.1,0.1,0.1>] [0.4 color rgb<0,0,.05>] [0.8 color rgb<0,0,.1>] } turbulence .4 lambda .4 } scale<2,2,2> } This should make a black and grey granite. The important things here are that the greys are not the same, there is a gradient between a paler grey and a darker grey. It’s not much, but it makes a big difference. If you like, change them to be the same, and see how it looks. Also, you will see that the black parts are not really black, but have small amounts of blue, like a midnight blue. As usual there is alot of trial and error in the turbulence amounts. More important is the scale. I want the areas of colour to be large. Patches, not flecks of colour. For this reason I’ve doubled the size, and not made the turbulence too high. High turbulence tends to break the color map up and leave a ragged appearance. Replace the stone12 texture in table.pov with this texture, BlackStone, and render. This will give you an idea of how the table will look. However this texture is still far simpler and less effective than the other stone textures that we have used for the rest of the table. That is because the other textures are layered. In POV-Ray a single texture, like BlackStone can be made from several textures put on top of each other in layers. Of course if you do this, the layers will have to have some transparency in, or you won’t be able to see what is underneath them. With our texture we can add just one other layer on top that will be almost entirely transparent, but with a thin white streak. This will in theory give us a simulation of white veins in the granite. POV-Ray takes any textures given to an object an puts them on in the order they appear in the scriptfile. Therefore the first texture specified is the bottom layer. To add our second layer, just carry on typing, and add this. texture{pigment{ gradient x color_map{ [0.0 color rgbf<1,1,1,1>] [0.95 color rgbf<1,1,1,1>] [0.98 color rgbf<1,1,1,0>] [1 color rgbf <1,1,1,0>] } turbulence .8 omega .7 octaves 4 Basically, 95% of the colour map is transparent, rgbf<1,1,1,1> gives red, green, and blue values of 1 each, for whiteness, and a filter value of one for full transparency. Then there is a change from .95 to .98 where the colour moves from clear to opaque white. from .98 to 1 it stays opaque white. We have used gradient x type pigment rather than marble to give a hard edge to the vein. After it gets to 1 (White) it jumps back to 0 (Clear) with no blend. This is more interesting than a smooth marble. Render this and see what I mean. Now change the first value in the colour map to this [0.0 color rgbf<.8,.8,.8,1>]// darkens underlayer Although the filter is still full on, the colour is no longer pure white but a pale grey. This has the effect of darkening the texture underneath, and is much easier than changing all the colours in the previous layer. If you want to darken, or tint, a texture you can always add another layer that is slightly tinted, like ours (darkening is just tinting black). It remains for us to find the most interesting stripes for our texture. You may have noticed that the white veins are far too big. Scale them down like this: scale <.7,1.5,.2> This will also stretch them in the y axis and make them thinner. We also want them going diagonally, so rotate them like this: rotate z*-40 Finally we put in a translate command simply to find a more interesting part of the texture, and add a finish. There is no point putting a finish in for each layer of a texture, POV-Ray only takes note of the last layer’s finish. Later we may make our texture reflective, but not for now. translate <0,2,0> } finish{ specular .5 diffuse .3 /*reflection .35*/} } Now that we have our BlackStone texture, put it in the material map like this: texture{material_map{gif "matmap.gif" texture{Stone22 scale<.5,.5,.5>}//black texture{Gold_Metal}//blue texture{BlackStone scale<.5,.5,.5>}//green texture{BlackStone <.5,.5,.5>}//cyan texture{Stone9 scale <.5,.5,.5>}//red } Looks good doesn’t it? If you want an idea of how it will look in the picture, rotate it so that it is flat and move the camera up a little. Now comment out the #include’s and any objects so that it can be a .inc file, and rename it table.inc. Finally, we need the stands that will be on the table. This is going to be an exercise in well thought out csg construction. We will design the stands in such a way that each part (the clamp, the base, the arm) can be easily rotated, so that once one clamp is built, an almost identical scene file can be used for other clamps of the same kind in different positions. There will be basically three moving parts. The jaws will be able to move apart (or closer together, of course). The jaws will be able to swing left or right on the end of the arm. The arm will be able to tile up and down at the top of the vertical part. Of course the whole thing can be rotated in the y axis to turn it around, but that is just rotating the final object. Of course when we title the horizontal arm up and down, we want to make sure the jaws go up and down on the end of it. So, not only must the centre of the horizontal arm be at 0,0,0 when we rotate it, the jaws must already be defined, and sitting on the end as part of it. For this reason, we start defining from the smallest part. Imagine we are modelling an arm. We start with the fingers, because we need to think of the fingers as independently moveable things attached to the arm. We don’t want to thing of the arm as a big solid thing stuck onto the fingers! In other words, when we rotate the wrist, we need to think of it as the arm staying still and the wrist moving, not the wrist staying still and the hand moving. This is called a hierarchy of objects. The arm is the highest (or the parent object), and the vertical part of our stand will be the parent object. The parent object is made up of all the lesser objects, and I think it is much easier to define those lesser objects before doing the parent. There is no real reason why you shouldn’t #declare TheArm to be a union of Wrist, Finger1, Finger2, Thumb, etc, and then work out what the fingers are going to look like, but since in the scene file you have to say what Finger1 is before making an object like TheArm that uses it, I think it is better to define all the parts before deciding just how they are all going to fit together. Well, open up a new file called stand.pov and start it off with the textures that we’ll use for the stand. We won’t put these in t2.inc because these only apply to the stand, and they are not complex at all. #include "colors.inc" #include "textures.inc" #include "t2.inc" object{light_source{<0,100,-6> color White}} object{light_source{<50,5,-100> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> //1,3.5,-9 } These values here will be the amounts by which each of the various parts are rotated. By #declaring the words here at the beginning of the file, we can easily move our stand without having to search through the whole file for the place where the different parts are rotated and translated about. #declare BaseRot=-40 #declare Tilt=20 #declare Rot=0 #declare Gap=0 This first texture is a dull finish with bumpiness. It doesn’t simulate any real material, but it is meant to contrast with the next texture. It is mud coloured and dull! The bumps are very small (look at the scale of them) this is because we are defining this to quite a small scale. The whole thing is only 4 or 5 units long, and I want lots of little bumps in that. #declare S1Tex=texture{ pigment{color rgb<.3,.25,.25>} finish{specular .4 roughness .008} normal{bumps .5 scale<.01,.01,.01>} } This second texture is like polished brass. Bright and shiny. As you see I eventually opted for phong rather than specular specification. It is also reflective, so it will mirror other elements in the scene to an extent. #declare S2Tex=texture{ pigment{color rgb<.7,.7,.3>} finish { metallic ambient 0.1 diffuse 0.75 //brilliance 2 reflection 0.5 phong .8 phong_size 70 // specular .95 // roughness .007 } } Now it is time to think about the fist part of the object. We are doing the clamp on the end. It will be, basically, to thin fingers that slide up and down parallel to each other. They will need something to slide up and down on, and they will need to be attached to that. We are defining our stand with the cross arm going along the x axis, with the clamp on the right. //THE FIST PART WE DEFINE IS THE CLAMP ON THE END. IT IS CALLED THE CLAW. CP1 is claw part one, the top finger of the clamp. The finger itself is a very flat cone, only .15 high, but stretched along the x axis to become long and thin. It has a radius of .2, and is then scaled by 3 to become .6. This means that the cone extends .6 either side of 0 in the x axis, and .2 either side in the z axis, and is still .15 tall. The box and cylinder make up the little part that will join the finger onto the rest of the stand. The box is half as wide as the finger. The cone had a radius of .2 (ie went .2 either side of 0) and our box only goes .1 either side of 0 (look at the z values). It extends into the finger a bit, since the left end of the finger is at -.6 and the right end of the box is at -.2. The box then goes left as far as -1.3, making it 1.5 long in all. The cylinder is a flat disc the same height as the box and simply acts to get rid of the ugly square end of the box. It is situated at -1.3, on top of the end of the box. It is slightly larger in radius than the box. This is because there will be a long thin vertical cylinder running through this cylinder and its counterpart in the lower finger of the clamp. The long thin vertical cylinder will be a slide that the two finger ride up and down on. Finally, and very importantly the whole thing is translated by 1.3 along the x axis. This is because we will want to line up the cylinders here with the slide that they travel up and down on, and so we want them conveniently at 0. This part of our stand has the first texture. #declare CP1=object{union{ cone{<0,.15,0>0 <0,0,0>.2 scale<3,1,1>} box{<-1.3,0,-.1> <-.2,.05,.1>} cylinder{<-1.3,0,0> <-1.3,.05,0> .15} } translate x*1.3 texture{S1Tex} } If you were at all lost in the explanation above, now is the time to see what is happening. Just add the line object {CP1} and render. You may need to move the camera a touch. The Claw itself then is simply two of the fingers we defined above, together with a slide for them to move up and down on, and to hold them together. Simple. The first bit of trickery that may throw you here is that CP1 is used for the upper and lower part. That is because we can very easily make a mirror image of it using the scale command with a negative value. If you scale something by -1 it will be mirrored in that axis. Note that the space between the two parts is determined according to the Gap value that is defined at the top of the file. #declare Claw=object{union{ object{CP1 translate y*.3} //raises top part a little object{CP1 scale<1,-1,1> translate y*Gap} //translate //space between jaws The next part will define the slide that the fingers move up and down on. It is composed of two cylinders, the first of which has a sphere on each end for decoration. The first cylinder is narrow (thin) and stretches from .4 to -.7 in the vertical axis. It does not run through the ends of the CP objects, but actually runs through the middle of the box shape in the CP objects. This is supposed to be the adjustment pin in the clamp. The second cylinder is much taller, and wider, and runs through the ends of the fingers. Both these use the second, shiny, texture. That is because these are moving parts, as it were, and have been polished by years of use. object{union{ object{cylinder{<.5,.4,0> <.5,-.7,0> .035}} object{sphere{<.5,.4,0> .06}} object{sphere{<.5,-.7,0> .06}} } texture{S2Tex} } object{cylinder{<0,-1,0> <0,1,0> .045} texture{S2Tex}} } rotate y*Rot //rotate into place } Then this part too is rotated. Note that the big (second) slide cylinder is still at 0 on the x and z values, so we can easily rotated the claw object, with the effect that this cylinder stays still, and all the apparatus to the right of it(our CP objects, the little adjusting cylinder etc) will rotate in a graceful arc around it. The value Rot is used to determine this rotation. Now is an excellent time to see what we have made, so render away by making an object of the claw(ie add the line object{Claw}). Look at this object from a couple of angles so that you can see how it is put together. Next we do the CrossArm. This will have no independent moving parts, but will itself pivot on a central point. Needless to say the central point is going to be at 0, and the arm will extend either side. On the left side will be a counter weight to balance the claw apparatus on the other end. This balance is realistic, in a sense, but I really put it there for artistic balance. IT would look a bit odd with this lovely complicated clamp on one end of the object, and nothing at all on the other. The brute simplicity of the counterweight contrasts with the delicate construction of the Claw. Anyway, let’s take a look at this. // THE CROSSARM IS A HORIZONTAL CYLINDER WITH A PIVOT IN THE CENTER. #declare CrossArm=object{union{ cylinder{<-2,0,0> <2,0,0> .07} sphere{<0,0,0> .45 scale<2,1,1> translate x*-2 } box{<-.5,-.5,-1> <.5,.5,1> rotate z*45 scale<.15,.3,.8> texture{S2Tex}} Here are three of the four main objects. The cylinder is a great big horizontal cylinder extending 2 units either side of the centre. It has a radius that look right. The sphere is the counter weight. Its size (radius) was arrived at by trial and error until it looked as though it balanced the other end of the stand. It is then scaled to stretch it along the x axis, and make it a more interesting shape. Note that it, like everything I do, is defined at the origin and then translated to its place on the left end of the cylinder. The box is rather more complicated. What we need is some kind of pivot. The box has been rotated by 45 degrees, so that instead of its sides being parallel with the sides of the cylinder, it has its corners pointing up and down and left and right, like a diamond shape. This means the bottom corner will be a sharp edge for the arm to pivot on. To emphasise this effect the box has been scaled so that it is tall and thin. The scale command has made it smaller all round (the values are less that 1), but it is much smaller in the x axis than the y axis - net result, it’s taller and thinner. The scale has also made it quite long in the z axis. The box will stick out either side of the main CrossArm cylinder and rest on two brackets in the next part of the stand. The pivot (the box) has the shiny texture since it is a sort of moving part. The rest of the parts will get the dull texture (see below). cylinder{<3,.5,0> <2,0,0> .05} cylinder{<3,.6,0> <3,.4,0> .12} cylinder{<3,-.5,0> <2,0,0> .05} cylinder{<3,-.6,0> <3,-.4,0> .12} object{Claw scale<.8,.8,.8> translate<3,0,0>} } texture{S1Tex} rotate z*Tilt //tilt into place } //object{CrossArm translate x*-1} On the other end from the counter weight is the claw. However, we cannot simply put the Claw straight on the end of the arm. The four cylinders here will make a bracket to attach it. The first cylinder stretches from the end of the CrossArm (<2,0,0>, the second value) to a point past the end of the cross arm, and above it (<3,.5,0>) The second cylinder then sits at the end of this and runs vertically for a short distance. This short fat cylinder will hold the top end of the left-most cylinder of the Claw. The third and fourth cylinders do exactly the same thing for the lower end of the slide. It looks confusing, but don’t worry because any moment now we can render the crossarm and see how things look. The Claw object is scaled to a reasonable size, and translated out to 3 in the x axis, where the cylinders we just made will grip it’s slide. We then make everything dull, which will affect all the parts of CrossArm not already given a texture. The whole thing can now tilt about its pivot. Finally we will do the vertical part of the stand that hold the CrossArm and its clamp up in the air. This will have two parts. The top will be the bracket needed to hold the CrossArm, and then a long tall cylinder. The bracket is rather complicated. It is made from two half toruses, that act as cups, like the letter u. There is one either side of the CrossArm. These two u shapes are then held together by another u shape, running in the z axis. The object Cradle is just one of the halves of the bracket. It is a union of three objects. First, a torus cut in half by a plane, making a half-torus or u shape. Note that the total radius to the outside edge of the torus is .56 (.5 from centre of doughnut to centre of dough, then .06 from centre of dough to edge of dough). Second and third, a sphere to sit on each end of the torus to round of the edges. Owing to the great length of time taken to render toruses, this shape is bounded. It has a shiny texture on the basis that the pivot moves on it, and so polishes it. //THE CRADLE IS ONE HALF TORUS WITH SMALL SPHERES. TWO OF THEM WILL HOLD //THE CROSS ARM #declare Cradle=object{union{ object{difference{ torus{.5,.06 rotate x*90} plane{-y,0} } } object{sphere{<-.5,0,0> .1}} object{sphere{<.5,0,0> .1}} } bounded_by{cylinder{<0,0,-.2> <0,0,.2> .6}} texture{S2Tex} } So, the UpArm will have at the top a couple of these Cradle objects, and a further u shape to join them. We see the two Cradle objects, each translated .5 each way along the x axis. This is so that there will be one on each side of the CrossArm. But they are also translated .5 up. Why? Because the pivot must rest on the solid part of the torus, not the hole in the middle! A torus is defined by where its centre is, not where the solid part is, so we must move the whole thing up until the base of the curved part is at 0 where it will meet up with the pivot of the CrossArm, right? Wrong, in fact. Firstly, our torus now has the centre of the solid part of the torus at 0, not the edge of the solid part at 0. This means a pivot at 0 will be inside the solid part, not just touching the surface at the inside of the curve where we want it. However, the pivot is not at 0 anyway! The centre of the box that forms the pivot is at 0, because we put the box in the centre of the main cylinder that forms the CrossArm, but the corner of the box extends down from there. We are obviously going to have to move the whole CrossArm up a little to get the two parts to meet nicely, but that can wait. So, we now have the two Cradle objects in place. We need another shape to link them underneath. We could make another u shape using another torus (we could even re-use the Cradle object, just rotating it by 90 degrees in the y axis and moving it down a bit), but all those toruses would look boring. Instead we can make a u shape by cutting a hollow cylinder in half. Imagine sawing a 1 inch disk off the end of a drain pipe, and then cutting it in half to make a u shape. That’s what we will do. The first difference operation is making a hollow cylinder. First we specify the a cylinder running along the x axis, but only a very short distance, from -.1 to .1 You notice that the centre is therefore at 0,0,0. It has a radius of .53. This is important. It must join the two Cradles, and their centre are each .5 either side of 0, so the two arms of our u shape must be .5 either side of 0. The first cylinder is slightly wider than .5 so it can be thick, with the centre at .5. The second cylinder that we subtract is the same only with a smaller radius, .47. The result is a hollow cylinder whose wall is .06 thick (.53-.47=.06), and the centre of the wall joins the centres of the two Cradles. Of course you’ll have noticed that the second cylinder extends a little further along the x axis that the first. This is to get rid of those difference problems again. Then we cut the whole thing in half with a plane. This joining shape gets the dull texture. Finally, just a simple cylinder running from -.5 to -5.5. This is the tall cylinder that forms the big vertical part of the stand. It has the dull texture. Then we can add the CrossArm to this object, and, as you remember, we have to move it up so that the very edge of the pivot shape touches the edge of the Cradle shapes. The value here was obtained by trial and error. It works passably. the whole thing is then translated up so that the lower end of the vertical rod is at 0,0,0. This is to help with positioning on the table. We can now rotate this in the y axis to have the effect of rotating the whole apparatus from its base. This value is defined at the top of the file. #declare UpArm=object{union{ object{Cradle translate<0,.5,-.5>} //base of curve at 0 object{Cradle translate<0,.5,.5>} object{difference{ cylinder{<-.1,0,0> <.1,0,0> .53 } //smaller rim //than torus cylinder{<-.11,0,0> <.11,0,0> .47} plane{-y,0} } translate <0,0,0> texture{S1Tex} } object{cylinder{<0,-.5,0> <0,-5.5,0> .11}texture{S1Tex}} object{CrossArm translate y*.19} } translate y*5.5 //base at 0,0,0 rotate y*BaseRot// rotates whole } //object{UpArm} But there is one more part, the base at the bottom. At the moment the stand would fall over immediately, so we need a wide base. We could make a flat disc shape, but that would be boring, or we could use a cone, but that would look weird, so instead we can use the inside curve of a torus. It’s a bit difficult to imagine what that shape is, but imagine getting a torus shape and pressing it down into something soft like putty. The putty would be squeezed up through the middle of the torus into a cone shape with smooth curving sides, so that it splays out at the base. We will make this shape by the difference of a big fat cylinder and a big fat torus. Notice that the lesser radius of the torus is almost as big as the greater radius. This means that the hole in the middle will be very small, so the top of the base will be very small. #declare Base =object{difference{ cylinder{<0,0,0> <0,2,0> 1.5} torus{2,1.7 translate y*1.9} } texture{S1Tex} } Finally we combine the parts. The UpArm object already contains all the other objects, and the base is added to it. The base is made smaller, so it doesn’t look out of scale with the rest of the object. #declare Holder=object{union{ object{UpArm} object{Base scale<.5,.5,.5> } } } OK, now render the whole thing. You will probably have to move the camera around to get all of it in the picture, but there’s no harm in moving it close so that you can see parts in detail. Try experimenting with the various tilt and rotations, but set them back to what they were when you have finished. After you’ve had fun doing that, make this file into an include file stand.inc and remove all the usual parts (ie the camera/lights/#includes and any objects that are actually present in the scene). As usual a final version of stand.inc is in the appendix. Now that we have done one stand, doing another is simplicity itself. Make a copy of the file stand.inc and call it stand2.inc. Go into Stand2.inc and change the very last bit, above, to read #declare Holder2=object{union{ object{UpArm} object{Base scale<.5,.5,.5> } } } Now stand2.inc defines an object Holder2, which is exactly the same as Holder, except that we will position its bits and pieces differently. Change the relevant part of stand2.inc to look like this. #declare BaseRot=180 #declare Tilt=-10 #declare Rot=-80 #declare Gap=.12 Now we have two differently positioned stands. Next we must put them on the table we have made. Now that we have these rather nice elaborate Holder objects, we can put them on our table. Eventually we will put the table in the main scene, as a separate object. We could also put the Holders in the main scene as separate objects, but then we would have to render that big scene just to get the positioning right. Instead, we will put the Holders in place on the table, as part of the Table object, while it is just floating in air, and then when we position the table in the main scene, the Holders will automatically be in place. Open up table.inc. Make it look like this (here the lights and cameras have been deleted, if you have commented out all yours, that’s ok too). Notice that the Table object is now a union, including the two holders. The holders have been scaled down to an appropriate size, and put in a sensible place. If you want to see how the table looks with two stands on, you will have to add cameras and lights as well as the usual include files, but remember to get rid of them when you have finished. // THESE #INCLUDES ARE VERY IMPORTANT, LEAVE THEM IN THE .INC FILE!! #include “stand.inc” #include “stand2.inc” #declare Table=object{union{box{<0,0,0> <1,1,1>} texture{material_map{gif "matmap.gif" texture{Stone22 scale<.5,.5,.5>}//black texture{Gold_Metal}//blue texture{BlackStone scale<.5,.5,.5>}//green texture{BlackStone scale <.5,.5,.5>}//cyan texture{Stone9 scale <.5,.5,.5>}//red }//end material map }//end texture translate <-.5,-.5,-1> scale <2,2,.1> object{Holder scale<.23,.23,.23>translate <-.5,.1,.5>} object{Holder2 scale<.23,.23,.23>translate <.6,.1,-.7>} }//end union }// end object There is only one thing left to do. Our second holder is going to hold a magnifying glass. Before we worry about what that will look like, consider how very near impossible it would now be to position a magnifying glass in the jaws of one of our Holders by trial and error. It is necessary to the jaws of one of the holders as a union with the magnifying glass. That way, even after the jaws are rotated, and the Holder moved on the table, and the table moved about in the room, the magnifying glass will still be between the jaws of the Holder. Anyway, let’s quickly make a magnifying glass, by doing this. Open a file called magnify.inc and make it look like this: #declare Rim=object{difference{ cylinder{<0,0,.05> <0,0,-.05> .3525} cylinder{<0,0,.06> <0,0,-.06> .34} } texture{Chrome_Metal} scale<4,4,4> } First we do the Rim, a simple band of steel that will hold the glass lens in. It is the usual hollow cylinder (with the second part extended to remove differencing problems), except that the radius is very particular. I’ll explain why when we have done the lens. #declare Handle=object{cylinder{<-1.2,0,0> <-.2525,0,0> .05} texture{Chrome_Metal} scale<4,4,4> } The handle could hardly be simpler. The rather exact position of one end is simply to make that end meet flush with the rim. We could of course have made the handle much more interesting, but there comes a point at which you have to stop, and since in the finished scene the magnifying glass will be really quite small, it seemed pointless to get elaborate. #declare Lens=object{intersection{ sphere{<0,0,0> 2 translate z*1.97} sphere{<0,0,0> 2 translate z*-1.97} } texture{LensTex} scale <4,4,1> } The lens is made from the intersection of two spheres. This can easily be imagined in two dimensions. Draw a circle (The size of two pence piece). Draw another the same size, but offset so that they overlap by a margin of about 4 millimetres. The shape that is made by the intersection is the same shape as the cross section of our lens. Unfortunately it is very difficult to work out the radius if this lens shape. The thickness at the centre is simply the sum of the radii of the two spheres, minus the total offset. In our case (2+2)-(1.97*2)= .06. There is almost certainly a formula for working out the radius of the lens, but since I don’t know it and it probably needs a calculator, I used trial and error until the size of the Rim was equal to the size of the Lens. All the other objects have been scaled by 4 in all directions. The lens is not scaled up in the z direction, so it becomes even flatter. Our lens does not magnify very much, because it is so flat, but we do not want it to. You’ll see why in the end. We also need to make a texture for our lens. Normally we could just use a standard glass texture, but it matter how our lens refracts light, so we want to specify our own index of refraction. Save magnify.inc (we’ll be coming back to it in just a few seconds) and add this texture to t2.inc: #declare LensTex=texture{ pigment{rgbf<.95,1,.95,1>} finish{refraction 1 ior 1.35}} The pigment is not totally clear. Although the filter value is full (1) the red and blue components are less than one, which will leave a purplish tint to the lens. This tint is nearly imperceptible, but makes a difference. The ior (index of refraction) determines how much the texture bends light. 1 is not at all, the higher, the more it does. This can be used to fine tune how much our glass magnifies things. The higher the ior the greater the magnification. Now get back to magnify.inc and carry on where you left off.... #declare Mag=union{object{Rim} object{Handle} object{Lens} translate x*2.3 rotate y*85 } And finally we make Mag the finished magnifying glass object, orientated to its final position relative to the claw. Save magnify.inc, and open up stand2.inc so we can include the Mag object in it. // old #includes, light etc removed // WE NEED TO KEEP THIS #INCLUDE IN THE FILE #include "magnify.inc" #declare BaseRot=180 #declare Tilt=-10 #declare Rot=-80 #declare Gap=.12 #declare S1Tex=texture{ pigment{color rgb<.3,.25,.25>} finish{specular .4 roughness .008} normal{bumps .5 scale<.01,.01,.01>} } #declare S2Tex=texture{ pigment{color rgb<.7,.7,.3>} finish { metallic ambient 0.1 diffuse 0.75 //brilliance 2 reflection 0.5 phong .8 phong_size 70 // specular .95 // roughness .007 } } #declare CP1=object{union{ cone{<0,.15,0>0 <0,0,0>.2 scale<3,1,1>} box{<-1.3,0,-.1> <-.2,.05,.1>} cylinder{<-1.3,0,0> <-1.3,.05,0> .15} } translate x*1.3 texture{S1Tex} } #declare Claw=object{union{ object{CP1 translate y*.35} //raises top part a little object{Mag translate x*1 translate y*.2} object{CP1 scale<1,-1,1> translate y*Gap*-1} //translate //space between jaws object{union{ object{cylinder{<.5,.4,0> <.5,-.7,0> .035}} object{sphere{<.5,.4,0> .06}} object{sphere{<.5,-.7,0> .06}} } texture{S2Tex} } object{cylinder{<0,-1,0> <0,1,0> .045} texture{S2Tex}} } rotate y*Rot //rotate into place } .......[The rest of the file continues as for stand.inc.....] There are only two changes, marked in bold. We have to include magnify.inc, since we are using the Mag object here, and we have to make the Mag object part of the Claw object. That’s it. Simple, really. Now we just need to put the table in the scene. Open up scene.pov and add the table object to it, remembering to add table.inc to the list of #includes. The lines that need to be added have been put in bold. #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" #include "pill.inc" #include "piccy.inc" #include "table.inc" //NB this file contains stand.inc, and stand2.inc #include "mounts.inc" #include "spotty.inc" #declare Camera1= camera{ location <0,0,0> direction <0, 0, .91> up <0,1,0> right <1.33,0,0> look_at <0,0,0.001> } BIG CHUNK LEFT OUT, IT DOESN’T NEED TO CHANGE. #declare Roof=object{box{<-.2,4.1,-.2> <5.3,4.1,4.2>} texture{WallTex}} //larger than room, a bit.. just above the ceiling light. #declare Room=object{ union{ object{Roof} object{Window translate<1,0,3.99>}//was 3.99 object{Floor} difference{ union{ object{BackWall } object{BackWall translate <0,0,4.2>} object{SideWall } object{SideWall translate <5.2,0,0>} // object{Floor} had to move! } object{WindowFrame translate<1,0,3.85>}//was 3.99 }// end difference translate <-2.5,0,-2> // texture {Basic} }//end union }//end object object{Room} object{Pillar scale<.2,.37,.2> translate <-1.6,0,1.75> texture {PaintTex}} object{Pillar scale<.2,.37,.2> translate <-.1,0,1.75> texture {PaintTex}} // translate x value -1.5 for width of window frame object {Painting scale <.3,.3,.3> rotate y*-90 translate <-2.49,1.3,1>} object{Table scale<.1,.1,.1>rotate y*0 translate <-.7,.85,-1.65>} object{Mountains scale<50,100,50> translate <0,-20,900>} object{SpotL rotate y*90 scale<.3,.3,.3>translate<1.3,2.6,2>} And that is very nearly a finished scene. Render and have a look. There are just some final touches to add before rendering. Namely area lights and a sky (which at present still shows black behind the mountains). The sky is the easiest bit to do. All we need is a vast sphere going around our scene, with a sky colour to it. Add this at the very end of the file scene.pov. //SKYSPHERE sphere{<0,-.5,0> .5 texture{ pigment{gradient y color_map{ [0.0 color rgb<.1,.1,.3>] [1.0 color rgb<.7,.7,.8>] } } finish{ambient 1} }//end texture translate y*.5 scale<20000,20000,20000> //scale both sphere and texture }//end of sphere. The texture is a simple gradient running from dark to light blue. The gradient starts at 0,0,0, which means a sphere at that point would have its middle dark blue and its top and bottom pale blue, since the pattern repeats every unit spreading outward from 0. The sphere is moved down to prevent this. Note that it is moved back into the centre before being scaled up. Area lights make soft shadows. They do this at vast computational cost, so unless you are running POV-Ray on an SGI Onyx I wouldn’t ever use them except for a final rendering. But, you will be glad to know, we are now ready for a final rendering. Change the top of the file scene.pov so that the lights look like this. Don’t delete the ordinary lights, just comment them out. object {light_source {<720,1800,1000> color rgb<2,2,2> area_light <0,0,0> <20,20,0>, 10,10 adaptive 1 } } object{light_source {<0,4,-1.9> color White area_light <0,0,0> <.1,0,.1>, 3,3 adaptive 0 } } The information after the area_light keyword determines what sort of area light it is. Look in the manual for details, but essentially the vector co-ordinates determine the size of the area light. The bigger it is, the bigger the shadows will be. The next two numbers determine the rows and columns of little lights that make up the area light. The more there are the smoother the shadows will be, and the longer it takes to trace. Adaptive is a trick for speeding things up a little; look in the manual if you want to know how, but basically the bigger the number, the less POV-Ray cheats when doing area light calculations. If you’re going to render this scene at high quality it will take days anyway. You may as well make the area lights good. The first light is the exterior one, and is quite big to get a nice soft daylight effect. The other one is our interior room light, and so is quite small. Render away. Make sure the glass in the windows is there, and make sure all your .inc files are ok. It’s worth doing a quick render (240x320, no area lights or anti-aliasing) to make sure there are no glaring mistakes. Then do the final one. I suggest anti-aliasing at 0.3, at the greatest resolution your monitor will display, with the area lights. Enjoy POV-Ray!! Appendix I Listing of all files in their final form Magnify.inc #declare Rim=object{difference{ cylinder{<0,0,.05> <0,0,-.05> .3525} cylinder{<0,0,.06> <0,0,-.06> .34} } texture{Chrome_Metal} scale<4,4,4> } #declare Handle=object{cylinder{<-1.2,0,0> <-.2525,0,0> .05} texture{Chrome_Metal} scale<4,4,4> } #declare Lens=object{intersection{ sphere{<0,0,0> 2 translate z*1.97} sphere{<0,0,0> 2 translate z*-1.97} } texture{LensTex} scale <4,4,1> } #declare Mag=union{object{Rim} object{Handle} object{Lens} translate x*2.3 rotate y*85 } Mounts.inc /* #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" //object{light_source{<-10,5,-10> color White}} object{light_source{<100,50,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,3,-10> } */ #declare Terrain=object{height_field{gif "plasma3.gif" smooth}texture {Basic} translate <-.5,-.5,-.5> scale<20,4,20> } #declare Mountains=object{union{ object{Terrain rotate y*-90 rotate x*-20 translate <-3,0,-3> texture{MountTex scale<1,1,1>} } object{plane{y,.15} texture{WaterTex scale<2,2,2>}} } } //object{Mountains} Piccy.inc #declare Picture=object{ box{<0,0,0> <2.5,2.5,.01>} texture{pigment{ image_map{gif "simple.gif" } } finish{phong .3 phong_size 5} translate <0,0,0> scale<2.5,2.5,1> } translate <-1.25,-1.25,0> scale<1.33,1,1> } #declare Mount=object{ box{<-1.25,-1.25,0> <1.25,1.25,.01> scale <1.33,1,1> scale <1.2,1.2,1> texture{pigment{color rgb<.7,.7,.1>} finish {phong 1 phong_size 13} } } translate z*.0001 } #declare Frame=object{difference{ box{<-1.35,-1.35,0> <1.35,1.35,.1>} box{<-1.25,-1.25,-.001> <1.25,1.25,.1>} // to remove error } texture{pigment{Black} finish{reflection .5 specular .3 roughness .003} } scale<1.33,1,1> scale <1.2,1.2,1> translate z*-.07 } #declare Painting=object{union{ object{Frame} object{Mount} object {Picture} } bounded_by {box{<-1.35,-1.35,-.001> <1.35,1.35,.1> scale<1.33,1,1> scale <1.2,1.2,1> translate z*-.07 } } } Scene.pov #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" #include "pill.inc" #include "piccy.inc" #include "table.inc" #include "mounts.inc" #include "spotty.inc" #declare Camera1= camera{ location <0,0,0> direction <0, 0, .91> up <0,1,0> right <1.33,0,0> look_at <0,0,0.001> } object {light_source {<720,1800,1000> color rgb<2,2,2> area_light <0,0,0> <20,20,0>, 10,10 adaptive 0 } } object{light_source {<0,4,-1.9> color White area_light <0,0,0> <.1,0,.1>, 3,3 adaptive 0 } } camera {Camera1 translate <-.8, 1, -2>} #declare BarsY= union{ cylinder{<.5,0,.17> <.5,5,.17> .03} cylinder{<1,0,.17> <1,5,.17> .03} } #declare BarsX= union{ cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*.7} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.4} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*1.9} cylinder {<-.5,0,.17> <2.5,0,.17> .03 translate y*2.4} } #declare WinBase=object{ box{<0,0,0> <5,.1,.1>} translate <0,0,0.1> } #declare WinBars=object{union{ object{BarsY} object{BarsX} } bounded_by{box{<0,-.01,0><1.5,5,.3>}}//extends to ceiling } #declare WindowGlass=object{ box{<-1,-1,0> <2,5,.0015>} texture {Glass}} #declare Window=object{union{ object{WinBars} object{WindowGlass translate z*.17} object{WinBase} } texture {WinTex} } #declare WindowFrame=object{union{ box{<0,-.01,0> <1.5,2.5,.3>} // minus y value to prevent membrane error object{ cylinder{<0,0,0> <0,-.3,0> .75} rotate x*-90 translate y*2.5 translate x*.75 } }//end union texture {WallTex} scale<1,1,1.5>}//end object scaling to cut out skirting #declare PRail=object{ cylinder{<0,2.3,-.2> <5.2,2.3,-.2> .02} texture{PaintTex} } #declare PRail1=object{ cylinder{<0,2.3,0> <0,2.3,4.2> .02} texture{PaintTex} } #declare Skirting=object{union{ // Goes on the wall BEHIND the camera box{<-.2,-.2,-.2> <5.2,5.2,0> translate<0,-4.9,-.04>} cylinder{<0,.3,-.2> <5.2,0.3,-.2> .02} texture{PaintTex} }//end union } #declare Skirting1=object{union{ box{<-.2,-.2,-.2> <0,5.2,4.2> translate<0.04,-4.9,0>} cylinder{<0,.3,0> <0,.3,4.2> .02} texture{PaintTex} }//end union } #declare BackWall=object{union{ // This is the wall BEHIND the camera box{<-.2,-.2,-.2> <5.2,5.2,0> texture {WallTex} } object { Skirting } object {PRail} }//end union } #declare SideWall=object{union{ box{<-.2,-.2,.-2> <0,5.2,4.2> texture {WallTex rotate y*-90} } object{ Skirting1 } object{ PRail1} }//end union } #declare Floor=object{ box{<-.2,-.2,-.2> <5.2, 0,4.2>} texture{FloorTex} } #declare Roof=object{box{<-.2,4.1,-.2> <5.3,4.1,4.2>} texture{WallTex}} //larger than //room, a bit.. just above the ceiling light. #declare Room=object{ union{ object{Roof} object{Window translate<1,0,3.99>}//was 3.99 object{Floor} difference{ union{ object{BackWall } object{BackWall translate <0,0,4.2>} object{SideWall } object{SideWall translate <5.2,0,0>} // object{Floor} had to move! } object{WindowFrame translate<1,0,3.85>} }// end difference translate <-2.5,0,-2> // texture {Basic} }//end union }//end object object{Room} object{Pillar scale<.2,.37,.2> translate <-1.6,0,1.75> texture {PaintTex}} object{Pillar scale<.2,.37,.2> translate <-.1,0,1.75> texture {PaintTex}} // translate x value -1.5 for width of window frame object {Painting scale <.3,.3,.3> rotate y*-90 translate <-2.49,1.3,1>} object{Table scale<.1,.1,.1>rotate y*0 translate <-.7,.85,-1.65>} object{Mountains scale<50,100,50> translate <0,-20,900>} object{SpotL rotate y*90 scale<.3,.3,.3>translate<1.3,2.6,2>} //SKYSPHERE sphere{<0,.5,0> .5 texture{ pigment{gradient y color_map{ [0.0 color rgb<.3,.3,.6>] [1.0 color rgb<.7,.7,.8>] } } finish{ambient 1} }//end texture scale<20000,20000,20000> //scale both sphere and texture }//end of sphere. Stand.inc /* #include "colors.inc" #include "textures.inc" #include "camlight.inc" object {Light1 translate <0,100,-6>} object {Light1 translate <50,5,-100>} camera {Camera1 rotate x*0 translate <1,3.5,-9>} #declare Basic =texture{pigment{color Red} finish{Shiny} } */ #declare BaseRot=-40 #declare Tilt=20 #declare Rot=0 #declare Gap=0 #declare S1Tex=texture{ pigment{color rgb<.3,.25,.25>} finish{specular .4 roughness .008} normal{bumps .5 scale<.01,.01,.01>} } #declare S2Tex=texture{ pigment{color rgb<.7,.7,.3>} finish { metallic ambient 0.1 diffuse 0.75 //brilliance 2 reflection 0.5 phong .8 phong_size 70 // specular .95 // roughness .007 } } #declare Base =object{difference{ cylinder{<0,0,0> <0,2,0> 1.5} torus{2,1.7 translate y*1.9} } texture{S1Tex} } //object{Base} #declare CP1=object{union{ cone{<0,.15,0>0 <0,0,0>.2 scale<3,1,1>} box{<-1.3,0,-.1> <-.2,.05,.1>} cylinder{<-1.3,0,0> <-1.3,.05,0> .15} } translate x*1.3 texture{S1Tex} } #declare Claw=object{union{ object{CP1 translate y*.3} //raises top part a little object{CP1 scale<1,-1,1> translate y*Gap} //translate space between jaws object{union{ object{cylinder{<.5,.4,0> <.5,-.7,0> .035}} object{sphere{<.5,.4,0> .06}} object{sphere{<.5,-.7,0> .06}} } texture{S2Tex} } object{cylinder{<0,-1,0> <0,1,0> .045} texture{S2Tex}} } rotate y*Rot //rotate into place } //object{Claw rotate<-20,40,0>} #declare CrossArm=object{union{ cylinder{<-2,0,0> <2,0,0> .07} sphere{<0,0,0> .45 scale<2,1,1> translate x*-2 } box{<-.5,-.5,-1> <.5,.5,1> rotate z*45 scale<.15,.3,.8> texture{S2Tex}} cylinder{<3,.5,0> <2,0,0> .05} cylinder{<3,.6,0> <3,.4,0> .12} cylinder{<3,-.5,0> <2,0,0> .05} cylinder{<3,-.6,0> <3,-.4,0> .12} object{Claw scale<.8,.8,.8> translate<3,0,0>} } texture{S1Tex} rotate z*Tilt //tilt into place } //object{CrossArm translate x*-1} #declare Cradle=object{union{ object{difference{ torus{.5,.06 rotate x*90} plane{-y,0} } } object{sphere{<-.5,0,0> .1}} object{sphere{<.5,0,0> .1}} } bounded_by{cylinder{<0,0,-.2> <0,0,.2> .6}} texture{S2Tex} } #declare UpArm=object{union{ object{Cradle translate<0,.5,-.5>} //base of curve at 0 object{Cradle translate<0,.5,.5>} object{difference{ cylinder{<-.1,0,0> <.1,0,0> .53 } //smaller rim than torus cylinder{<-.11,0,0> <.11,0,0> .47} plane{-y,0} } translate <0,0,0> texture{S1Tex} } object{cylinder{<0,-.5,0> <0,-5.5,0> .11}texture{S1Tex}} object{CrossArm translate y*.19} } translate y*5.5 //base at 0,0,0 rotate y*BaseRot// rotates whole } //object{UpArm} #declare Holder=object{union{ object{UpArm} object{Base scale<.5,.5,.5> } } } //object{Holder translate <0,0,-2>} Stand2.inc /* #include "colors.inc" #include "textures.inc" #include "camlight.inc" #include "t2.inc" object {Light1 translate <0,100,-6>} object {Light1 translate <50,5,-100>} camera {Camera1 rotate x*0 translate <3,3.5,-9>} */ #declare Basic =texture{pigment{color Red} finish{Shiny} } #include "magnify.inc" #declare BaseRot=180 //180 #declare Tilt=-10 //10 #declare Rot=-80 //-10 #declare Gap=.12 #declare S1Tex=texture{ pigment{color rgb<.3,.25,.25>} finish{specular .4 roughness .008} normal{bumps .5 scale<.01,.01,.01>} } #declare S2Tex=texture{ pigment{color rgb<.7,.7,.3>} finish { metallic ambient 0.1 diffuse 0.75 //brilliance 2 reflection 0.5 phong .8 phong_size 70 // specular .95 // roughness .007 } } #declare Base =object{difference{ cylinder{<0,0,0> <0,2,0> 1.5} torus{2,1.7 translate y*1.9} } texture{S1Tex} bounded_by{cylinder{<0,0,0> <0,2,0> 1.5}} } //object{Base} #declare CP1=object{union{ cone{<0,.15,0>0 <0,0,0>.2 scale<3,1,1>} box{<-1.3,0,-.1> <-.2,.05,.1>} cylinder{<-1.3,0,0> <-1.3,.05,0> .15} } translate x*1.3 texture{S1Tex} } #declare Claw=object{union{ object{CP1 translate y*.35} //raises top part a little object{Mag translate x*1 translate y*.2} object{CP1 scale<1,-1,1> translate y*Gap*-1} //translate space between jaws object{union{ object{cylinder{<.5,.4,0> <.5,-.7,0> .035}} object{sphere{<.5,.4,0> .06}} object{sphere{<.5,-.7,0> .06}} } texture{S2Tex} } object{cylinder{<0,-1,0> <0,1,0> .045} texture{S2Tex}} } rotate y*Rot //rotate into place } //object{Claw rotate<-20,40,0>} #declare CrossArm=object{union{ cylinder{<-2,0,0> <2,0,0> .07} sphere{<0,0,0> .45 scale<2,1,1> translate x*-2 } box{<-.5,-.5,-1> <.5,.5,1> rotate z*45 scale<.15,.3,.8> texture{S2Tex}} cylinder{<3,.5,0> <2,0,0> .05} cylinder{<3,.6,0> <3,.4,0> .12} cylinder{<3,-.5,0> <2,0,0> .05} cylinder{<3,-.6,0> <3,-.4,0> .12} object{Claw scale<.8,.8,.8> translate<3,0,0>} } texture{S1Tex} rotate z*Tilt //tilt into place } //object{CrossArm translate x*-1} #declare Cradle=object{union{ object{difference{ torus{.5,.06 rotate x*90} plane{-y,0} } } object{sphere{<-.5,0,0> .1}} object{sphere{<.5,0,0> .1}} } bounded_by{cylinder{<0,0,-.2> <0,0,.2> .6}} texture{S2Tex} } #declare UpArm=object{union{ object{Cradle translate<0,.5,-.5>} //base of curve at 0 object{Cradle translate<0,.5,.5>} object{difference{ cylinder{<-.1,0,0> <.1,0,0> .53 } //smaller rim than torus cylinder{<-.11,0,0> <.11,0,0> .47} plane{-y,0} } translate <0,0,0> texture{S1Tex} } object{cylinder{<0,-.5,0> <0,-5.5,0> .11}texture{S1Tex}} object{CrossArm translate y*.19} } translate y*5.5 //base at 0,0,0 rotate y*BaseRot// rotates whole } //object{UpArm} #declare Holder2=object{union{ object{UpArm} object{Base scale<.5,.5,.5> } } } //object{Holder2 translate <1,-1,-1>} Simple.pov #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} object{light_source{<100,80,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } #declare Rod= object{cylinder{<0,-1,0> <0,2,0> .25} texture{Basic2} translate <0,0,0> // rotate z*90 // rotate y*-45 } #declare FirstShape= object{union{ object{sphere{<0,0,0> .5 texture{Basic} } } object{Rod} object{Rod rotate z*-90 texture{Basic2}} object{Rod rotate <90,0,0> texture{Basic2}} } //end of the union }// end of the object object{FirstShape scale <.5,.5,.5> translate <0,1,0>} object{plane{y,-2} texture{Chex} } object{difference{ object{box{<0,0,0> <2,2,2>} texture{PinkAlabaster} } object{sphere{<1,1,1> 1.2} texture {White_Marble} } } //end difference scale <.5,.5,.5> rotate y*-30 translate <-2,-2,-1> }// end main object object{cone{<0,.5,0> .5 <2.5,0,0> 0} texture{Tan_Wood scale<.25,.25,.25>} rotate y*10 translate<-.6,-2,3.9> } object{sphere{<0,0,0> 1000 } texture{DaySky scale<150,30,150> }} object{torus{.7,.15 texture{Reflect} rotate x*90 } translate <.5,-1.15,2>} object{cylinder{<0,0,0> <0,2.5,0> .3} texture{Glass} translate <2,-2,1.6> } Spotty.inc /* #include "colors.inc" #include "textures.inc" #include "shapes.inc" #include "t2.inc" object{light_source{<-10,5,-10> color White}} object{light_source{<10,5,-10> color White}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-5> } */ #declare Vents=object{union{ box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}}} box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}} translate x*.2} box{<.14,-1,-.15> <.2,1,.15> texture{pigment{color White}} translate x*.4} } } #declare Body=object{difference{ object{union{ cylinder{<0,0,0> <1,0,0> .25} sphere{<0,0,0> .25} } texture{pigment{color Black}finish{Dull}} } object{union{ cylinder{<0,0,0> <1.1,0,0> .2} //difference probs sphere{<0,0,0> .2} }texture{pigment{color White}finish{ambient.7}} } object{Vents} object{Vents rotate x*90} } bounded_by{cylinder{<-.25,0,0> <1,0,0> .25}} } #declare Flap=object{ box{< 0 ,0 ,-.25> <.01,.30,.25>rotate z*-45 translate<.95,.25,0>} } #declare Flaps=object{union{ object{Flap} object{Flap rotate x*90} object{Flap rotate x*180} object{Flap rotate x*270} texture{pigment{color Yellow}} } } #declare Bulb=object{light_source {<.8,0,0> color White spotlight point_at <1,0,0> radius 7 falloff 11 tightness 50}} #declare Bulb1=object{union{ object{light_source {<.2,0,0> color White }} cylinder{<.7,0,0> <.71,0,0> .24 texture{pigment{color White}} } } } #declare Beam=object{cone{<.2,0,0>0 <100,0,0>16.5} texture{pigment{color rgbf<1,1,1,.95>}finish{ambient 1}} no_shadow } #declare Bracket=object{union{ cylinder{<0,0,0> <0,-.5,0> .07} cylinder{<0,-.5,0> <-1,-.5,0> .07} sphere{<0,0,0> .1 scale <1,.7,1> translate y*-.5} } texture{pigment{color Black}finish{Dull}} } #declare SpotL=object{union{ union{ object {Body } object {Flaps} object{Bulb} object{Bulb1} object{Beam} rotate z*-20 // up/down rotate y*80 // across } object{Bracket} } translate x*1 //to make the end of the bracket at 0. } //object{SpotL rotate <0,0,0> translate z*-1} Table.inc /* #include "colors.inc" #include "textures.inc" #include "t2.inc" #include "stones.inc" object{light_source{<0,100,-6> color White}} object{light_source{<5,5,-10> color rgb<1,1,1>}} camera{location <0,0,0> look_at <0,0,1> direction <0,0,1> up <0,1,0> right<1.3,0,0> translate <0,0,-2.7> } */ #declare Table=object{union{box{<0,0,0> <1,1,1>} texture{material_map{gif "matmap.gif" texture{Stone22 scale<.5,.5,.5>}//black texture{Gold_Metal}//blue texture{BlackStone scale<.5,.5,.5>}//green texture{BlackStone scale <.5,.5,.5>}//cyan texture{Stone9 scale <.5,.5,.5>}//red } } translate <-.5,-.5,-1> scale <2,2,.1> } object{Holder scale<.23,.23,.23>translate <-.5,.1,.5>} object{Holder2 scale<.23,.23,.23>translate <.6,.1,-.7>} } T2.inc #declare WallTex=texture{pigment{color rgb<.8,.76,.6>} finish{diffuse .85 specular .25 roughness .00001} } #declare PaintTex=texture{pigment{color rgb<1,1,1>} // finish{phong 1 phong_size 20} finish{diffuse .5 specular .8 roughness .009} } #declare WinTex=texture{pigment{color rgb<.95,.95,.95>} finish{phong .8 phong_size 30} // finish{diffuse .3 specular .9 roughness .001} } #declare FloorTex=texture{pigment{checker color White color rgb<.3,.45,.7>} // finish{phong .8 phong_size 10} finish{diffuse .6 specular .5 roughness .0001} scale <.3,.3,.3>} #declare Basic=texture{pigment{color Red}finish{Shiny}} #declare Basic2=texture{pigment{color Blue}finish{Shiny}} #declare Stripes= texture{ pigment{ wood color_map{ [0.0 color rgb<.7,.6,.55>] [0.6 color rgb<.7,.6,.55>] [0.7 color rgb<.7,.5,.4>] [0.75 color rgb<.7,.5,.4>] // [0.6 color White] // [0.79 color White] // [0.8 color Blue] }//end of color map turbulence .07 octaves 2 omega .5 lambda .5 } finish{ Dull } scale<.2,.2,.2> } #declare Chex=texture{pigment{checker color rgb<.7,.3,.3> color rgb<.3,.45,.3>} // finish{phong .8 phong_size 10} finish{diffuse .6 specular .5 roughness .0001} normal {bumps .5 scale <.15,.5,.15>} } #declare DaySky= pigment {bozo color_map {[0.0 color rgb<.6,.6,.6>] [0.3 color rgb <.7,.7,.7>] [0.55 color rgb<.4,.4,.9>] [0.75 color rgb<.3,.3,.85>] [0.99 color rgb<.6,.6,.9>] } turbulence .3 octaves 5 omega .7 } #declare Reflect=texture{pigment{color rgb<1,1,1>} finish{reflection 1 diffuse .2 specular .3 roughness .002} } #declare MountTex=texture{ pigment{ granite color_map{ [0.0 color rgb<.2,.3,.1>] [0.3 color rgb<.2,.3,.1>] [0.3 color rgb<.4,.4,.2>] [0.6 color rgb<.2,.5,.3>] [0.8 color rgb<.4,.35,.2>] } turbulence .4 lambda .9 } finish{diffuse .9 specular 0 brilliance 1 metallic} } #declare LensTex=texture{pigment{rgbf<.99,1,.99,1>}finish{refraction 1 ior 1.35}} #declare WaterTex = texture {pigment{color rgbf<.7,.7,.9,.9>} normal {ripples 0.75 frequency 10 } finish {reflection 0.3 refraction 1 ior 1.33 } } #declare BlackStone= texture{ pigment{ granite color_map{ [0.0 color rgb<0.2,0.2,0.2>] [0.25 color rgb<0.1,0.1,0.1>] [0.4 color rgb<0,0,.05>] [0.8 color rgb<0,0,.1>] } turbulence .4 lambda .4 } translate <3,0,0> scale<2,2,2> } texture{pigment{ gradient x color_map{ [0.0 color rgbf<.8,.8,.8,1>] [0.95 color rgbf<1,1,1,1>] [0.98 color rgbf<1,1,1,0>] [1 color rgbf <1,1,1,0>] } turbulence .8 omega .7 octaves 4 scale <.7,1.5,.2> rotate z*-40 translate <0,2,0> } finish{ specular .5 diffuse .3 /*reflection .35*/} } Appendix II Other POV-Ray related information The are thousands of pieces of software available that will help you with POV- Ray and raytracing in general. Many will probably be available where you got this. Other places to go for information are.. Usenet: Comp.graphics.raytracing is the newsgroup for raytracing in practice and theory, many of the best POV-Ray artists around read this group, as well as members of the official POV-Ray team. Feel free to ask for help, but please read the manual FIRST :-) ftp: ftp.povray.org is the official ftp site for povray, and has almost all the available material in it. In addition, it has hundreds of sample images and scene files. WorldWideWeb: There are now a couple of raytracing pages out there, as well as a whole host of computer graphics pages in general. Appendix III The Artistic considerations POV-Ray is not just about getting things to like like they do in real life. If you want you picture to stand out from all the other thousands of rendered images, you’ll need to do more than slavishly reproduce some object. Below is a brief account of the more artistic considerations of the finished image, and please don’t dismiss them until you have thought about them. Balance. I suppose this is the one thing everyone considers in a scene. If all the objects are crowded into one corner, it’s going to look silly. On the other hand, if everything is perfectly symmetrical, it will look dull. In my room, the window, probably the most powerful feature is dead centre. There are reasons for this, but to balance it, the rest of the room is not at all symmetrical. The left wall is visible, but not the right wall. The collection of small detailed objects (stands, table, spotlight) are all to the right of the room, and on the left is only the big picture, and open floor space. Movement. Computer graphics almost always seems to produce very still images. By still I don’t mean not animated, of course, but the image looks calm and set in stone. Features such as motion blur, or soft focus are not available in POV-Ray (yet) and so everything has a crispness to it that makes it look unreal. To make up for this, it is important to get the viewer’s eye moving all over the picture. Of course no-one ever just looks at one part of a picture, but very quickly the eye will settle on one part, and the rest will just be a setting for that part. In the case of the portrait, for example, we want this to happen, and to focus attention on the face. In my scene, I want to break up the inherent stillness by forcing the viewer’s eyes all over the place. The strongest pull in the scene is straight out of the window. It is central, and everything converges on it. The squared floor emphasises the perspective effect, as do the horizontal lines formed by the skirting board of the left wall, and by the top and bottom of the picture. But against this strong pull is the light coming back in through the window. The shadows cast by the window bars push the eye back into the room, and the window itself, with strong bars going across the picture is a block between the perspective of the squared floor, and the sea. Going across all this is the beam of the spotlight, which at once points to the picture on the wall, and equally forms an arrow pointing at the spotlight itself, and the curious patterns of light cast on the wall by it. The picture itself has perpective of its own, and is like another window in the left wall, drawing us out of the room. It is natural for people to read writing they see, and right in the foreground is the writing on the table, and on top of that the stands, all of which is detailed and demands close attention. The magnifying glass then turns our gaze back onto the window, and so it goes, round and round. Concept. This is hardly conceptual art, but there is a sort of reference to POV- Ray. POV stands for persistance of vision, and as I have said, the eye can never rest, it persistantly moves round and around, now going out into the background, now in to the foreground. The lights never stop shining, and the magnifying glass never stops magnifying, it is a passive scene (a television in the scene would be directly opposed to this notion of persistance). Salvador Dali, the great surrealist made a famous picture entitled The Persistance of Memory, and in recognition of this here is a thought for you. While designing the scene, I moved the water in the background up so that it covered the floor. Try it yourself and compare the two pictures, the effect is quite striking.