Top Banner
twelve painting with procedures
54

Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Dec 21, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

twelve

painting with procedures

Page 2: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Overview

Making shaded images with procedures Making a more elegant language Making textures with noise functions

Page 3: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making bitmaps

[bitmap-from-procedure procedure width height] Returns a bitmap width pixels by height pixels Obtains colors for pixels by calling procedure

Passes procedure a point (vector) object with the coordinates

Procedure returns a color object (color image) or a single number (grayscale image)

Page 4: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making a grayscale ramp

We can use dot products to make a grayscale ramp

The dot-product of two vectors is a single number

It increases as The first vector grows in the

direction of the second, or alternatively,

The second grows in the direction of the first

i.e. it’s symmetrical Each vector gets bigger

By manipulating the direction of the vector in the dot-product, we can get different directions for the ramp

[bitmap-from-procedure[p → [dot p [vector 0.5 0.5]]]256256]

Page 5: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Changing the vector direction

[bitmap-from-procedure[p → [dot p [vector 1 0]]]256256]

[bitmap-from-procedure[p → [dot p [vector 0 1]]]256256]

Page 6: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Clipping

Why is this one different? The display only has the

ability to produce amounts of light in the range 0-255

[bitmap-from-procedure[p → [dot p [vector 1 1]]]256256]

Page 7: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Constructive laziness

It’s bad to keep typing the same arguments over and over again Slows you down Frustrates you Leads to errors

So make a new procedure that Just takes the parameter

we care about and Fills in the rest for us

[define show [procedure →

[bitmap-from-procedure procedure 256 256]]]

Now we can just say: [show [p → [dot p [vector 1 1]]]]

Page 8: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making it (slightly) more efficient

This version calls the vector procedure for each pixel

Wasteful Arguments are always the

same Same vector is always

returned (more or less) We only need to call it once

So we can call it once and save it in a local variable

[show [p → [dot p [vector 1 1]]]]

