1. Trang chủ
  2. » Công Nghệ Thông Tin

Học Actionscript 3.0 - p 27 pot

10 346 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 5,23 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

We’ll focus on the convolution, displacement map, and Perlin noise filters in this section, and then group a trio of color filters together in the following section.. Put simply, a convo

Trang 1

9 g beginFill (0xFFFF00, 1);

10 g drawRoundRect (0, 0, 200, 50, 20);

11 g endFill ();

12

13 sp filters = [ds];

14 addChild (sp);

Because we went the simple route of using a sprite for our interactive element

(rather than building a multistate button with the SimpleButton class, as seen

in the applied example at the end of Chapter 8), we need to set the buttonMode

property of the sprite to true in line 15 This won’t create the up, over, and

down states of a button symbol, but it will provide visual feedback by

chang-ing the cursor to the hand cursor when over the sprite

The listeners in lines 16 through 18 trigger functions based on mouse

behav-ior The mouse down listener function, onDown() (lines 20 to 22) removes the

drop shadow effect from the sprite by clearing the filters array Both the

mouse up and mouse out listeners point to the onUp() function in lines 23 to

25, which repopulates the filters array with the drop shadow This restores

the elevated “up” appearance to the sprite

15 sp buttonMode = true ;

16 sp addEventListener ( MouseEvent.MOUSE_DOWN , onDown, false , 0, true );

17 sp addEventListener ( MouseEvent.MOUSE_UP , onUp, false , 0, true );

18 sp addEventListener ( MouseEvent.MOUSE_OUT , onUp, false , 0, true );

19

20 function onDown(evt: MouseEvent ): void {

21 sp filters = [];

22 }

23 function onUp(evt: MouseEvent ): void {

24 sp filters = [ds];

25 }

Another way to handle this task would be to leave the ds filter active, but

change some of its properties For example, rather than eliminating the

shadow, you could reduce its distance value when the button is pressed

When the shadow appears closer to the object, the object’s virtual elevation

appears to be reduced

Using the BlurFilter to create an airbrush

With just a couple of lines of additional code, you can turn the brush from

the drawing tool developed previously in this chapter into an airbrush The

following ActionScript excerpt shows new code in bold, and can be found

in the paint_tool_erase_blur.fla source file The first new line (30) creates an

instance of the BlurFilter that blurs 40 pixels in the x and y direction The

second new line (39) applies the filter to the current tool Figure 9-10 shows

the result of softening the brush and eraser with these modifications

26 canvas addEventListener ( MouseEvent.MOUSE_DOWN ,

27 onDown, false , 0, true );

28 canvas addEventListener ( MouseEvent.MOUSE_UP , onUp,

29 false , 0, true );

30 canvas addEventListener ( Event.ENTER_FRAME , onLoop,

31 false , 0, true );

N OT E

For information about creating arrays with bracket syntax ([]), see Chapter 2.

N OT E

Filters can be used in creative ways

If you wanted to simulate casting a shadow from a moving light source, you could vary the distance, angle, and alpha values of the DropShadowFilter See the “Animating Filters” post at the companion website, http://www.

LearningActionScript3.com , for more information.

Trang 2

33 var blur: BlurFilter = new BlurFilter (40, 40);

34

35 function onDown(evt: MouseEvent ): void {

36 mouseIsDown = true ;

37 if (evt shiftKey ) {

38 tool = eraser;

39 } else {

40 tool = brush;

41 }

42 tool filters = [blur];

43 }

Advanced Filters

A number of more advanced ActionScript filters allow you to mimic some of the special effects features in pixel-editing applications like Photoshop We’ll focus on the convolution, displacement map, and Perlin noise filters in this section, and then group a trio of color filters together in the following section

Convolution filter

Convolution filtering is typically a part of many visual effects in most, if not all, pixel-editing applications Photoshop offers direct access to a convolution filter (renamed to Custom some years ago, and found in the Filters→Other

menu), but usually the filter works quietly behind the scenes

Put simply, a convolution filter calculates pixel color values by combining color values from adjacent pixels Combining these colors in different ways (using different values in the matrix) produces a wide variety of image effects These effects include, but are not limited to, blurring, sharpening, embossing, edge detection, and brightness

Using the filter effectively requires at least a working knowledge of matrices

so, if you haven’t read Chapter 8, do so now Although still a matrix, visualized

as a grid of numbers, the ConvolutionFilter doesn’t use the same matrix for-mat discussed in Chapter 8 Instead, you can define any number of rows and columns in a convolution matrix, and the structure of the matrix determines how each pixel is affected

Unless you plan to delve deeply into writing your own filters, you probably don’t need to learn the algorithms behind how a convolution matrix works

In most circumstances, you’ll use an existing matrix for a specific effect and use experimentation to determine a satisfactory setting

To give your experimenting some focus, let’s look at three parts of the matrix: the center grid element, the grid symmetry, and the sum of all grid elements Consider a 3 × 3 matrix The center value in the matrix represents the current pixel (all pixels in an image are analyzed), while the remaining elements are the eight adjacent pixels The numbers in each matrix position determine how the color values of that pixel affect the current pixel The basic idea is that each of the nine pixels is given a weight, or importance, that affects how they are altered

Figure 9-10. A Blur filter applied to

the drawing tool in the ongoing paint

application

Trang 3

Blur Brightness Edges

Figure 9-11. Example convolution filter effects

A convolution matrix of all zeros will turn an image black because no color

values are used for any pixel, including the current pixel in the center of the

grid Using a 1 in the center of an all-zero grid won’t change the image because

the current pixel is unchanged (default value of 1), and no color values from

surrounding pixels are used Placing a 2 in the center of an all-zero grid will

brighten the image because no colors from surrounding pixels are used, but

the weight of the color values of the current pixel are increased

The ConvolutionFilter constructor appearing on line 8, 14, and 20 in the

following code example requires two parameters, the number of rows and

the number of columns A third, optional parameter is the matrix used to

affect the image If no matrix is furnished a default (no change) matrix is

used Applying a default matrix allows you to remove any changes made by

prior convolution filters, as seen in the event listener that follows This code

is found in the convolution_filter_basics.fla source file

1 var black: ConvolutionFilter ;

2 var noChange: ConvolutionFilter ;

3 var brightness: ConvolutionFilter ;

4

5 var blackArr: Array = [0, 0, 0,

6 0, 0, 0,

7 0, 0, 0];

8 black = new ConvolutionFilter (3, 3, blackArr);

9 mc0 filters = [black];

10

Trang 4

11 var noChangeArr: Array = [0, 0, 0,

12 0, 1, 0,

13 0, 0, 0];

14 noChange = new ConvolutionFilter (3, 3, noChangeArr);

15 mc1 filters = [noChange];

16

17 var brightnessArr: Array = [0, 0, 0,

18 0, 2, 0,

19 0, 0, 0];

20 brightness = new ConvolutionFilter (3, 3, brightnessArr);

21 mc2 filters = [brightness];

22

23 stage addEventListener ( MouseEvent.CLICK , onClick,

24 false , 0, true );

25

26 function onClick(evt: MouseEvent ): void {

27 for ( var i: int = 0; i < 3; i++) {

28 var mc: MovieClip = MovieClip ( getChildAt (i));

29 mc filters = [noChange];

30 }

31 } Now let’s focus on the symmetry of the surrounding grid elements The remainder of the code in this section is found in the convolution_filter_more fla source file, and demonstrates centralizing the filter creation into a

func-tion called convFilter() to reduce repeating code The funcfunc-tion appears at the end of the discussion so you can focus on the matrices we’re discussing The embossUp example uses reduced values for the three pixels to the upper left

of the current pixel, and increased values for the three pixels to the lower right

of the current pixel The result is a traditional embossing effect (see Figure 9-11)

By contrast, the embossDown example reverses this effect, seemingly stamping

into the image

32 var embossUp: Array = [-1, -1, 0,

33 -1, 1, 1,

34 0, 1, 1];

