Atualmente, estou trabalhando em um jogo 2D, e minha tarefa atual é descrever o objeto selecionado.
Basicamente, uso um shader de desfoque para fazê-lo em tempo de execução total. Primeiro, desenho meu sprite usando um sombreador de desfoque gaussiano vertical, depois o desenho com um sombreador de desfoque gaussiano horizontal e depois desenho meu sprite normalmente.
Aqui está o meu shader shader: 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 são as compensações que permitem testar os pixels de arredondamento. SampleWeights são pesos calculados com a função gaussiana ( http://en.wikipedia.org/wiki/Gaussian_blur )
Aqui está o resultado:
Não é tão ruim, bastante suave, mas não é visível o suficiente no jogo ... Mas eu gostaria de poder controlar a espessura (para aumentá-la) e adicionar um primeiro contorno opaco antes de desbotá-la em alfa (para mais visível). E eu sinto que o borrão gaussiano talvez não seja tão bom quanto eu pensava na minha tarefa :)
Outra idéia é gerá-lo automaticamente a partir do .png (usando um script do photoshop para torná-lo automático). Eu só preciso preencher os pixels do contorno com uma cor personalizada, armazenando o valor alfa no componente Vermelho, por exemplo, e definir todos os outros componentes como 0. Então, só preciso aplicar um sombreador que substitua os pixels transparentes pela cor desejada
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;
}
}
O problema é que estou usando a compressão DXT5 para o meu sprite, então não tenho certeza de que a cor do shader será exatamente a mesma que escrevi. É por isso que eu nem tentei ... Alguma idéia?
Qualquer conselho seria bem vindo :)
fonte
Respostas:
O que você provavelmente está procurando é uma forma de detecção de borda antes, depois ou mesmo antes e depois do desfoque gaussiano. Talvez uma versão do Sobel Edge Detection possa funcionar. Eu sei que seu jogo é 2D, mas se a página da wiki for muito grossa, aqui está um tutorial sobre como fazê-lo funcionar no UDK que pode ser traduzido melhor.
Sua detecção de borda só precisa encontrar as bordas do canal alfa se você precisar de um aumento de velocidade.
fonte
O que funcionou para mim com o esboço de texto foi:
Você pode fazer a mesma coisa - tudo o que você precisa fazer é desenhar o sprite com os pixels opacos coloridos com a cor do contorno. (Mantenha os valores de transparência para que as bordas arredondadas ainda pareçam redondas).
Isso funciona, parece melhor do que desenhar uma versão em escala e tem algumas outras propriedades interessantes (como poder controlar o alfa do contorno para obter ousadia e manter quaisquer "furos" na imagem do sprite) - a única desvantagem é que você pode ' realmente não controla muito bem a largura do contorno.
fonte
Eu sou meio que novato em tudo isso, mas aqui está a minha ideia:
Você pode usar o canal alfa da sua textura para criar outra textura. Qualquer valor alfa abaixo de um valor limite será definido como totalmente transparente. Qualquer um dos itens acima será totalmente opaco. Usando essa nova textura, você pode definir os valores de RGB para qualquer cor que desejar. Escale essa nova "textura" para ser um pouco maior que a textura do seu personagem. Isso daria uma boa cor sólida ao redor do personagem. Em seguida, use essa cor com seu sombreador gaussiano para dar um brilho agradável ao redor da textura criada. Suponho que isso possa ser feito sem criar outra textura e ser todo o sombreamento baseado na textura do personagem.
Isso faz algum sentido?
fonte