Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Процессор постэффектов

Процессор постэффектов

Поделиться

Страницы: 1 2 3 4 5 Следующая

Daniil PetrovПостоялецwww2 окт. 201715:04#0
Реализовал простой до безумия процессор постэффектов.
Для новичков возможно будет интересно, а от профи жду рецензий, так что не скупитесь, товарищи :)))
Пример фрагментного шейдера для вывода отрендеренной текстуры:
+ Показать

В коде рендера, соответственно выставляется флаг, делать картинку чёрно-белой или нет. Ну и т.д. и т.п. для любого количества эффектов, их последовательность уже меняется по вкусу.
Не стал пока заморачиваться вытаскивать код эффекта в отдельный шейдер, но это уже дело плёвое.

Правка: 2 окт. 2017 15:06

FireFenixПостоялецwww2 окт. 201715:11#1
Держи нас в курсе!
Che@terПостоялецwww2 окт. 201715:12#2
Вау! Фантастика!
Андрей5000Постоялецwww2 окт. 201715:16#3
Предлагаю ещё реализовать систему расчёта и отображения вращающегося треугольника.
Daniil PetrovПостоялецwww2 окт. 201715:28#4
Не понимаю сарказма в отношении новичка :))) я впервые что-то в шейдере накропал!

Немного доработав, добавил силу эффекта:

+ Показать

Точно также можно добавить и цветовой фильтр, заменив ч/б составляющую на любое значение RGB, добавляя любые фотофильтры типа сепии и пр.

Правка: 2 окт. 2017 16:12

Daniil PetrovПостоялецwww2 окт. 201717:25#5
Подскажите, пожалуйста, как в GLSL получить случайное число, а то увлёкся написанием всевозможных эффектов, а чёрно-белый и цветной шум пока не могу получить, а гугл по этому поводу молчит :)

Правка: 2 окт. 2017 17:26

FireFenixПостоялецwww2 окт. 201717:42#6
Daniil Petrov
просто rand() нету, гугли техники шумов

например вот https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

boolПостоялецwww2 окт. 201718:17#7
Daniil Petrov
>> return vec4(Color.r - (Color.r - GreyShade) * strength, Color.g - (Color.g - GreyShade) * strength, Color.b - (Color.b - GreyShade) * strength, 1.0);
return mix(Color, vec4(GreyShade,GreyShade,GreyShade, Color.a), strength);

boolПостоялецwww2 окт. 201718:18#8
Ну и
float GreyShade = dot(Color.rgb, vec3(0.3333));

Правка: 2 окт. 2017 18:19

Daniil PetrovПостоялецwww2 окт. 201718:35#9
bool
> mix(Color, vec4(GreyShade,GreyShade,GreyShade, Color.a), strength);
Премного благодарен :) век живи, век учись!
boolПостоялецwww2 окт. 201718:41#10
Daniil Petrov
ну и лучше не комбинировать пост-процессы флагами в шейдере. Можно сделать смотри как. делаешь в коде класс, типа:
class Postprocess : ImageEffect
{
public:
  //эта функция будет биндить шейдер, текстуры и рисовать единичный квад с этой текстурой, обрабатывая ее
  void blit(Texture src, Texture dst, Material material);
};

далее можно сделать для удобства шаблонный шейдер, у которого есть уже определенный для всех пост-процессов интерфейс с базовыми юниформами и лейаутом. Ну т.е. чтобы ты знал сразу, что основная текстура, допустим, приходит в srcTexture.
Ну и так же можно сделать твой же strength.
Ну и в шаблонном шейдере типа:
void main() {
  {SHADER_POSTPROCESS_BODY}
  return mix(srcColor, dstColor, strength);
}

Но, не стоит сразу бежать и реализовывать это, это один из вариантов, с большой вероятностью не самый лучший)
Но может позволить быстро наклепать разных пост-процессов, реализовывать их комбинацию и т.д.
В таком случае, в моем видении, каждый пост-процесс знает каким шейдером рисуется. Это может быть именно код, может имя текстового файла, в котором код, может быть что-то еще.

Правка: 2 окт. 2017 18:49

Mr FПостоялецwww2 окт. 201719:17#11
bool
не стоит спешить делать каждый постэффект своим квадом, чем больше объединишь вместе - тем лучше. запись пикселей медленное дело.
но можно упороться и сделать генератор скленного одного шейдера из кучи маленьких отдельных, там где мультипасс не нужен.

bool
>Ну и
> float GreyShade = dot(Color.rgb, vec3(0.3333));
ну тогда уж и float GreyShade = dot(Color.rgb, vec3(0.2125, 0.7154, 0.0721));
почему так? потому что глаз воспринимает максимальные экранные значения красного/зеленого/синего разными по яркости. зелёный кажется нам ярче, синий темнее, даже если физически яркость сигнала одна.
это даже эксплуатируют форматы текстур, в DXT вроде больше бит на зелёный канал, или вспомнить R11G11B10 формат...

Правка: 2 окт. 2017 19:18

0xc0deПостоялецwww2 окт. 201719:22#12
Mr F
> ну тогда уж и float GreyShade = dot(Color.rgb, vec3(0.2125, 0.7154, 0.0721));
> почему так? потому что глаз воспринимает максимальные экранные значения
> красного/зеленого/синего разными по яркости. зелёный кажется нам ярче, синий
> темнее, даже если физически яркость сигнала одна.
> это даже эксплуатируют форматы текстур, в DXT вроде больше бит на зелёный
> канал, или вспомнить R11G11B10 формат...

А еще эта формула верна для линейного цветового пространства, поэтому надо так:
float GreyShade = pow( dot(pow(Color.rgb,vec3(2.2)), vec3(0.2125, 0.7154, 0.0721)), 1.0/2.2 );

boolПостоялецwww2 окт. 201719:23#13
Mr F
>
> ну тогда уж и float GreyShade = dot(Color.rgb, vec3(0.2125, 0.7154, 0.0721));
> почему так? потому что глаз воспринимает максимальные экранные значения
> красного/зеленого/синего разными по яркости. зелёный кажется нам ярче, синий
> темнее, даже если физически яркость сигнала одна.
> это даже эксплуатируют форматы текстур, в DXT вроде больше бит на зелёный
> канал, или вспомнить R11G11B10 формат...
>
>
Luminance я сознательно не писал, пусть сам ищет)) я просто написал как сделать более кратко то, что он сделал.
А по поводу объединения пост-процессов - описанный мной способ никак этому не мешает)
FordPerfectПостоялецwww2 окт. 201719:29#14
Mr F
У тебя коэффициенты из https://habrahabr.ru/post/304210/ , смотрю.
А DXT - там 565, насколько я понимаю. Несколько больше точности цвета с наибольшим вкладом (зелёного) ценой невозможности представить оттенки серого - спорное решение.

Страницы: 1 2 3 4 5 Следующая

/ Форум / Программирование игр / Графика

2001—2017 © GameDev.ru — Разработка игр