35 convFilter(mc0, embossUp);

36

37 var embossDown: Array = [1, 1, 0,

38 1, 1, -1,

39 0, -1, -1];

40 convFilter(mc1, embossDown);

As our third area of interest, we want to focus on the fact that overall image brightness is affected by the sum of all elements in the matrix In each of the prior examples, all the matrix elements add up to 1, except brighter (which

adds up to 2) and black (which adds up to 0) The following example is a

matrix that uses the left, top, right, and bottom adjacent pixel color values to affect the current pixel The result is a blurring effect However, a dramatic brightening of the image occurs because the sum of the matrix elements is 5, not 1 The affected image is five times brighter

If this is not desired, you can compensate by using an optional fourth param-eter of the ConvolutionFilter class, called a divisor The sum of the matrix will be divided by this value and the result will affect the brightness If the

Trang 5

result is 1, the brightening effect of the matrix will be eliminated The first

filter instance here uses only the first three parameters without compensating

for brightness The second instance adds the divisor as the fourth parameter,

bringing the brightness back to the original state, leaving only the blur effect

41 var blurBright: Array = [0, 1, 0,

42 1, 1, 1,

43 0, 1, 0];

44 convFilter(mc2, blurBright);

45

46 var blurOnly: Array = [0, 1, 0,

47 1, 1, 1,

48 0, 1, 0];

49 convFilter(mc3, blurOnly, 5);

As a summary of what we’ve learned, we’ll look at how sharpen and find

edges filters differ The sharpen instance that follows uses negative values for

the left, top, right, and bottom pixels, which is the opposite of blur and causes

the pixels to pop The sum of the matrix is 1, meaning there is no increase or

decrease in brightness

The edges instance uses the same values for the surrounding pixels, but the

sum of the array is 0 This has a sharpening effect but reduces the brightness,

leaving only the emphasized edges visible

50 var sharpen: Array = [ 0, -1, 0,

51 -1, 5, -1,

52 0, -1, 0];

53 convFilter(mc4, sharpen);

54

55 var edges: Array = [ 0, -1, 0,

56 -1, 4, -1,

57 0, -1, 0];

58 convFilter(mc5, edges);

The function that applies these matrices differs from the prior source file in

only one major respect: It provides for the use of the fourth optional

param-eter, divisor, to compensate for accumulated brightness.

59 function convFilter(dispObj: DisplayObject , matrix: Array ,

60 divisor: int =1): void {

61 var conv: ConvolutionFilter =

62 new ConvolutionFilter (3, 3, matrix, divisor);

63 dispObj filters = [conv];

64 }

Perlin noise and displacement map

Two other very useful and entertaining effects supported by ActionScript

are the Perlin noise generator and the displacement map filter Perlin noise

is widely used for generating naturalistic animated effects like fog, clouds,

smoke, water, and fire, as well as textures like wood, stone, and terrain

Displacement maps are used to translate (or displace) pixels to add extra

dimension to surfaces They are commonly used to add realism to textures

(such as a pitted or grooved surface) as well as distort images to appear as if

seen through a refracting material like glass or water

N OT E

Ken Perlin developed the Perlin noise algorithm while creating the special effects for the 1982 film Tron At the time, the extensive use of effects in that film may have been cost-prohibitive using traditional multi-exposure film compositing techniques Perlin noise was used to manipulate the near-constant computer-generated glows and shad-ings, among other effects Mr Perlin won an Academy Award for Technical Achievement in 1997 for his contribu-tions to the industry.

Trang 6

The following exercise, found in the perlin_displacement.fla source file, will

cre-ate an animcre-ated Perlin noise texture that will then be used as the source for a displacement map In our example, the Perlin noise will include random areas

of blue, as shown in Figure 9-12 These blue areas will cause the displacement

in a photo of a reef aquarium, and the combined effect will cause soft corals in the scene to undulate as if experiencing the effect of water currents

The source material we’ll use is a picture of a reef aquarium, as seen in Figure 9-13 The sea life are the sole elements in a foreground image, and will be affected by the filters so that they will appear to be moving in the water cur-rent The rock is in a separate background and will not be affected

