Окресліть спрайт


9

Зараз я працюю над 2D грою, і моє поточне завдання - окреслити вибраний об’єкт.

Я в основному використовую шейдер для розмиття, щоб зробити це повністю виконуваним. Спочатку малюю спрайт за допомогою вертикальної шейдера розмиття, потім малюю горизонтальним гауссовим шейдером розмиття, а потім малюю спрайт нормально.

Ось мій шейдер розмиття: sampler 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, щоб зробити його автоматичним). Мені просто потрібно заповнити контури пікселів спеціальним кольором, зберігаючи, наприклад, значення альфа в компоненті Червоний, а всі інші компоненти встановити на 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 Dection може спрацювати. Я знаю, що ваша гра 2D, але якщо вікі-сторінка занадто груба, ось урок про те, як змусити її працювати в UDK, що може перетворитись на краще.

Для виявлення ваших країв дійсно потрібно знайти краї альфа-каналу, якщо вам потрібно збільшити швидкість.


Цікаво! Я спробував це. Результат був хорошим, за винятком випадків, коли я збільшую /
зменшую

1
Який артефакт ви бачите? Чи можете ви надати зображення?
Алекс Шепард

2

Що для мене працювало з викладенням тексту:

  • Підберіть колір контуру
  • Намалюйте текст у (x-1, y-1) кольором контуру
  • Намалюйте текст у (x + 1, y-1) кольором контуру
  • Намалюйте текст у (x-1, y + 1) кольором контуру
  • Намалюйте текст у (x + 1, y + 1) кольором контуру
  • Намалюйте текст у (x, y)

Можна зробити те ж саме - все, що вам потрібно зробити, це намалювати спрайт непрозорими пікселями, забарвленими кольором вашого контуру. (Підтримуйте значення прозорості, щоб круглі краї все ще виглядали круглими).

Це працює, виглядає краще, ніж малювати масштабовану версію та має деякі інші цікаві властивості (наприклад, можливість контролю альфа-контуру для сміливості та збереження будь-яких "дірок" у вашому зображенні спрайта) - єдиний недолік полягає в тому, що ви можете " t дуже добре контролювати ширину контуру.


1

Я щось нове у всьому цьому, але ось моя ідея:

Ви можете використовувати альфа-канал текстури для створення іншої текстури. Будь-яке значення альфа нижче порогового значення буде встановлено повністю прозорим. Будь-яке вище буде повністю непрозорим. Використовуючи цю нову текстуру, ви можете встановити значення RGB будь-якого кольору. Масштабуйте цю нову "текстуру", щоб бути трохи більшою, ніж ваша текстура персонажа. Це дало б приємний суцільний колір навколо персонажа. Потім використовуйте цей колір разом з гауссовим шейдером, щоб надати приємно окреслене сяйво навколо створеної текстури. Я здогадуюсь, що це можна зробити, не створюючи іншої текстури, і будьте все шейдером на основі текстури символів.

Це взагалі має сенс?


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