Sprite garis besar

9

Saat ini saya sedang mengerjakan game 2D, dan tugas saya saat ini adalah untuk menguraikan objek yang dipilih.

Saya pada dasarnya menggunakan shader blur untuk melakukannya sepenuhnya runtime. Saya pertama-tama menggambar sprite saya menggunakan shader gaussian blur vertikal, kemudian saya menggambarnya dengan shader gaussian blur horizontal, dan kemudian saya menggambar sprite saya secara normal.

Ini shader blur saya: 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 adalah offset yang memungkinkan saya untuk menguji pixel pembulatan SampleWeights adalah bobot yang dihitung dengan fungsi gaussian ( http://en.wikipedia.org/wiki/Gaussian_blur )

Inilah hasilnya:

masukkan deskripsi gambar di sini

Ini tidak seburuk itu, cukup halus, tetapi tidak cukup terlihat dalam permainan ... Tapi saya ingin dapat mengontrol ketebalan (untuk membuatnya lebih besar), dan menambahkan garis buram pertama sebelum memudar dalam alpha (untuk membuat lebih terlihat). Dan saya merasa seperti gaussian blur mungkin tidak sebagus yang saya pikirkan untuk tugas saya :)

Gagasan lain adalah membuatnya secara otomatis dari .png (menggunakan skrip photoshop untuk membuatnya otomatis). Saya hanya perlu mengisi garis besar piksel dengan warna kustom, menyimpan nilai alfa di komponen Merah misalnya, dan mengatur semua komponen lain ke 0. Lalu saya hanya perlu menerapkan shader yang menggantikan piksel transparan ke warna yang saya inginkan

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;
    }
}

Masalahnya adalah, saya menggunakan kompresi DXT5 untuk sprite saya, jadi saya tidak bisa memastikan warna yang akan saya dapatkan di shader saya akan sama persis dengan yang saya tulis. Itu sebabnya saya bahkan tidak mencobanya ... Ada pikiran?

Setiap saran akan diterima :)

s0ubap
sumber
Anda harus dapat mengontrol ketebalan dan penurunan alpha pada shader Anda. Ingin mempostingnya untuk referensi?
Seth Battin
Saya menggunakan Gaussian blur shader dari sampel ini: tautan izinkan saya mengedit posting saya untuk menunjukkan kepada Anda shader secara detail
s0ubap
Saya tidak yakin Gaussian blur adalah yang tepat untuk Anda. Sebagai gantinya cobalah radial blur.
user1306322

Jawaban:

6

Apa yang mungkin Anda cari adalah bentuk deteksi tepi sebelum, sesudah, atau bahkan sebelum dan sesudah keburaman Gaussian Anda. Mungkin versi Sobel Edge Detection bisa berfungsi. Saya tahu permainan Anda adalah 2D tetapi jika halaman wiki terlalu kasar, inilah tutorial tentang cara membuatnya bekerja di UDK yang mungkin menerjemahkan lebih baik.

Deteksi tepi Anda hanya benar-benar harus menemukan tepi saluran alpha jika Anda memerlukan peningkatan kecepatan.

Alex Shepard
sumber
Menarik! Saya mencobanya. Hasilnya bagus, kecuali ketika saya memperbesar / memperkecil ... Pixel muncul dan menghilang, menghasilkan artefak yang tidak diinginkan ...
s0ubap
1
Artefak apa yang Anda lihat? Bisakah Anda memberikan gambar?
Alex Shepard
2

Apa yang berhasil bagi saya dengan menguraikan teks adalah:

  • Pilih warna garis besar
  • Gambarlah teks pada (x-1, y-1) dengan warna garis besar
  • Gambarlah teks di (x + 1, y-1) dengan warna garis besar
  • Gambarlah teks pada (x-1, y +1) dengan warna garis besar
  • Gambarlah teks pada (x + 1, y + 1) dengan warna garis besar
  • Gambarkan teks di (x, y)

Anda dapat melakukan hal yang sama - yang perlu Anda lakukan hanyalah menggambar sprite dengan piksel buram yang diwarnai dengan warna outline Anda. (Pertahankan nilai transparansi sehingga ujung bundar tetap terlihat bulat).

Ini berfungsi, terlihat lebih baik daripada menggambar versi berskala, dan memiliki beberapa sifat keren lainnya (seperti bisa mengontrol garis besar alfa untuk keberanian, dan mempertahankan "lubang" dalam gambar sprite Anda) - satu-satunya kelemahan adalah Anda dapat ' t terlalu mengontrol lebar garis terlalu baik.

ashes999
sumber
1

Saya agak baru dalam hal ini, tapi ini ide saya:

Anda bisa menggunakan saluran alpha tekstur Anda untuk membuat tekstur lain. Nilai alfa apa pun di bawah nilai ambang batas akan disetel sepenuhnya transparan. Apa pun di atas akan sepenuhnya buram. Dengan menggunakan tekstur baru ini, Anda dapat mengatur nilai RGB menjadi warna yang Anda inginkan. Skala "tekstur" baru ini menjadi sedikit lebih besar dari tekstur karakter Anda. Ini akan memberi Anda warna solid yang bagus di sekitar karakter. Kemudian gunakan warna itu dengan Gaussian shader Anda untuk memberikan cahaya yang bagus di sekitar tekstur yang Anda buat. Saya menduga ini bisa dilakukan tanpa membuat tekstur lain, dan semua shader didasarkan pada tekstur karakter.

Apakah ini masuk akal?

Aglassman
sumber
Metode ini memiliki kelemahan utama ketika berhadapan dengan bentuk non-cekung. Misalnya ketika diterapkan pada donat hanya tepi luar yang akan mendapatkan garis besar. Belum lagi distorsi ketebalan garis besar lainnya.
Kromster