Perlin noise

The first step in building our aquarium simulation is to create a BitmapData object to contain the Perlin noise Our image will cover the stage, so we’ll pass the stage width and height into the object to size it appropriately (line 1) Lines 3 and 4 create a bitmap using the bitmap data, and then add that bitmap to the display list However, the lines are commented out because we

do not want to see the Perlin noise in the final product We need access only

to the bitmap data to drive the displacement map However, it’s often help-ful to see the Perlin noise as you work so you can experiment with various settings By uncommenting these lines, you can adjust the Perlin noise values until you’re satisfied with the effect, and then comment out these lines again when moving on to the displacement filter

1 var bmpData: BitmapData = new BitmapData ( stage.stageWidth ,

2 stage.stageHeight );

3 //var bmp:Bitmap = new Bitmap(bmpData);

4 //addChild(bmp);

5 //comment out lines 3 and 4 to see Perlin noise

The Perlin noise generator has a number of settings that will produce dra-matically different results when adjusted As we discuss these settings, we’ll reference natural phenomena, like water and smoke We’ll first discuss the settings of the filter and then simply pass these settings into the perlin-Noise() method later on in lines 30 through 32.

Lines 7 and 8 set the scale of the texture in the x and y directions Think of this as influencing the number of waves you can see at one time in water A very large scale might result in the look of a swelling sea, and a small scale might look like a babbling brook

Line 7 determines the number of octaves in the texture, which are discreet layers of noise that function independently of each other A single-octave noise will not be as complex as a multi-octave noise and, during animation, you can move a single-octave noise in only one direction at a time You can create basic animations with single octaves, like the look of running water

or, in our case, underwater current But the ability to move each octave in a different direction makes multi-octave noise better suited for effects like col-liding waves moving in multiple directions, or fire, or smoke

Figure 9-12. Perlin noise texture

Figure 9-13. Elements of the Perlin noise

and displacement map filter exercise

Trang 7

Line 10 creates a random seed to influence the starting point for the creation

of the texture A random seed allows you to randomize the effect but also call

back that same result by using the same seed at a later time In our case, we

only care about the randomization, so we’ll use a random number, between

0 and 100, for the seed as well

6 //perlin noise settings

7 var baseX: Number = 50;

8 var baseY: Number = 50;

9 var numOctaves: Number = 1;

10 var randomSeed: Number = Math.random () * 100;

11 var stitch: Boolean = true ;

12 var fractalNoise: Boolean = true ;

13 var channelOptions: Number = BitmapDataChannel.BLUE ;

14 var grayScale: Boolean = false ;

15 var offsets: Array = new Array ( new Point ());

Line 11 determines whether the edges of the area defined when creating the

noise pattern are stitched together in an attempt to create a seamless tile

When creating static textures, this “stitching” is not usually needed, but it’s

recommended when animating the effect

Whether fractal noise or turbulence techniques are used when generating

the effect is determined by line 12 Fractal noise (used when the fractalNoise

property is true) generates a smoother effect; turbulence (used when the

fractalNoise property is false) produces more distinct transitions between

levels of detail For example, fractal noise might be used to create a terrain

map of rolling hills or an oceanscape, and turbulence might be better suited

to a terrain of mountains or crevices in a rock

Line 13 chooses which channels of bitmap data are used when generating

the texture: red, green, blue, and/or alpha These can be indicated by

con-stants from the BitmapDataChannel class or with integers You can also use a

special operator called the bitwise OR operator (|) to combine channels to

create multicolor effects or combine color with alpha For example,

combin-ing alpha with noise can create fog or smoke with transparent areas through

which a background can be seen

In this exercise, because we are generating a pattern only to provide data for

a displacement map, we need only one channel (Blue was chosen arbitrarily.)

However, experimenting with the Perlin noise settings can make it difficult

to visualize the texture’s effect To improve these efforts a bit, you can add

alpha data to the mix, so you can see the underlying image through the

pat-tern Figure 9-14 shows the visible noise texture and the reef beneath it In our

finished example, the anemones will be displaced to a greater degree where

blue is more visible

To see the background image as you experiment with the noise settings, you

just have to add an alpha channel to the channelOptions property To do this,

replace line 13 with this:

13 var channelOptions: Number = BitmapDataChannel.BLUE |

BitmapDataChannel.ALPHA ;

N OT E

Perlin noise layers are called octaves because, like musical octaves, each one doubles the frequency of the previous octave, increasing detail within the tex-ture It’s also important to note that the processor power required to generate noise patterns increases with the num-ber of octaves used.

Figure 9-14. Perlin noise detail without alpha data

Trang 8

The grayscale parameter in line 14 desaturates the texture so it generates

only grays In our exercise, the texture won’t be visible, so this isn’t relevant, but it’s ideal when visible fog or smoke is required

Finally, line 15 uses an array of offset points, one for each octave, to control the location of the noise pattern generated We need only one octave in this example, so this is a single-item array Because the texture will not be visible, its starting point is arbitrary, so we’ll use a default point of (0, 0) During animation, we’ll alter the position of this point to move the pattern

You’ve now set all the values required to create a Perlin noise texture If you want to see the noise before moving on to the next section, look at the per-lin_noise_only.fla source file Later, we’ll animate these values by changing the

offset values upon every enter frame event First, however, we need to set up the displacement map settings

Displacement map

The displacement map filter is a bit simpler Lines 18 and 19 of the script that follows determine which color channel will affect the distortion in each direction We used the blue channel when creating our Perlin noise texture,

so we’ll use the same channel here

Next, lines 20 and 21 set the scale of displacement in the x and y directions Think of these values as the size of the waves when looking through water, or the degree of refraction when looking through glass, in each direction

16 //displacement map settings

17 var displaceMap: DisplacementMapFilter ;

18 var componentX: uint = BitmapDataChannel.BLUE ;

19 var componentY: uint = BitmapDataChannel.BLUE ;

20 var xScale: Number = 10;

21 var yScale: Number = 10;

22 displaceMap = new DisplacementMapFilter (bmpData, new Point (),

23 componentX, componentY, xScale, yScale,

24 DisplacementMapFilterMode.CLAMP );

Finally, lines 22 through 23 determine how the edges of the displacement map will behave When set to clamp, any displacement will be confined by

the edges of the source data If wrap, is used, the distortion will wrap around

from edge to edge The wrap option is great for tiled patterns but not useful

for affecting a realistic image of a recognizable object You don’t want to see the top of a person’s head appearing beneath their feet as a displacement wraps from top to bottom edge

Now that our settings are complete, we create the DisplacementMapFilter

in lines 22 through 24 The source for the displacement data is the same

BitmapData object that is being affected by the Perlin noise pattern, so the

degree of displacement will be determined by that bitmap data, passed into the class in the first parameter The second parameter is the map point—the location at which the upper-left corner of the displacement map filter will

be applied This is useful for filtering only a portion of the image We want

Trang 9

to filter the entire image, however, so we’ll pass in a default point to begin

filtering at (0, 0) The remainder of the parameters correspond directly to the

settings previously created

Animating the effect

To animate the Perlin noise, and therefore the displacement map effect, we

start with a listener that triggers the onLoop() function upon every enter

frame event The first thing the function does is update the offset point for

the Perlin noise octave, seen in lines 28 and 29 This example sets the offset

point of the octave, not the location of a display object (see the adjacent note

for more information) Lines 28 and 29 move the first octave (the only octave

used in our example) up and to the right, 2 pixels in each direction

With each change to the offset point, the perlinNoise() method is called

(line 30), applying all the previously set parameters along with the offset

update Finally, with the call of the Perlin noise method, the DisplacementMap

filter source data is updated, so the DisplacementMap filter must be reapplied

to the display object in line 33

25 //enter frame update of both filters

26 addEventListener ( Event.ENTER_FRAME , onLoop, false , 0, true );

