forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Уроки (http://forum.boolean.name/forumdisplay.php?f=145)
-   -   AA-эмуляция в Deferred render (http://forum.boolean.name/showthread.php?t=13850)

Taugeshtu 07.12.2010 01:54

AA-эмуляция в Deferred render
 
Вложений: 1
Потихоньку (ага, скромник какой нашелся) осваиваю Unity3d. Решил делиться знаниями.

Начиная с версии 3.0 был введен deferred render. Что это такое некоторые знают, некоторые слышали, а кто-то видит эти слова вместе в первый раз. Если кратко, то deferred render - это техника, позволяющая использовать много пиксельных источников света без существенного падения ФПС. Это достигается за счет того, что освещение просчитывается не во время рендера сцены, а после него - то есть только для тех пикселей, что попали на экран. Это довольно удобная техника, которая, к тому же, в unity хорошо дружит с припаянным Beast Lightmapper и обеспечивает красивое мягкое перетекание динамических теней в статические.

Недостатком deferred render-а является то, что он несовместим с хардварным АнтиАлиасингом (АА). Но беда не велика - это достаточно просто исправить, что я вам сейчас и покажу.

Для начала - принцип. Хардварный АА работает примерно так: для устранения "лесенок" для рассчета цвета пиксела используется значение не одного пиксела, а нескольких. То есть видеокарта просчитывает для одного пиксела рендер несколько раз со смещением, затем смешивает полученные цвета и выдает конечный результат. Получается весьма красиво и гладко.
Мы будем делать то же самое, но другими путями. Как? Очень просто:
  • Наложим на камеру эффект размытия граней (есть в стардартной поставке имедж эффектов)
  • Отрендерим мир в разрешении, превышающем экранное в некоторое число раз;
  • Отрисуем отрендеренное уже в экранное разрешение (т.е. с уменьшением) и наложим GUI и HUD элементы.

Что нам для этого понадобится в сцене:
  • Слой "GUI", в который мы поместим всё, что должно быть отрисовано после рендера мира;
  • Главная камера с наложенным на неё эффектом "Edge blur" и скриптом "захвата" текстуры;
  • Дополнительная камера с ортогональной проекцией, с Culling Mask, содержащей в себе только слой GUI, компонентом GUILayer, скриптом финального вывода картинки и параметром "Depth", большим чем у Главной камеры.

Скрипт, который надо вешать на Главную камеру (JavaScript) :

Код:

var BigRenderScale : float = 1.5;
static var big_render : RenderTexture;

function Start() {
        // Создадим рендер-текстуру
        big_render = RenderTexture(Screen.width*BigRenderScale, Screen.height*BigRenderScale, 24);
        big_render.Create();
        // И установим её
        gameObject.camera.targetTexture = big_render;
}

Скрипт для Дополнительной камеры (JavaScript) :

Код:

private var mat : Material;

function Start() {
        // Создадим материал с простейшим шейдером
        mat = new Material("Shader \"Texture Simple\" {" +
                "  Properties { " +
                "      _MainTex (\"Base (RGB)\", 2D) = \"white\" " +
                "  } " +
                "  SubShader { " +
                "      Pass { " +
                "        SetTexture [_MainTex] " +
                "}" +
                "}" +
                "}"
        );
}

function OnPostRender() {
        // Установим материалу текстуру из рендера Главной камеры
        mat.SetTexture("_MainTex", AA_emul_grab.big_render);

        // Прямоугольник с текстурными координатами
        GL.PushMatrix();
        mat.SetPass(0);
        GL.Color(Color(1,1,1,1));
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
                GL.TexCoord(Vector3(0,0,0));
                GL.Vertex3(0,0,0);
                GL.TexCoord(Vector3(0,1,0));
                GL.Vertex3(0,1,0);
                GL.TexCoord(Vector3(1,1,0));
                GL.Vertex3(1,1,0);
                GL.TexCoord(Vector3(1,0,0));
                GL.Vertex3(1,0,0);
        GL.End();
        GL.PopMatrix();
}

Особенности:
Для наглядности рекомендую отключить на время компонент "Camera" дополнительной камеры и настроить Edge Blur визуально. Параметр "BigRenderScale" больше 2х делать ОЧЕНЬ не рекомендую. Помните, нагрузка на систему возрастает в квадратичной зависимости от этого параметра. Больше рендер - больше пикселей - меньше ФПС. Скорее всего оптимальным будет настроить "BigRenderScale"=1.3, и дальше "плясать" с Edge Blur параметрами.

Результат усилий - в аттаче.

P.S.
Кусочки скрипта, ответственные за GL-часть, нагло позаимствованны с соседнего ресурса. Но особой мыслительной ценности в них нет, так что копирайта они не достойны :-D

P.P.S.
По этому же принципу возможны другие реализации, и скорее всего моя - не самая быстрая. Но она работает.

.Squid 07.12.2010 02:11

Ответ: AA-эмуляция в Deffered render
 
Я отношусь к той группе, которая сочетание этих слов видит впервые.

И таки ты прав: такой способ далеко не самый быстрый. Гораздо быстрее (хотя и менее качественно, но разницу только профессионалы, пожалуй, заметят) размывать бекбуфер по маске, полученной с помощью edge detection. Например, как тут http://orenk2k.blogspot.com/2010/10/...-aliasing.html

ЗЫ. deferred. Ну и правильнее все же Deferred Shading, а не Rendering, т.к. отложено именно освещение, а не рендеринг. Хотя сейчас говорят и так, и эдак, так что пофиг.

Taugeshtu 07.12.2010 02:26

Ответ: AA-эмуляция в Deferred render
 
Вложений: 1
Цитата:

размывать бекбуфер по маске
Строго говоря, Edge Blur этим и занимается - детектирует грани и моет что нашел. Но то ли он это сильно неумело делает, то ли у меня глаз такой острый - мне очень неприятно наблюдать ДИКОЕ заблюривание заднего плана. Как правило чем дальше - тем больше граней на квадратный пиксель, и задний план превращается в кашу. В аттаче - иллюстрация.

Есть предположения, как это побороть?

.Squid 07.12.2010 11:23

Ответ: AA-эмуляция в Deferred render
 
Извини, мне Knightmare запрещает помогать юнитоидам.

viper86 07.12.2010 14:15

Ответ: AA-эмуляция в Deferred render
 
Цитата:

Сообщение от .Squid (Сообщение 171230)
Извини, мне Knightmare запрещает помогать юнитоидам.

Они чем то хуже остальных?

.Squid 07.12.2010 15:19

Ответ: AA-эмуляция в Deferred render
 
Цитата:

Сообщение от viper86 (Сообщение 171242)
Они чем то хуже остальных?

Нет, наоборот. Он говорит, что я еще не достиг нужного уровня.

ffinder 07.12.2010 16:25

Ответ: AA-эмуляция в Deferred render
 
Цитата:

Сообщение от .Squid (Сообщение 171230)
Извини, мне Knightmare запрещает помогать юнитоидам.

конкурентная борьба во всей красе:super:

Taugeshtu 07.12.2010 17:43

Ответ: AA-эмуляция в Deferred render
 
Нашел более "вкусный" фильтр, по результату - примерно так же хорошо, как и с большим рендером, зато производительность падает значительно меньше.

Линк на тему на официальном форуме

Применение:
Просто вешаем на главную камеру самым первым Image Effect-ом. Если число включенных Image Effect-ов перед этим скриптом нечетное - не работает О_о.

.Squid 07.12.2010 17:55

Ответ: AA-эмуляция в Deferred render
 
Такое чувство, что размываются не только границы. Ну это если сильно присматриваться.

UPD. Так и есть. Указано в недостатках в описании исходного алгоритма ( http://www.gamedev.net/community/for...opic_id=580517 ). А вообще полезная ссылка.


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

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot