How does DisplacementMapFilter work?

I am new to ActionScript. If I understand correctly, DisplacementMapFilter moves pixels from the "source image" according to the color of the corresponding pixel position in the "MAP image".

The problem is that my destination image contains pixels that are NOT in the original image!

For example, I take the original UNICOLOR image of 10 * 10 pixels with this BitMapData:

sourceBitmap = new BitmapData(BITMAP_WIDTH, BITMAP_HEIGHT, false, 0x000002); produce: 0 1 2 3 4 5 6 7 8 9 [002,002,002,002,002,002,002,002,002,002] Row 0 [002,002,002,002,002,002,002,002,002,002] Row 1 [002,002,002,002,002,002,002,002,002,002] Row 2 [002,002,002,002,002,002,002,002,002,002] Row 3 [002,002,002,002,002,002,002,002,002,002] Row 4 [002,002,002,002,002,002,002,002,002,002] Row 5 [002,002,002,002,002,002,002,002,002,002] Row 6 [002,002,002,002,002,002,002,002,002,002] Row 7 [002,002,002,002,002,002,002,002,002,002] Row 8 [002,002,002,002,002,002,002,002,002,002] Row 9 

Now, I take this BLACK MAP move and I add a little BLUE square:

 displacementBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0x000000); for(i=5;i<10;i++) for(j=5;j<10;j++) displacementBitmap.setPixel(i,j,255); produce: 0 1 2 3 4 5 6 7 8 9 [000,000,000,000,000,000,000,000,000,000] Row 0 [000,000,000,000,000,000,000,000,000,000] Row 1 [000,000,000,000,000,000,000,000,000,000] Row 2 [000,000,000,000,000,000,000,000,000,000] Row 3 [000,000,000,000,000,000,000,000,000,000] Row 4 [000,000,000,000,000,255,255,255,255,255] Row 5 [000,000,000,000,000,255,255,255,255,255] Row 6 [000,000,000,000,000,255,255,255,255,255] Row 7 [000,000,000,000,000,255,255,255,255,255] Row 8 [000,000,000,000,000,255,255,255,255,255] Row 9 

Result:

 displacementFilter = new DisplacementMapFilter(); displacementFilter.alpha=0; displacementFilter.color=0; displacementFilter.mapPoint=new Point(0,0); displacementFilter.scaleX=1; displacementFilter.scaleY=1; displacementFilter.componentX = flash.display.BitmapDataChannel.BLUE; displacementFilter.componentY = flash.display.BitmapDataChannel.BLUE; displacementFilter.mapBitmap = displacementBitmap; destinationBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0xFFFFFFFF); destinationBitmap.applyFilter( sourceBitmap.bitmapData, new Rectangle(0,0,BITMAP_WIDTH,BITMAP_HEIGHT), new Point(0,0), displacementFilter ); produce: 0 1 2 3 4 5 6 7 8 9 [002,002,002,002,002,002,002,002,002,002] Row 0 [002,002,002,002,002,002,002,002,002,002] Row 1 [002,002,002,002,002,002,002,002,002,002] Row 2 [002,002,002,002,002,002,002,002,002,002] Row 3 [002,002,002,002,002,002,002,002,002,002] Row 4 [002,002,002,002,002,001,001,001,001,001] Row 5 [002,002,002,002,002,001,001,001,001,001] Row 6 [002,002,002,002,002,001,001,001,001,001] Row 7 [002,002,002,002,002,001,001,001,001,001] Row 8 [002,002,002,002,002,001,001,001,001,001] Row 9 

Therefore, I donโ€™t understand why I have the โ€œ001โ€ pixels that are not in the original image.

Thank you very much.

+6
source share
1 answer

The offset map filter decides which pixel to capture from the original bitmap using this formula :

 dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256, y + ((componentY(x, y) - 128) *scaleY) / 256) 

dstPixel is the destination bitmap, srcPixel is the original bitmap, and componentX/Y is from the offset bitmap. The mapping is determined by how far the remote component channel is 128. Note that 128 is a neutral value, where there is no conversion, and the same source pixel is used.

For example, consider a pixel in (1, 1) in your case. Your component channel is blue, and the blue channel in (1, 1) on the displacement map has a value of 0. Thus, we displace (0 - 128) / 256 or -0.5. Thus, the final pixel that we take from the original bitmap image is at (0.5, 0.5).

But what does it mean to use half a pixel? It turns out that Flash uses bilinear filtering to smooth out the results. As a result, you get a combination of colors in four pixels between (0,0) and (1,1).

It is for this reason that you see odd pixels that are not in the original image. Although all the pixels in the original image have the same color, it seems that there are some floating point inaccuracies when Flash interpolates between colors, so sometimes you get a small value. Note that if you use a value in an offset bitmap that divides "purely" by 128, such as 0 or 64, you get the correct result. But if you use the value 255 or 19, you will get some error.

Unfortunately, there seems to be no way to turn off filtering and use a simple selection of nearest neighbors. Therefore, if you need to ensure that new colors are not introduced, you must carefully select the values โ€‹โ€‹on the displacement map.

Alternatively, you can use the Pixel Bender to create a kernel that does what you need. Pixel Bender allows you to select the nearest neighbors from the original bitmap.

+3
source

Source: https://habr.com/ru/post/910635/


All Articles