В настоящее время я работаю над 2D-игрой, и моя текущая задача - наметить выделенный объект.
Я в основном использую размытие шейдера, чтобы сделать это полностью во время выполнения. Сначала я рисую свой спрайт с помощью вертикального гауссова размытия, затем я рисую его с помощью горизонтального гауссова размытия, а затем я нормально рисую свой спрайт.
Вот мой шейдер размытия: сэмплер TextureSampler: register (s0);
#define SAMPLE_COUNT 15
float2 SampleOffsets[SAMPLE_COUNT];
float SampleWeights[SAMPLE_COUNT];
float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
float4 c = 0;
// Combine a number of weighted image filter taps.
for (int i = 0; i < SAMPLE_COUNT; i++)
{
c += tex2D(TextureSampler, texCoord + SampleOffsets[i]) * SampleWeights[i];
}
return c;
}
SampleOffets - это смещения, позволяющие мне тестировать пиксели округления. SampleWeights - это веса, рассчитанные с помощью гауссовой функции ( http://en.wikipedia.org/wiki/Gaussian_blur ).
Вот результат:
Это не так уж плохо, довольно плавно, но недостаточно заметно в игре ... Но я бы хотел иметь возможность контролировать толщину (чтобы она была больше) и добавить первый непрозрачный контур, прежде чем он исчезнет в альфа (чтобы сделать это более заметно). И я чувствую, что размытие по Гауссу, возможно, не так хорошо, как я думал для своей задачи :)
Другая идея состоит в том, чтобы генерировать его автоматически из .png (используя скрипт photoshop, чтобы сделать его автоматическим). Мне просто нужно заполнить контурные пиксели собственным цветом, например, сохранить альфа-значение в компоненте Red и установить для всех остальных компонентов значение 0. Затем мне просто нужно применить шейдер, который заменяет прозрачные пиксели на нужный цвет.
float4 PixelShaderFunction2(float2 texCoord : TEXCOORD0) : COLOR0
{
float4 color = tex2D(TextureSampler, texCoord);
float4 newColor = 0;
if (color.a == 0 && color.r != 0)
{
color.a = color.r;
// Blue outline
color.b = 1;
}
}
Проблема в том, что я использую сжатие DXT5 для своего спрайта, поэтому я не могу быть уверен, что цвет, который я получу в своем шейдере, будет точно таким же, как я написал. Вот почему я даже не попробовал ... Есть мысли?
Любой совет приветствуется :)
источник
Ответы:
То, что вы, вероятно, ищете, это форма обнаружения края до, после или даже до и после вашего размытия по Гауссу. Может быть, версия Sobel Edge Detection могла бы работать. Я знаю, что ваша игра 2D, но если вики-страница слишком грубая, вот учебник о том, как заставить ее работать в UDK, который может быть лучше переведен.
Ваше обнаружение края действительно должно найти края альфа-канала, если вам нужно повышение скорости.
источник
Что сработало для меня с выделением текста:
Вы можете сделать то же самое - все, что вам нужно сделать, это нарисовать спрайт с непрозрачными пикселями, окрашенными в цвет вашего контура. (Сохраняйте значения прозрачности, чтобы круглые края все еще выглядели круглыми).
Это работает, выглядит лучше, чем рисование масштабированной версии, и имеет некоторые другие интересные свойства (например, возможность контролировать альфа-контур для жирности и сохранение любых «дырок» в изображении спрайта) - единственный недостаток заключается в том, что вы можете ' на самом деле слишком хорошо контролировать ширину контура.
источник
Я новичок во всем этом, но вот моя идея:
Вы можете использовать альфа-канал вашей текстуры для создания другой текстуры. Любое альфа-значение ниже порогового значения будет полностью прозрачным. Все вышеперечисленное будет полностью непрозрачным. Используя эту новую текстуру, вы можете установить значения RGB для любого цвета. Масштабируйте эту новую «текстуру», чтобы она была немного больше текстуры вашего персонажа. Это даст вам хороший сплошной цвет вокруг персонажа. Затем используйте этот цвет с гауссовым шейдером, чтобы придать красивое очерченное свечение вокруг созданной текстуры. Я предполагаю, что это может быть сделано без создания другой текстуры, и все шейдеры основаны на текстуре персонажа.
Имеет ли это смысл вообще?
источник