Download presentation
Presentation is loading. Please wait.
1
painting with procedures
twelve painting with procedures
2
Overview Review The dot product Making shaded images with procedures
Making a more elegant language Making textures with noise functions
3
Color objects [color name] [color red green blue]
Returns color with the specified name [color red green blue] Returns color with the specified amounts of red, green, and blue light Arguments should be 0-255 [red c] or c.R [green c] or c.G [blue c] or c.B Returns the amount of red/green/blue light in the color c
4
Color operations [+ color color] [× number color], [ ⁄ color number]
Adds together the light of the two colors to form a new color [× number color], [ ⁄ color number] Brightens/dims color by the factor number [intensity color] Returns the total amount of light in the color from 0-255 This was called brightness in assignment 3 [gray intensity] Returns a neutral gray color with the specified intensity (0-255)
5
Vectors (aka points) Used to represent positions in the image or displacements between positions [vector x y] or: [point x y] Returns a vector object with the specified coordinates [vector-x p] or: [point-x p], p.X [vector-y p] or: [point-y p], p.Y Returns x (or y) coordinate of p
6
Vector operations [+ vector vector], [− vector vector]
Returns the sum/difference of two vectors (points) Sum shifts the first vector over by the amount of the second vector (or vice-versa) Difference shifts the first one back [× number vector], [ ⁄ vector number] Returns vector stretched/shrunk by a factor of number [rotate-vector vector angle] [rotate-vector-degrees vector angle] Rotates the vector about the origin [magnitude vector] Returns the length of the vector vector
7
What’s the difference between a vector and a point?
In this class, the terms are interchangeable Both are used in the literature They technically mean slightly different things, but the distinctions don’t matter for this class We’re teaching you both terms, but you don’t need to worry about them I’ll adopt the convention of using [point x y] when I really mean a position in the image [vector x y] when I mean a shift or a direction, but not a specific position in the image I don’t care whether you follow this convention
8
Overview Review The dot product Making shaded images with procedures
Making a more elegant language Making textures with noise functions
9
The “dot” product Enigmatic [dot p1 p2] Definitions: Measures
[+ [× p1.X p2.X] [× p1.Y p2.Y]] [× [magnitude p1] [magnitude p2] [cos [angle-between p1 p2]]] Also known as Projection Scalar product Inner product Enigmatic But very common in graphics, signal processing (music), statistics Measures Similarity between vectors p1 and p2 Distance p1 extends in the direction of p2 (or vice-versa) When p1 is one unit long (i.e. a “unit vector”) Returns the number of units p2 extends in the direction of p1. Modern video cards have special hardware to compute dot products as fast as possible
10
Dot product examples p2 = [vector 1.5 3] Y axis p3 = [vector 0 2]
[dot p1 p2] = 1×1.5+0×3 = 1.5 [dot p1 p3] = 1×0 + 0×2 = 0 [dot p3 p2] = 0×1.5+2×3 = 6 ←1.5 units → p1 = [vector 1 0] X axis
11
Overview Review The dot product Making shaded images with procedures
Making a more elegant language Making textures with noise functions
12
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 vector object with the coordinates Procedure returns a color object (color image) or a single number (grayscale image)
13
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 ]]] ]
14
Changing the vector direction
[bitmap-from-procedure [p → [dot p [vector 1 0]]] ] [bitmap-from-procedure [p → [dot p [vector 0 1]]] ]
15
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]]] ]
16
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 ]]] Now we can just say: [show [p → [dot p [vector 1 1]]]]
17
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]]]
18
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]
19
Question What’s the difference between: and:
magnitude and: [p → [magnitude p]] Nothing; they behave the same Both take a vector as input And return its magnitude as output [show [p → [magnitude p]]]
20
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 ]]]]]
21
Making it brighter Now it’s too dark Brighten by multiplying
How do we fix it? Brighten by multiplying Multiplying by 2 Doubles the brightness Although now it clips [show [p → [× [magnitude [− p [vector ]]]]]]
22
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 → [− [× [magnitude [− p [vector ]]]]]]]
23
Overview Review The dot product Making shaded images with procedures
Making a more elegant language Making textures with noise functions
24
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 → [− [× [magnitude [− p [vector ]]]]]]]
25
Making the code clearer
We’d like to be able to write the code like this Take the magnitude image Shift it by [vector ] Brighten it And invert it Can we make Meta work this way? [show [invert [brighten [shift [vector ] magnitude]]]]
26
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
27
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]
28
Programming with pattern operators
Now we can take the magnitude pattern Shift it [show [shift [vector ] magnitude]]
29
Programming with pattern operators
Now we can take the magnitude pattern Shift it Brighten it [show [brighten [shift [vector ] magnitude]]]
30
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 [shift [vector ] magnitude]]]]
31
Writing brighten ► [define brighten ???]
Okay, now let’s write brighten Remember we want to be able to say something like: [brighten [p → [magnitude p]]] And get back something that behaves like: [p → [× 2 [magnitude p]]] ► [define brighten ???]
32
Writing brighten Okay, now let’s write brighten Brighten must
Take a brightness level and a pattern as arguments ► [define brighten [level pattern → ???]]
33
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 → ???]]]
34
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]]]]]
35
Writing invert Okay, now let’s write invert ► [define invert ???]
36
Writing invert Okay, now let’s write invert Invert must
Take a a pattern ► [define invert [pattern → ???]]
37
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 → ???]]]
38
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 → [− [pattern p]]]]]
39
Writing shift ► [define 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 ???]
40
Writing shift ► [define shift [offset pattern → ???]]
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 → ???]]
41
Writing shift ► [define shift [offset pattern → [p → ???]]]
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 → ???]]]
42
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]]]]]
43
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 magnitude]]
44
Repeated patterns [brighten [replicate [shift [point 32 32] magnitude]]]] [replicate [invert magnitude]]
45
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
46
Groovy, man [colorize [brighten [replicate [shift [point 32 32] magnitude]]] [replicate [invert magnitude]] [p → 50]]]
47
Groovy, man [colorize [brighten [replicate [shift [point 32 32] magnitude]]] [replicate [p → [dot p [point 1 1]]]] [p → 50]]]
48
Overview Review The dot product Making shaded images with procedures
Making a more elegant language Making textures with noise functions
49
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
50
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]]]
51
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 → [ [× [noise [ ⁄ p 30]]]]]]
52
Bandpass noise at different frequences
[show [p → [ [× [noise [ ⁄ p 10]]]]]] [show [p → [ [× [noise [ ⁄ p 80]]]]]]
53
Summing bandpass noise
You can get interesting effects by summing bandpass noise at different frequencies [show [p → [ [× [+ [noise [ ⁄ p 80]] [noise [ ⁄ p 40]] [noise [ ⁄ p 20]]]]]]]
54
“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 → [ [× [+ [noise [ ⁄ p 80]] [ ⁄ [noise [ ⁄ p 40]] ] [ ⁄ [noise [ ⁄ p 20]] ]]]]]]
55
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 → [ [× [turbulence [ ⁄ p 30]]]]]]
56
Caveat 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
57
The Art of Noise [show [p → [× 255 [turbulence [ ⁄ p 30]]]]]
Noise clips on low end [show [p → [abs [× [turbulence [ ⁄ p 30]]]]]] Abs produces abrupt change on low end
58
The Art of Noise [show [with center = [point ] [p → [× [sin [+ [ ⁄ [magnitude [− p center]] ] [turbulence [ ⁄ p 30]]]]]]] Noise used in input to another function (sin) [show [p → [× [sin [+ [turbulence [ ⁄ p 20]] [dot p [point ]]]]]]]
59
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 → [ [× [turbulence [ ⁄ p 30] ]]]]]
60
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 → [ [× [turbulence [ ⁄ p 30] ]]]]]
61
The Art of Noise [show [p → [× 256 [turbulence [× 0.001 p.X p.Y]]]]]
You can also call noise or turbulence with a number as an argument (rather than a point) [show [p → [× [cos [× [turbulence [ ⁄ p 50]]]]]]]
62
Using the code from today’s lecture
[using Examples.Painting]
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.