Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > BuKT

Оценить эту запись

Bloom и HDR пост-эффекты.

Запись от BuKT размещена 09.01.2012 в 12:23
Обновил(-а) BuKT 11.01.2012 в 00:50 (мелкие правки)

Очень хочется передать огромный привет замечательному актёру и ходячему пост-эффекту в одном лице: Орландо Блуму. Пока существует гугль - ты не будешь забыт.

Часть первая. Блюр

Важное ограничение

Прежде всего, стоит понимать, что расчёт этих пост-эффектов не может быть выполнен на видеокарте. Связано это с одним замечательным ограничением, за которое мы и любим GPU - одновременно рассчитывается цвет нескольких пикселей. Из-за этого, вы не сможете точно узнать цвет "соседнего" пиксела, так необходимого при реализации этих эффектов. Поэтому, рассчитывать окончательную картинку будем на CPU. Это подобные пост-эффекты позволяют значительно сгладить неровности и некрасивые рёбра трёхмерной графики, и значительно улучшить картинку. Скорость выполнения пост-эффекта целиком и полностью зависит от размеров view, соответственно наибольшее падение производительности будет наблюдаться при full-screen картинке. Так же, хочется упомянуть, что ни к какому конкретному движку эти эффекты не относятся и могут быть выполнены на любом изображении, с которого можно снять BitmapData. В данной статье будет рассматриваться применение размытия к картинке, полученной при помощи движка alternativa3d. Приступим.

Подготовка картинки

В первую очередь, нам необходимо попросить видеокарту вернуть нам отрендеренную картинку в удобном для нас виде. Для этого, необходимо вызвать метод Context3D.drawToBitmapData(). Аргументом этот метод принимает объект типа BitmapData, обновляемый с каждым вызовом метода present() того же контекста. Если вы пользуетесь движком alternativa3d - необходимо просто выставить свойство renderToBitmap экземпляра View в true. Тогда отрендеренный bitmapData можно будет получить из свойства canvas того же экземпляра.

Код AS3:
private function itsRenderTime(e:Event):void { //No, dad, no!
	camera.view.renderToBitmap = true;
	camera.render(stage3d);
	realisePostEffect(camera.view.canvas);
}
Собственно размытие

Общепринято использовать следующий алгоритм размытия изображения:
  1. Сначала мы уменьшаем полученную от рендерера картинку, чтобы уменьшить нагрузку на процессор - ему придётся выполнять одну и ту же довольно непростую операцию над каждым пикселом.
  2. Следующим действием нам нужно узнать усреднённый цвет каждого из соседних текущему пикселу и смешать его с цветом текущего в равных долях. Если используется "усиленное" размытие - узнаются цвета соседей соседей; влияние цвета таких пикселей обратно пропорционально расстоянию (возможно даже его квадрату, не вдавался в подробности) до них от текущего.
  3. Пункт 2 может быть повторён несколько раз для усиления качества размытия. Теоретически, он может быть выполнен произвольное количество раз, однако опытным путём наилучшее соотношение качество/производительность было установлено при выполнении второго пункта трижды. Умные статьи говорят, что таким образом достигается наибольшее приближение к размытию по Гауссу, но в этой статье подробностей вам не видать, так что просто поверьте на слово.
  4. Полученная размытая картинка снова растягивается до размеров отрендеренной, чтобы соответствовать.
  5. Размытая и отрендеренная картинка смешиваются с учётом [полу]прозрачности размытой.

С пунктами 2 и 3 прекрасно справляется встроенный фильтр флеша под названием BlurFilter. 1 и 4 обеспечивается применением матрицы аффиных преобразований при вызове метода draw экземпляра bitmapData. Ну а пункт пятый легко реализовать настройкой параметров конструктора экземпляра ColorTransform. Остаётся только показать картинку на экране, с чем без посторонней помощи справляется добавленный к [ребёнку] Stage экземпляр View библиотеки альтернативы:

Код AS3:
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);
}
На этапе разработки бывает очень удобно вынести параметры _scaling, _power, _alpha и _quality в статическое свойство произвольного класса, чтобы менять их рантайм и настраивать картинку до тех пор, пока не будет достигнут желаемый баланс между красотой и производительностью. Либо позволить менять их непосредственно пользователю через меню настроек графики.

Coming soon: HDR-эффект - высветление картинки и как пощупать буфера.

Полная и/или частичная перепечатка подразумевает под собой согласие с правилом: обязательная ссылка на первоисточник
Всего комментариев 7

Комментарии

Старый 10.01.2012 15:06 -De- вне форума
-De-
 
Аватар для -De-
>рассчёт этих пост-эффектов не может быть выполнен на видеокарте
А мужики-то не знают)
Старый 10.01.2012 15:12 Котяра вне форума
Котяра
 
Аватар для Котяра
Цитата:
А мужики-то не знают)
даже не подозревают )
http://www.nulldesign.de/2011/12/07/nd2d-blur/
и тут тоже
http://wonderfl.net/c/r49o
Обновил(-а) Котяра 10.01.2012 в 15:42
Старый 10.01.2012 15:51 Котяра вне форума
Котяра
 
Аватар для Котяра
Первоисточник не работает.
Старый 10.01.2012 17:21 BuKT вне форума
BuKT
 
Аватар для BuKT
Уже в курсе про этот трюк. Перерендер сцены с несколькими подложенными друг под друга полупрозрачными полигонами затекстурированными отрендеренной "изначальной" сценой. Хитро, но не факт, что так уж удачно по фпс. В любом случае попробую.

Цитата:
Первоисточник не работает.
Первоисточник опять повис. Не хочет и всё с четырьмя гигами сервак работать
Старый 10.01.2012 20:05 Zebestov вне форума
Zebestov
 
Аватар для Zebestov
шота... не комильфо.
Старый 10.01.2012 23:03 dimarik вне форума
dimarik
 
Аватар для dimarik
Расчёт, расчет. Но рассчитать.
Обновил(-а) Котяра 11.01.2012 в 15:26 (атата)
Старый 11.01.2012 00:48 BuKT вне форума
BuKT
 
Аватар для BuKT
Да, в курсе. Извините, проглядел. В первоисточнике исправлено, а сюда копировал неисправленную версию.
 

 


Часовой пояс GMT +4, время: 01:29.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.