Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Задачка по блендингу

Задачка по блендингу

Поделиться

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

SuslikМодераторwww9 мая 20174:57#0
Рассмотрим абстрактную задачу, реальный смысл которой мне объяснять лень.

Итак, есть множество 2д спрайтов. У каждого спрайта есть альфа-канал(прозрачные пиксели отмечены белым), обычные цветовые пиксели(чёрным) и пиксели определённого фиксированного цвета, который назовём цветовым ключом (color key, отмечены фиолетовым). Требуется сблендить эти спрайты друг на друга обычным alpha blending'ом, а потом вырезать все пиксели цветового ключа результирующего изображения(сделать их прозрачными):
Blending | Задачка по блендингу

Всё здорово и тривиально до тех пор, пока в дело не вступает anti-aliasing. Переходные пиксели между цветовыми и color key'ем оказываются невнятного промежуточного цвета, который не ясно, как потом вырезать.

Возможно, кто-то знает интересный хак, как такую проблему можно обойти, не используя дополнительную текстуру?

=A=L=X=Постоялецwww9 мая 20179:01#1
Ну на шейдерах то можно и не заводить промежуточную текстуру, интерполируя цвета из исходных NEAREST-текстур самостоятельно. Но, насколько я помню, велосипедизация работы текстурного блока чревата тормозами и её лучше избегать.
jaguardУчастникwww9 мая 20179:15#2
Блитить текстуры без фильтрации? :)

Наверное можно задавать color key не цветом, а диапазоном альфы. Например ставить альфу в 0.08, и потом вырезать все, что в диапазоне альфы 0..0.08.

Правка: 9 мая 2017 9:16

ChupakaberПостоялецwww9 мая 20179:16#3
=A=L=X=
> велосипедизация работы текстурного блока чревата тормозами и её лучше избегать.
+

Suslik
> как такую проблему можно обойти, не используя дополнительную текстуру?
использовать как твой color key промежуток из альфа-канала, например от 0.5 до 0.6, и в спрайтах этот промежуток избегать, он будет также бить по антиалиасингу, но будет менее заметно, т.к. цвет не меняется, просто будут дырки кое где сквозные по контурам

SuslikМодераторwww9 мая 20179:50#4
Chupakaber
> использовать как твой color key промежуток из альфа-канала, например от 0.5 до 0.6
вот я какое-то решение в этом духе ищу. к сожалению, при интерполяции соседних текселей получаются значения, попадающие как раз в этот диапазон, вылазят артефакты.

=A=L=X=
> Ну на шейдерах то можно и не заводить промежуточную текстуру, интерполируя
> цвета из исходных NEAREST-текстур самостоятельно
даже если интерполировать цвета самостоятельно, не ясно, как в самих спрайтах хранить плавный antialiased переход от обычного цвета к color key. производительность не слишком интересует, тут нагрузка минимальная.

jaguard
> Блитить текстуры без фильтрации? :)
не покатит, к сожалению, потому что спрайты могут быть как угодно растянуты.

Правка: 9 мая 2017 9:51

=A=L=X=Постоялецwww9 мая 201710:09#5
Suslik
> даже если интерполировать цвета самостоятельно, не ясно, как в самих спрайтах
> хранить плавный antialiased переход от обычного цвета к color key.

А, тебе даже так надо. Но тут всё то же самое. Думай просто следующим образом (псевдокод):

vec4 get_tex_color( vec2 uv )
{
  vec4 color = ...; // текстурная выборка
  if ( color.xyz == KEY_COLOR )
  {
     color = vec4( 0, 0, 0, 255 );
  }
  return color;
};
Главное - что оно берется у текстуры с фильтром LINEAR, а потом уже ты блендишь всю эту фигню как хочешь, но ручками.

=A=L=X=Постоялецwww9 мая 201710:13#6
Suslik

Хотя погоди, я перестаю понимать что тебе надо. У тебя же как раз не может быть никакого бленда по краю розовых областей - там будет ровный край (сглаженный, но резкий), потому что тут не с чем блендить собственно. Розовый - это дырка. Нет там ничего с чем надо было бы блендить.

Правка: 9 мая 2017 10:13

