📜 ⬆️ ⬇️

How to implement bloom post effect in flash

First of all, I really want to convey a huge hello to a wonderful actor and a walking post effect in one person: Orlando Bloom. As long as Google exists, you will not be forgotten.

Part one. Blur



Important limitation

')
First of all, it should be understood that the calculation of these post-effects can not be performed on a video card. This is due to one remarkable limitation, for which we love the GPU - the color of several pixels is calculated simultaneously. Because of this, you can not know exactly the color of the "neighboring" pixel, so necessary when implementing these effects. Therefore, we will calculate the final picture on the CPU. Post effects can significantly smooth out the bumps and ugly edges of three-dimensional graphics, and greatly improves the picture. The speed of the post-effect entirely depends on the size of the view, respectively, the greatest performance drop will be observed with a full-screen image. Also, I want to mention that these effects do not apply to any specific engine and can be performed on any image from which BitmapData can be removed. This article will cover the application of blur to a picture obtained with the alternativa3d engine. Who still reads - I invite under habrakat.

Picture preparation


First of all, we need to ask the video card to return the rendered image to us in a convenient form. To do this, call the Context3D.drawToBitmapData () method. With an argument, this method accepts an object of type BitmapData, updated with each call to the present () method of the same context. If you are using the alternativa3d engine, you just need to set the renderToBitmap property of the View instance to true. Then the rendered bitmapData can be obtained from the canvas property of the same instance.

private function itsRenderTime(e:Event):void { //No, dad, no!
camera.view.renderToBitmap = true;
camera.render(stage3d);
realisePostEffect(camera.view.canvas);
}


Actually blur


It is common to use the following image blur algorithm:

  1. First, we reduce the image received from the renderer in order to reduce the load on the processor - it will have to perform the same rather difficult operation on each pixel.
  2. The next action we need to find out the average color of each of the neighboring current pixel and mix it with the current color in equal shares. If “enhanced” blur is used, the colors of the neighbors of the neighbors are recognized; the effect of the color of such pixels is inversely proportional to the distance (perhaps even to its square, did not go into details) to them from the current one.
  3. Paragraph 2 can be repeated several times to enhance the quality of the blur. Theoretically, it can be performed an arbitrary number of times, however, empirically, the best quality / performance ratio was determined by performing the second item three times. Clever articles say that in this way the closest approach to Gaussian blur is achieved, but you cannot see the details in this article, so just take a word.
  4. The resulting blurred image is stretched again to the size rendered to fit.
  5. Blurred and rendered image are mixed taking into account [semi] transparency blurred.


With points 2 and 3, an integrated flash filter called BlurFilter does a great job. 1 and 4 is provided by using the affine transformation matrix when invoking the draw method of the bitmapData instance. Well, the fifth point is easy to implement by setting the parameters of the constructor of the ColorTransform instance. It remains only to show the picture on the screen, with which, without any assistance, the copy of the alternative library added to [Stage] Stage copes:

private function realisePostEffect(canvas:BitmapData):void {
var _scaling:int = 4 // 16 (4*4) .
var _power:int = 4 //
var _alpha:Number = .5 //
var _quality:int = 3 // ,

var _cT:ColorTransform = new ColorTransform(1, 1, 1, _alpha);
var _bloomData:BitmapData = new BitmapData(canvas.width / _scaling, canvas.height / _scaling, true, 0);
var matrix:Matrix = new Matrix();
matrix.scale(1 / _scaling, 1 / _scaling);
_bloomData.draw(canvas, matrix, _cT);
_bloomData.applyFilter(_bloomData, _bloomData.rect, new Point(), new BlurFilter(_power, _power, _quality));
matrix.invert();
canvas.draw(_bloomData, matrix);
}


Image without and with post-processing:


During the development phase, it is very convenient to put _scaling, _power, _alpha and _quality parameters into a static property of an arbitrary class in order to change their runtime and adjust the picture until the desired balance between beauty and performance is reached. Or allow you to change them directly to the user through the graphics settings menu.

Coming soon: HDR effect - highlighting the image and how to touch the buffer.

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


All Articles