Exercise 4: Procedural texturing

Out: Tuesday, February 24
Due: Tuesday, March 2, 11:59pm

In this assignment, you will experiment with creating images using the bitmap-from-procedure primitive.  As with assignment 2, this assignment will be critiqued by your fellow students.  However, this time you will be critiqued both on the aesthetics of the images you create and also on the aesthetics of the code you use to create them.

Part 0: update meta

The first thing you'll want to do is to download the new version of meta that supports all the good stuff like noise functions that we talked about in lecture.  You'll need to uninstall the old version of meta before installing the new one (if someone knows how to get the installer to just overwrite the old version, let me know).

Part 1: Exploration

The purpose of this part of the assignment is to get experience using the various techniques for procedural painting discussed in class.  You will not have to turn in anything you do for this section per se.  However, you will use it as a starting point for the work you do in parts 2 and 3, which you will turn in.

First, you should review the lecture notes on procedural rendering.  Pay particular attention to the use of "higher-level" procedures like shift and replicate for building patterns from other patterns.  You need not use these for part 1, but the final code you turn in will be critiqued (in part) for how clear it is to the reader and for the degree to which it incorporates reusable building blocks like these.

Now experiment with making different patterns using bitmap-from-procedure.  You may want to copy the definition of the show procedure from the lecture notes and use it in place of bitmap-from-procedure, but that's entirely up to you.  You should experiment with making a large number of different kinds of patterns.  Give yourself at least 2 hours to experiment.  Note that you are allowed to have fun here.  You don't have to worry about doing something "bad" or "wrong" here because you'll only be turning in the work you're happy with.

Although there is no fixed goal for this part, you should make sure you experiment with using all the following techniques for making your images:

Along the way, keep track of what you like and what you don't like.  Make sure that you can find the code for the good stuff when you get to part 2.

Part 2: Refactoring

Okay.  Now that you've gotten a sense of what works and what doesn't, you've probably found that there are some basic "recipes" you like for different kinds of images.  For example, you may like images that have a certain kind of pattern repeated in a line or that you like to make images by starting with a "clean" image and then "messing it up" with noise in a certain way.  Whatever.  Your job now is to:

For example in assignment 1, you probably had a whole lot of code of the form:

[translate center [box width height]]

It would be clearer and less error prone to write it as [box-at center width height] and then add the definition:

[define box-at
             [center width height → [translate center
                                                                     [box width height]]]]

or there may be more complicated kinds of code patterns you use, such as a set of many different images all summed together.  You if you write it like this:

[p  → [+ [pattern1 p] [pattern2 p] [pattern3 p]]]

You could make it clearer by saying something like "[pattern+ pattern1 pattern2 pattern3]".  But then you need a procedure, pattern+, that understands how to make a new pattern by adding together old patterns.  We can define pattern+ as:

[define pattern+
             [patterns ... 
                [p  → [apply + [map [pattern  → [pattern p]]
                                                   patterns]]]]]

What the heck does this mean?  Well, first remember that:

So now we can understand the definition of pattern+.  It takes a variable number of arguments, all stored in the single variable "patterns" (as a list of patterns) and it returns a pattern.  A pattern is a procedure that takes a point as an argument and returns a color for the pixel at that point.  In this case, it computes that color by using map to call each of the patterns from patterns and passing it the point.  Map returns all those colors as a list, so then it passes the list to apply, along with the + procedure, to add them all together.

So, to reiterate, your job for part 2 here is to find the kinds of useful, reusable, building blocks for code that make it easier:

Think of it as making a little, simple language for expressing images.  Try to make the best language you can.  Then rewrite the code for your 10 best images to use these building blocks.

Part 3: Presentation

Okay, now make a .meta file containing:

and upload the file to the submission web site.  Do not include the actual images in the file since that will make the file huge.  Just make a simple .meta file with the code to create the images and upload that.  Don't compress it with winzip or otherwise screw around with it.

Note that you are responsible for turning in code that the reviewers will be able to understand.  This may or may not involve adding comments.  Your goal is to make the code concise, meaning short and easy to understand.  Code is like an essay.  Saying the same thing twice doesn't make it better.  So adding comments can sometimes make the code harder to read if the comments just repeat what the code already says.

But sometimes comments are necessary.  In that case, feel free to add them.  Remember that comments are enclosed in double angle brackets, which you can type by typing "<" twice (for open bracket) or ">" twice (for close bracket).

You should assume the reviewers already understand all the procedures discussed in class, so don't bother explaining what map does, what "..." means, or what a pattern is, the way I did above.

Critique

We haven't prepared critique questions yet, but you will be critiqued (separately) on both the aesthetics of the images you produce, and on the aesthetics of the code.  The aesthetics of the code would include intuitiveness, understandability, conciseness, and usefulness for creating other kinds of images.