Have a Merry Scripting Christmas with Persistence of Vision
Some of the best Christmas mornings I remember are mornings when I holed myself away and built things. On earlier Christmases, it could have been Legos, or off-brand erector sets, or a model train. Later, it might have been building characters or adventures using the new Dungeons and Dragons Basic or Expert boxed set I found under the tree.
When sitting at the computer, every day was Christmas, and in many ways it still is. As you can see from the majority of this blog, I’m still finding joy in the ASCII art script. So why not a touch more joy on Christmas morning? Consider this my erector set gift to you.
Except for this image, all of the ASCII art created using the asciiArt script in 42 Astounding Scripts• came from photographs or drawings. That is, a human hand was involved in its creation.
This Christmas image, on the other hand, was nearly completely scripted. Obviously, the version with Linus’s Bible quote over the Christmas scene came from the asciiArt script, but the Christmas scene itself came from the Persistence of Vision raytracer. The only hand-placed part of the image was the phrase “Merry Christmas” in the upper left.
Persistence of Vision is a lot of fun to play with, Christmas morning or any morning. Or, as was often the case for me (and still often is) late into the night.
Remember to install brew and then “brew install povray” as described in the bubble cake example if you haven’t already. To create an image from this POV-Ray script file, run the povray program on it, as you would any other command-line script or program.
- $ povray Christmas.pov
This will create, by default, an 800 by 600 PNG image with the same filename as the .pov file but with the extension .png. In this case, if you name the file “Christmas.pov” as I did, the file will come out “Christmas.png”.
You can adjust the width and/or height using the Width= and Height= command line options.
- #to double the dimensions
- $ povray Christmas.pov Width=1600 Height=1200
- #for a 2.39:1 widescreen image:
- $ povray Christmas.pov Width=1600 Height=670
- #for a Facebook-friendly ratio to share with your friends:
- $ povray Christmas.pov Width=1200 Height=628
If the ratio between the width and height remain the same, the image looks the same as well, other than being higher or lower quality depending on whether it has bigger or smaller dimensions. If the ratio changes, then the image changes as well. As in a movie scene, a wider ratio shows more off to the sides, and a taller ratio shows more top and bottom.
The Persistence of Vision code is very simple.
[toggle code]
- //A simple Christmas scene
- //Jerry Stratton astoundingscripts.com/merry
- #include "colors.inc"
- #include "textures.inc"
- #declare aspectRatio = image_width/image_height;
-
camera {
- location <0,0,-120>
- look_at <0,0,0>
- right x*aspectRatio
- }
- //stars in the sky
- light_source { <1000,1000,-2000> White*0.2 }
- light_source { <15000,15000,50000> White }
-
sky_sphere {
-
pigment {
- bozo
-
color_map {
- [0.0 White*3]
- [0.2 Black]
- [1.0 Black]
- }
- scale .001
- }
-
pigment {
- }
- //the snow-covered ground
-
height_field {
- png "plasma3.png"
- smooth
- translate <-0.5,0,-0.5>
- scale <1400,100,1000>
- translate y*-210
- pigment { SkyBlue }
-
normal {
- crackle 0.2
- scale 2
- }
- finish { Shiny }
- }
- //the red cross
-
union {
-
box {
- <-.2,0,-.2>,<.2,2,.2>
- }
-
box {
- <-.6,1.2,-.2>,<.6,1.6,.2>
- }
- scale 240
- rotate y*40
- pigment { color Red }
- translate <280,-250,640>
-
box {
- }
- //trees
-
#declare tree = object {
-
cone {
- <0,0,0>, 96, <0,240,0>,0
- pigment { color Green }
- }
-
cone {
- }
-
union {
- object { tree }
-
object { tree
- translate <120,-30,120>
- }
-
object { tree
- translate <-120,0,140>
- }
- translate <-150,-170,380>
- }
It consists of four items: a sky sphere, a height field for the ground, a cross, and a set of trees.
- The Camera
- Just as in the earlier example, the camera defines the direction from which we see the scene. This virtual camera is set up backward 120 units, looking straight down to the origin of <0,0,0>. Because I know I’m going to want to render this image at different sizes, and because it’s a good idea in general, I orient the camera using the aspect ratio of the image.
- The stars in the sky
- Every image has a light source, and in this case there are two, and they’re far away. There’s a dim one behind the camera, and a bright one far off in the sky, something like moonlight. The dim one is made dim by multiplying White by 0.2. There’s no difference between White*0.2 and 0.2—because White is <1,1,1>, both mean <0.2,0.2,0.2>—but the former reminds me what I’m doing. The stars themselves are a sky_sphere given a pseudo-random noise pattern (bozo) that looks pretty decent as stars. The stars are very bright in the sky field—they are literally whiter than white, by three times. The sky sphere’s pigment is white and black, and scaled very tiny to look like far away stars.
- The snow-covered ground
- A height field in Persistence of Vision takes an image and converts the colors of the image to heights in the scene. POV comes with a handful of predefined height fields, of which plasma3.png is one. Try commenting out the “smooth” keyword and rendering the image, and you’ll see the triangles that make up the mesh created by the values in plasma3.png. By smoothing and scaling up the height field, we end up with something that looks like rolling hills. And by giving it a shiny sky blue pigment, it looks like snow-covered hills.
- The red cross
- This is the simplest shape in the scene. It’s nothing more than two rectangular boxes, one long and one tall, joined into a cross shape. It is scaled up 240 times, rotated around the y axis (comment out the rotate y*40 line and you’ll see that the cross is now facing toward the camera), given the color red, and then moved to where in the scene I want it.
- Trees
- The trees are cones, given a straight green color. The one tree object is used three times to create a small grove of trees on the height field. Two of the trees are moved so that they’re not on top of each other, and then the entire grove is moved to where I want the trees in the scene.
Persistence of Vision renders these objects as if they actually existed in the scene as created. The cross, trees, and height field throw shadows from the light sources. Because the height field has been given a shiny finish, it reflects the light that’s shining on it from the stars. Even the sky sphere, though it isn’t obvious in this scene, curves around as if it were a sphere around the scene.
The scene can be made a lot more complex, and in fact this is one of the advantages of using a scripting language to create images. If you want more trees, add more of the trees you already have. You can reuse objects and entire scenes with different parts, such as by adding falling snow. I didn’t use the snow in the book because, besides being more complicated, the snow muddles up the ASCII art.
If you look closely at the ASCII version of the image, you’ll see a lens flare against one of the arms of the cross. I left that out of these examples because lens flares, like snow, are a more complex topic.
Even the text “Merry Christmas” could have been scripted if I’d felt like it. Add the following to the bottom of the script, and you’ll get MERRY CHRISTMAS in the upper left.
[toggle code]
- //Merry Christmas!
-
union {
-
text {
- internal 1 "MERRY"
- .05, 0
- translate <0,0,0>
- }
-
text {
- internal 1 "CHRISTMAS"
- .05, 0
- translate <-1.1,-1,0>
- }
-
texture {
- pigment { color Gold }
-
finish {
- Shiny
- ambient .4
- }
- }
- scale 70
- translate <0,180,400>
- translate <-148*pow(aspectRatio,1.4),0,0>
-
text {
- }
This is the union of two text objects; one reads “MERRY” and the other “CHRISTMAS”. The Christmas text is translated left 1.1 units and down 1 unit, to center it below the Merry text. Then the entire thing is scaled 60 times and translated into the upper left. In order to get the text approximately at the upper left for all three of the aspect ratios, I did a rough formula based on the aspect ratio. It’s very rough—it isn’t likely to work well with other aspect ratios.
- December 25, 2020: Sparkling lights for Christmas
-
It’s time once again to play with tinker toys for Christmas. This Christmas, like last Christmas, the tinker toys are the Persistence of Vision raytracer. (And by the way, if you enjoy this kind of toy, Astounding Scripts is currently on sale.)
And this time, instead of using the command-line version, I used the GUI version from Yvo Smellenbergh. I’m using the 3.8 development version although I’m not sure it matters for this scene; the 3.7 version is likely fine also. However, as betas go this has so far been very reliable. At the time of writing, I have not had a single crash, and the scenes render as I expect them to.
The GUI version recognizes the syntax of POV and highlights the keywords just as Textastic does for other scripting languages. It can also list your variables and macros, and it provides easy templates for the various POV shapes and scene elements.
I was inspired by the Christmas tree photo I used in O Little Town of Bethlehem, which is a photo of the Macy’s Christmas tree in San Francisco. I was also inspired by the wonderful artwork in the Charlie Brown Christmas Special. This video is a rough combination of those two inspirations.
You can easily change the background. The background in this scene is a shape like any other: a plane. I didn’t do anything special to create it, just played around with normals in Persistence of Vision. Normals are basically roughness on the surface of a shape. The most common is probably a bumpy surface, and that’s what I used first, scaled by .1. Scaling a bumpy surface by less than one makes the bumps smaller and more numerous.
[toggle code]
-
normal {
- bumps
- scale .1
- }
After playing around while reading the manual about normals, I ended up choosing the marble keyword, with a turbulence of 1. That's pretty much all I did—read through the various keywords for altering the normal and chose the one that felt right.
You can download the scene file, as well as the music that went along with it, as a zip file (Zip file, 10.6 KB).
-
normal {
- 42 Astoundingly Useful Scripts and Automations for the Macintosh•: Jerry Stratton at Amazon.com (paperback)
- If you have a Macintosh and you want to get your retro on, take a look at 42 Astoundingly Useful Scripts and Automations for the Macintosh. These modern scripts will help you work faster and more reliably, and inspire your own custom scripts for your own workflow.
- Photo-editing with Persistence of Vision
- You can use the Persistence of Vision raytracer from the command-line to add elements to photos.
- POV-Ray
- POV-Ray is a ray-tracing program for Macintosh, Unix, DOS, and Windows. It is very powerful, full-featured, reliable, and free. It also uses a “programmer-style” interface rather than a graphical one. The tutorial that comes with it is well-written, so it’s worth a look .Persistence of Vision is very useful for those of us who like to automate our image creation. It uses a simple scripting language to build up complex 3-dimensional imagery.
More ascii art
- Create your own ASCII art palettes with densitySort
- You can create your own ASCII art palettes from special (fixed pitch) fonts and specific collections of characters, using the densitySort script here.
- Random colors in your ASCII art
- One of the great things about writing your own scripts is that when you need new functionality, you can add it. I needed random colors in a single-character ASCII art image. It was easy to add to the asciiArt script. Here’s how.
- Hello World in Amber
- A hello world too retro even for me.
- A thousand points of color: give your photos a pointillist turn
- I had far too much fun with that kleenex mask in the book. Here’s a more serious look at creating pointellated images using the asciiArt script in 42 Astounding Scripts.
- Commemorate Patriot Day with Betsy Ross
- The Declaration of Independence overlaid on the Betsy Ross flag.
- Three more pages with the topic ascii art, and other related pages
More Christmas
- Candy cane oatmeal crispies
- These candy cane cookies are a great way to use up post-Christmas candy canes. You might even want to hit the after-Christmas sales just to get canes to make these with.
- Sparkling lights for Christmas
- This POV-Ray scene file will animate sparkling lights against a green background. If you want to make three dimensional images with lots of similar objects and then animate them, this will show you how to do it.
- 8 (bit) Days of Christmas: Day 0 (Go Tell It On the CoCo!)
- Day 0 of the 8 (bit) days of Christmas. Christmas Eve, and the cattle are lowing.
- 8 (bit) Days of Christmas
- Eight holiday images created on the TRS-80 Color Computer, from the early to mid eighties.
- Real frothin’ eggnog
- You are going to need a straw to drink this eggnog—because it’s too frothy to pour out of your glass.
- Two more pages with the topic Christmas, and other related pages
More Persistence of Vision
- Sparkling lights for Christmas
- This POV-Ray scene file will animate sparkling lights against a green background. If you want to make three dimensional images with lots of similar objects and then animate them, this will show you how to do it.
- Photo-editing with Persistence of Vision
- You can use the Persistence of Vision raytracer from the command-line to add elements to photos.
- Persistence of Vision tutorial
- A step-by-step tutorial, available under the Gnu Free Documentation License, on using the Persistence of Vision raytracer.
Tanti Auguri di un Buon Natale a tutti!
Gianmarco Marchetti at 5:15 p.m. December 22nd, 2022
WyDAZ
And a Merry Christmas to you, too!
Jerry Stratton in Texas at 6:14 p.m. December 22nd, 2022
yFmrE