Наброски спрайтов


9

В настоящее время я работаю над 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 для своего спрайта, поэтому я не могу быть уверен, что цвет, который я получу в своем шейдере, будет точно таким же, как я написал. Вот почему я даже не попробовал ... Есть мысли?

Любой совет приветствуется :)


Вы должны иметь возможность контролировать толщину и альфа-спад в своем шейдере. Хотите опубликовать это для справки?
Сет Баттин

Я использовал гауссовский размытый шейдер из этого примера: ссылка позволяет мне редактировать мой пост, чтобы показать вам шейдер в деталях
s0ubap

Я не уверен, что размытие по Гауссу подходит вам. Попробуйте вместо этого радиальное размытие.
user1306322

Ответы:


6

То, что вы, вероятно, ищете, это форма обнаружения края до, после или даже до и после вашего размытия по Гауссу. Может быть, версия Sobel Edge Detection могла бы работать. Я знаю, что ваша игра 2D, но если вики-страница слишком грубая, вот учебник о том, как заставить ее работать в UDK, который может быть лучше переведен.

Ваше обнаружение края действительно должно найти края альфа-канала, если вам нужно повышение скорости.


Интересно! Я попробовал это. Результат был хорошим, за исключением случаев, когда я увеличивал /
уменьшал

1
Какой вид артефакта вы видите? Можете ли вы предоставить изображение?
Алекс Шепард

2

Что сработало для меня с выделением текста:

  • Выберите цвет контура
  • Нарисуйте текст в (х-1, у-1) с цветом контура
  • Нарисуйте текст в (х + 1, у-1) с цветом контура
  • Нарисуйте текст в (х-1, у + 1) с цветом контура
  • Нарисуйте текст в (х + 1, у + 1) с цветом контура
  • Нарисуйте текст в (х, у)

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

Это работает, выглядит лучше, чем рисование масштабированной версии, и имеет некоторые другие интересные свойства (например, возможность контролировать альфа-контур для жирности и сохранение любых «дырок» в изображении спрайта) - единственный недостаток заключается в том, что вы можете ' на самом деле слишком хорошо контролировать ширину контура.


1

Я новичок во всем этом, но вот моя идея:

Вы можете использовать альфа-канал вашей текстуры для создания другой текстуры. Любое альфа-значение ниже порогового значения будет полностью прозрачным. Все вышеперечисленное будет полностью непрозрачным. Используя эту новую текстуру, вы можете установить значения RGB для любого цвета. Масштабируйте эту новую «текстуру», чтобы она была немного больше текстуры вашего персонажа. Это даст вам хороший сплошной цвет вокруг персонажа. Затем используйте этот цвет с гауссовым шейдером, чтобы придать красивое очерченное свечение вокруг созданной текстуры. Я предполагаю, что это может быть сделано без создания другой текстуры, и все шейдеры основаны на текстуре персонажа.

Имеет ли это смысл вообще?


Этот метод имеет большой недостаток при работе с не вогнутыми формами. Например, при нанесении на пончик только внешний край получит контур. Не говоря уже о других искажениях толщины контура.
Кромстер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.