SuslikМодераторwww9 мая 201710:33#7
=A=L=X=
> if ( color.xyz == KEY_COLOR )
ещё раз. это не прокатит, потому что внутри одного спрайта граница между цветовым ключом и обычной геометрией тоже должна быть сглажена. собственно, сейчас я делаю так, как ты написал, но появляются артефакты на этой границе, потому что там — переходный цвет.

=A=L=X=
> У тебя же как раз не может быть никакого бленда по краю розовых областей - там
> будет ровный край (сглаженный, но резкий)
так сглаженный или резкий? именно потому что в самом спрайте он сглаженный(antialiasing), появляются цвета промежуточного цвета, поэтому даже point filter не поможет.

=A=L=X=Постоялецwww9 мая 201710:51#8
Suslik
> но появляются артефакты на этой границе, потому что там — переходный цвет.

Это потому что ты блендишь стандартными средствами.

> так сглаженный или резкий?

Зависит от того куда и как ты будешь потом результат применять.
Если он уже будет самодостаточным полигоном, то это должно выглядеть как гладкая в смысле неквадратности текселей, но резкая всмысле отсутствия полупрозрачности граница.
Искал-искал скрншоты с такими поверхностями - не нашёл, но самый частый пример это листва всякая.

jaguardУчастникwww9 мая 201711:08#9
=A=L=X=
> Главное - что оно берется у текстуры с фильтром LINEAR,

Видимо все-таки NEAREST. А так да, мне тоже кажется что подходит такое решение. Брать 4 текселя влево-вверх от текущего и делать свою "собственную" билинейку. Если попали в колоркий в одном из этих пикселов - ну тут уже какая-то логика, в зависимости от того что мы хотим получить в результате.

SuslikМодераторwww9 мая 201712:37#10
Окей, сделаю немного более информативную иллюстрацию. Возможно, так будет более понятно. Сделал в увеличенном варианте, чтобы было понятно, что именно мне нужно:
Blending2 | Задачка по блендингу
Обратите внимание, что между всеми цветами могут быть плавные anti-aliased переходы. То есть напрямую с цветом color key'я сравнивать нельзя, потому что на границе с цветом он оказывается смешанным. Здесь чёрным отмечены просто цветные пиксели, которые могут быть почти произвольного цвета. Фиолетовым — сам color key. Шашечками — альфа-канал.

Я склоняюсь к идее, что color key в таком виде использовать не удастся и думаю, как его можно запаковать в другие каналы. Спрайты на всех этапах рендерю я сам и могу их запекать так, как мне вздумается и потом трактовать их в шейдере так, как мне вздумается.

Правка: 9 мая 2017 12:42

destractПользовательwww9 мая 201712:56#11
Suslik
> Возможно, кто-то знает интересный хак, как такую проблему можно обойти, не
> используя дополнительную текстуру?
Отключить фильтрацию?
jaguardУчастникwww9 мая 201713:03#12
Suslik
> Я склоняюсь к идее, что color key в таком виде использовать не удастся и думаю,

То есть у тебя заранее "колоркий" с альфой? Так чего ты нам голову морочишь? :).

"Кровавую Мэри" нельзя разделить на водку и сок.

Правка: 9 мая 2017 13:05

destractПользовательwww9 мая 201713:08#13
Suslik
> Окей, сделаю немного более информативную иллюстрацию.
Не уверен, что это решается на GPU. Даже на CPU понадобятся костыли, чтобы разрешить смешивание на границах.
jaguardУчастникwww9 мая 201713:10#14
Suslik
> Спрайты на всех этапах рендерю я сам и могу их запекать так, как мне вздумается
> и потом трактовать их в шейдере так, как мне вздумается.
>

Ну кстати, в таком случае достижимо согласно классической теории информации - кодируешь ARGB уменьшенной битности и на оставшихся битах хранишь свою колорокиевую магию(например 7 бит на альфу и 1 на колорки а, ну да, у тебя колоркий тоже с альфой. Тогда, например, 6-6-6-6-8). Ну и фильтрацию все-равно свою писать, чтобы не потерять эти волшебные биты.

Правка: 9 мая 2017 13:15

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

/ Форум / Программирование игр / 2D графика и изометрия

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