[show [with vec = [vector 1 1] [p → [dot p vec]]]

Page 9: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making another pattern

The magnitude procedure gives the length of the vector passed to it

So using it as the painting function for a bitmap gives us

A radial pattern That’s black at (0,0) And grows white farther away

Like a grayscale ramp, but circular

[show magnitude]

Page 10: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Question

What’s the difference between:

magnitude

and:[p → [magnitude p]]

Nothing; they behave the same Both take a vector as input And return its magnitude

as output

[show magnitude][show [p → [magnitude p]]]

Page 11: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Shifting it over

How do we shift it so that the black part is in the center of the image?

We shift the vector we’re taking the magnitude of We use − to shift vectors

What vector do we subtract off? It’s a 256×256 image So the center is (128, 128)

[show [p → [magnitude [− p [vector 128 128]]]]]

Page 12: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making it brighter

Now it’s too dark How do we fix it?

Brighten by multiplying Multiplying by 2 Doubles the brightness Although now it clips

[show [p → [× 2 [magnitude [− p [vector 128 128]]]]]]

Page 13: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

White on black

Okay, but what if we want it to be white in the center and black on the outside? How do we fix it?

Just subtract The brightness computed

brightness From 255 (the maximum

brightness)

[show [p → [− 255 [× 2 [magnitude [− p [vector 128 128]]]]]]]

Page 14: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Overview

Making shaded images with procedures Making a more elegant language Making textures with noise functions

Page 15: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Thinking about it differently

We started with a simple pattern (magnitude)

We shifted it over We brightened it We inverted it

But the code doesn’t make that clear Can we make the code

reflect our intentions more clearly?

[show [p → [− 255 [× 2 [magnitude [− p [vector 128 128]]]]]]]

Page 16: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Making the code clearer

We’d like to be able to write the code like this Take the magnitude image Shift it by [vector 128 128] Brighten it And invert it

Can we make Meta work this way?

[show[invert [brighten 2 [shift [vector 128 128] magnitude]]]]

Page 17: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Procedures that operate on whole patterns

Let’s call A pattern a procedure that

takes a point and returns a brightness

A pattern operator a procedure that takes a pattern and returns a new pattern

If we had pattern operators For shifting, brightening, and

inverting We could write the code much

more clearly

[shift vector pattern] Makes a new pattern that’s

pattern shifted over by vector [brighten level pattern]

Makes a new pattern that’s like pattern but with its brightness multiplied by level

[invert pattern] Makes a new pattern that’s

the same as pattern, but with black exchanged for white

Page 18: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Programming with pattern operators

Now we can take the magnitude pattern Since magnitude takes

a point as input And returns a number

So we can use it as a pattern

[show magnitude]

Page 19: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Programming with pattern operators

Now we can take the magnitude pattern

Shift it

[show [shift [vector 128 128] magnitude]]

Page 20: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Programming with pattern operators

Now we can take the magnitude pattern

Shift it Brighten it

[show [brighten 2 [shift [vector 128 128] magnitude]]]

Page 21: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Programming with pattern operators

Now we can take the magnitude pattern

Shift it Brighten it And invert it

Now we don’t even need to know that patterns are really procedures

[show[invert [brighten 2 [shift [vector 128 128] magnitude]]]]

Page 22: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing brighten Okay, now let’s write brighten

Remember we want to be able to say something like:

[brighten 2 [p → [magnitude p]]]

And get back something that behaves like:

[p → [× 2 [magnitude p]]]

► [define brighten ???]

Page 23: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing brighten

Okay, now let’s write brighten

Brighten must Take a brightness level and a

pattern as arguments

► [define brighten [level pattern → ???]]

Page 24: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing brighten

Okay, now let’s write brighten

Brighten must Take a brightness level and a

pattern as arguments Return a new procedure that

Takes a point as an argument

► [define brighten [level pattern → [p → ???]]]

Page 25: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing brighten

Okay, now let’s write brighten

Brighten must Take a brightness level and a

pattern as arguments Return a new procedure that

Takes a point as an argument And computes the correct

brightness

► [define brighten [level pattern → [p → [× level [pattern p]]]]]

Page 26: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Higher-order procedures

Brighten is called a “higher-order” procedure It takes a procedure as

input And returns a new

procedure as a result

Procedures that make new procedures are perfectly acceptable And very useful

[define brighten [level pattern → [p → [× level [pattern p]]]]]

[brighten 2 magnitude]= [p →

[× 2 [magnitude p]]]

[brighten 3 magntidue]= [p → [× 3 [magnitude p]]]

[brighten 3 [brighten 2 magnitude]]

= [p → [× 3 [ [p → [× 2 [magnitude p]]] p]]

≈ [p → [× 3 [× 2 [magnitude p]]]]

Page 27: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing invert

Okay, now let’s write invert ► [define invert ???]

Page 28: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing invert

Okay, now let’s write invert

Invert must Take a a pattern

► [define invert [pattern → ???]]

Page 29: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing invert

Okay, now let’s write invert

Invert must Take a a pattern Return a new procedure that

Takes a point as an argument

► [define invert [pattern → [p → ???]]]

Page 30: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing invert

Okay, now let’s write invert

Invert must Take a a pattern Return a new procedure that

Takes a point as an argument And computes the correct

brightness

► [define invert [pattern → [p → [− 255 [pattern p]]]]]

Page 31: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing shift

Patterns are procedures

So shift is a higher order procedure

It takes a procedure as an argument

And returns a new procedure as its result

► [define shift ???]

Page 32: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing shift

Patterns are procedures

So shift is a higher order procedure

It takes a procedure as an argument

And returns a new procedure as its result

Shift must Take an offset and a pattern as

arguments

► [define shift [offset pattern → ???]]

Page 33: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing shift

Patterns are procedures

So shift is a higher order procedure

It takes a procedure as an argument

And returns a new procedure as its result

Shift must Take an offset and a pattern as

arguments Return a new procedure that

Takes a point as an argument

► [define shift [offset pattern → [p → ???]]]

Page 34: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Writing shift

Patterns are procedures

So shift is a higher order procedure

It takes a procedure as an argument

And returns a new procedure as its result

Shift must Take an offset and a pattern as

arguments Return a new procedure that

Takes a point as an argument And computes the correct

brightness

► [define shift [offset pattern → [p → [pattern [− p offset]]]]]

Page 35: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Repeated patterns

[mod a b] For positive numbers,

returns the remainder when dividing a by b

When a is negative, returns b minus the remainder

This turns out to be just the right thing to make a repeated texture

[define replicate[width height pattern → [p → [pattern [point [mod p.X width]

[mod p.Y height]]]]]]

[show [replicate 64 64 magnitude]]

Page 36: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Repeated patterns

[brighten 8 [replicate 64 64 [shift [point 32 32] magnitude]]]]

[replicate 64 64 [invert magnitude]]

Page 37: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

And now, in color …

[define colorize[r-pattern g-pattern b-pattern → [p → [color [r-pattern p] [g-pattern p] [b-pattern p]]]]]

Takes three grayscale patterns and combines them into a single color pattern

Page 38: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Groovy, man

[colorize [brighten 8 [replicate 64 64 [shift [point 32 32] magnitude]]] [replicate 64 64 [invert magnitude]]

[p → 50]]]

Page 39: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Groovy, man

[colorize [brighten 8 [replicate 64 64 [shift [point 32 32] magnitude]]] [replicate 64 64 [p → [dot p [point 1 1]]]]

[p → 50]]]

Page 40: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Overview

Making shaded images with procedures Making a more elegant language Making textures with noise functions

Page 41: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Spatial frequencies

Pictures can be thought of as having harmonic structure

Like sound Picture can be thought of as

many different frequencies combined

We won’t go into this in any detail, but …

Frequency corresponds roughly to size

Fine detail is high frequency Bigger structures are lower

frequeny

Page 42: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

White noise

White noise is a random signal Every pixel (sample)

computed using a random number generator

Called “white” because it contains equal amounts of all frequencies

Not very interesting as a texture

► [show [p → [random-integer 0 255]]]

Page 43: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Bandpass noise

But now suppose we zoom in between the randomly chosen pixel values

And smoothly interpolate between them

The result is still a random texture, but it’s missing the very high and very low frequencies

[noise point] Interpolated noise Gaussian distribution Result is between -0.7 and 0.7

[show [p → [+ 128 [× 128 [noise [ ⁄ p 30]]]]]]

Page 44: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Bandpass noise at different frequences

[show [p → [+ 128 [× 128 [noise [ ⁄ p 10]]]]]]

[show [p → [+ 128 [× 128 [noise [ ⁄ p 80]]]]]]

Page 45: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Summing bandpass noise

You can get interesting effects by summing bandpass noise at different frequencies

[show [p → [+ 128 [× 128 [+ [noise [ ⁄ p 80]] [noise [ ⁄ p 40]] [noise [ ⁄ p 20]]]]]]]

Page 46: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

“1/f noise”

Important kind of noise Amplitude of frequency f is 1/f Self-similar (like fractals)

Zoom in on it and it still looks like itself

Approximated using bandpass noise

Compute at different scales Sum with weights that vary

inversely with frequency

Also known as Brown noise (Brownian motion) Turbulence

[show [p → [+ 128 [× 128 [+ [noise [ ⁄ p 80]] [ ⁄ [noise [ ⁄ p 40]] 2] [ ⁄ [noise [ ⁄ p 20]] 4]]]]]]

Page 47: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Perlin noise

Ken Perlin (1985) Technique for

approximating 1/f noise using interpolated bandpass noise

Built into most graphics cards

[turbulence point] Computes a sum of many

calls to noise All you really need to

understand for this class

[show[p → [+ 128 [× 128 [turbulence [ ⁄ p 30]]]]]]

Page 48: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Annoying bug/misfeature

You have to divide p by some number before calling noise or turbulence The noise function returns 0 for all points

whose coordinates are both integers So you have to divide by something to make

sure the coordinates are usually not integers

Page 49: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

The Art of Noise

[show[p → [× 255 [turbulence [ ⁄ p 30]]]]]

Noise clips on low end

[show[p → [abs [× 255 [turbulence [ ⁄ p 30]]]]]]

Abs produces abrupt change on low end

Page 50: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

The Art of Noise

[show[with center = [point 128 128] [p → [× 255 [sin [+ [ ⁄ [magnitude [− p center]] 10]

[turbulence [ ⁄ p 30]]]]]]]

Noise used in input to another function (sin)

[show[p → [× 255 [sin [+ [turbulence [ ⁄ p 20]] [dot p [point 0.1 0.1]]]]]]]

Page 51: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Extra arguments to turbulence Turbulence works by calling noise at

different frequencies and summing

You can call turbulence with three extra arguments

Drop-off factor Amplitude of the new noise component

drops by this factor each iteration Frequency multiplier

Frequency get multiplied by this each iteration

Iteration count

Try playing with the extra arguments The default values are 2, 2, and 4

[show[p → [+ 127 [× 128 [turbulence [ ⁄ p 30] 1.5 2 8]]]]]

Page 52: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Extra arguments to turbulence Turbulence works by calling noise at

different frequencies and summing

You can call turbulence with three extra arguments

Drop-off factor Amplitude of the new noise component

drops by this factor each iteration Frequency multiplier

Frequency get multiplied by this each iteration

Iteration count

Try playing with the extra arguments The default values are 2, 2, and 4

[show[p → [+ 127 [× 128 [turbulence [ ⁄ p 30] 5 2 8]]]]]

Page 53: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

The Art of Noise

[show[p → [× 256

[turbulence [× 0.001 p.X p.Y]]]]]

You can also call noise or turbulencewith a number as an argument (rather than a point)

[show[p → [× 256 [cos [× 10 [turbulence [ ⁄ p 50]]]]]]]

Page 54: Twelve painting with procedures. Overview Making shaded images with procedures Making a more elegant language Making textures with noise functions.

Using the code from today’s lecture

Meta is distributed with the code for brighten, invert, etc.

To load it and make it available, just type:[using Examples.Painting] Doing it twice won’t hurt anything You only need to do this when you start using Meta But you have to do it over again if you exit Meta and

run it again later