Bagaimana saya bisa mengurangi alias dalam efek cahaya garis besar saya?

42

Saya mencoba untuk mereplikasi efek garis besar pada game Left 4 Dead. Efeknya menyebabkan garis objek bersinar, bahkan ketika objek tersumbat. Berikut ini adalah screenshot dari efeknya:

masukkan deskripsi gambar di sini

Saya agak bisa meniru efek ini dalam program berbasis OpenGL saya. Inilah yang sedang saya lakukan:

  • Buat tekstur warna dan kedalaman yang setengah dari ukuran layar untuk menampilkan objek yang bersinar
  • Bersihkan tekstur warna kedalaman / cahaya. Warna dibersihkan menjadi hitam.
  • Untuk setiap objek bercahaya, renderkan ke tekstur cahaya sebagai warna solid
  • Lakukan blur gaussian yang dapat dipisahkan pada tekstur cahaya
  • Jadikan adegan resolusi penuh seperti biasa
  • Tambahkan tekstur cahaya dengan adegan normal secara positif, tetapi gunakan tekstur kedalaman cahaya untuk menutupi objek, hanya meninggalkan garis kabur.

Ini screenshot dari pendekatan saya:

masukkan deskripsi gambar di sini

Berikut adalah shader fragmen yang menggabungkan tekstur cahaya dengan adegan:

uniform sampler2D glowColorTex;
uniform sampler2D glowDepthTex;
uniform sampler2D sceneColorTex;
void main()
{
    vec2 uv = gl_TexCoord[0].st;

    vec4 color = texture2D( sceneColorTex, uv);

    float depth = texture2D( glowDepthTex, uv).r;
    if(depth == 1.0) {
        color += 2.0 * texture2D( glowColorTex, uv);
    }

    gl_FragColor = color;
}

Seperti yang Anda lihat, sepertinya itu berfungsi sebagian besar, tetapi aliasing pada garis besarnya benar-benar buruk.

Adakah yang punya saran untuk menghaluskan tepi bagian dalam garis besar?

Haruskah saya mengambil sampel nilai kedalaman tetangga dari setiap piksel dan skala cahaya berdasarkan jumlah nilai kedalaman yang sama dengan 1,0?

Atau adakah pendekatan yang lebih baik yang akan menghasilkan hasil yang lebih halus?

flashk
sumber

Jawaban:

13

Mungkin alih-alih mengeceknya terhadap buffer kedalaman resolusi rendah, Anda mungkin menggunakan tes stensil. Saat merender adegan normal, Anda cukup merender objek yang seharusnya bersinar ke dalam buffer stensil (tanpa pengujian kedalaman, saya pikir) dan kemudian membaurkan tekstur glow yang lengkap di dalamnya, tetapi konfigurasikan uji stensil untuk hanya melewati di mana buffer stensil berada tidak diatur, oleh karena itu menutupi objek resolusi tinggi.

Dengan cara ini Anda mendapatkan siluet yang tepat dari objek asli, sedangkan perataan tepi hanya akan menghasilkan hasil perkiraan, tetapi mungkin ini sudah cukup untuk Anda.

Kata Chris Reinstate Monica
sumber
Terima kasih, itu pasti membantu. Saya berharap untuk beberapa teknik yang akan mendukung beberapa bentuk anti-aliasing, tetapi ini masih merupakan peningkatan besar.
flashk