27 function onLoop(evt: Event ): void {

28 offsets[0] x -= 2;

29 offsets[0] y += 2;

30 bmpData perlinNoise (baseX, baseY, numOctaves, randomSeed,

31 stitch, fractalNoise, channelOptions,

32 grayScale, offsets);

33 tank_mc filters = [displaceMap];

34 }

Color Effects

You can apply color effects using ActionScript in multiple ways, and we’ll

look at three The first is relatively straightforward: Alter the emphasis of

individual color channels (red, green, blue, and alpha) in an image using the

ColorTransform class The second is a more powerful technique that uses the

ColorMatrixFilter to apply a detailed matrix to simultaneously change all

color and alpha channels The last method discussed is the simplest, using

the Color class to apply a tint to a display object

The ColorTransform Class

Although we’ll focus exclusively on color, you can use the ColorTransform

class to adjust the alpha channel as well as the individual color channels of

a display object or BitmapData object In the examples that follow, we’ll be

using the class to invert an image (create a color negative) and apply a simple

saturation effect

N OT E

Animating an octave with the offset property is not the same as moving a display object Instead, think of adjust-ing the offset position of an octave as adjusting that octave’s registration point

If you move a movie clip five pixels

in the x and y directions, it will move down and to the right However, if you adjust the movie clip’s registration point, down and to the right, the clip won’t move on stage, but its contents will move up and to the left

Trang 10

The class offers two ways to change color First, you can multiply a color chan-nel to increase or decrease its effect For example, you can double the weight of the color by using a multiplier of 2, and you can reduce the weight of the color

by half by using 0.5 as a multiplier Second, you can offset a color channel from –255 to 255 For example, assuming a default multiplier of 1 (no change from the multiplier), an offset value of 255 would maximize the red channel, 0 would apply no change, and –255 would remove all red from the image

The following code, found in the color_transform.fla source file, manipulates

three movie clips instantiated as mc0, mc1, and mc2 Lines 1 through 10 show the default ColorTransform instance, which makes no change to the source material Also, by using this default configuration (with a multiplier of 1 and an offset of 0 on each channel), you can effectively reset any prior color transformation Despite the example’s focus on color, we’ve included alpha multiplier and offset values to show the complete syntax of a reset

Note that the ColorTransform class is not a filter, so it’s not applied to the

fil-ters property of a display object Instead, the color transformation is applied

to the colorTransform property of a display object’s transform object (line

10) Similar to the filtering process, however, every time a change is made to the color transformation, it must be reapplied to the colorTransform property Lines 12 through 19 provide for an increase in saturation The offset values

of all colors are unchanged, but the color multipliers increase the color for each channel To emphasize the image, the values used increase red more than green and blue This effect can be seen in the “Saturation” example in Figure 9-15 You could also partially desaturate an image using the same technique but applying a multiplier value of less than 1 to each color channel

Finally, lines 21 through 28 invert all color in the image The multiplier for all color channels is set to –1, which effectively turns the image black, and then the offset values are set to full to revert back to color This effect can be seen

in the “Invert” example from Figure 9-15

1 var noChange: ColorTransform = new ColorTransform ();

2 noChange redOffset = 0;

3 noChange greenOffset = 0;

4 noChange blueOffset = 0;

5 noChange alphaOffset = 0;

6 noChange redMultiplier = 1;

7 noChange greenMultiplier = 1;

8 noChange blueMultiplier = 1;

9 noChange alphaMultiplier = 1;

10 mc0 transform.colorTransform = noChange;

11

12 var saturation: ColorTransform = new ColorTransform ();

13 saturation redOffset = 0;

14 saturation greenOffset = 0;

15 saturation blueOffset = 0;

16 saturation redMultiplier = 1.3;

17 saturation greenMultiplier = 1.1;

18 saturation blueMultiplier = 1.1;

19 mc1.tr ansform.colorTransform = saturation;

20

Original

Saturation       

Invert

Figure 9-15. ColorTransform filter effects

Ngày đăng: 06/07/2014, 18:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN