Ertelenmiş gölgeleme - birden fazla ışık nasıl birleştirilir?


9

GLSL ile başlıyorum ve konumlar, normaller ve albedo ile G-buffer çıktısı basit ertelenmiş gölgeleme uyguladım.

Ayrıca basit bir nokta hafif gölgelendirici yazdım.

Şimdi nokta ışığı için bir küre çiziyorum ve çıktı bir aydınlatma tamponuna gidiyor.

Sorun şu ki, birden fazla ışık çizerken aydınlatma arabelleğinin sonuçlarını nasıl birleştirebilirim?

Örneğin, nokta ışığı gölgelendiricisini kullanarak ikinci ışığı lightbuffer'a çizerken, aydınlatma arabelleğindeki ikinci ışığa nasıl ilk ışığı eklerim. Yani, aynı çıktı tamponundan okuyamaz ve yazamazsınız?

Yanıtlar:


12

Katkı harmanlama, yani glBlendFunc (GL_ONE, GL_ONE) ve glEnable (GL_BLEND).


bunun için derinlik testinin devre dışı bırakılması gerekiyor mu?
woojoo666

1
@ woojoo666 Hayır. Aslında, derinlik testi daha az eşit olacak şekilde ayarlandığında etkinleştirilmelidir, böylece önceki geçişle tam olarak eşleşen yüzeyler geçer. Derinlik testi kapalıysa, yüzeyler arkalarında ne varsa yanlış bir şekilde ışık biriktirir. :)
Nathan Reed

hmm, bu tam olarak ne oluyor gibi görünüyor. harmanlamayı etkinleştirmek, derinlik testini etkin tutmuş olmama rağmen ön yüzleri arka yüzlerle harmanlıyor. maske ile de bir şeyler yapmam gerekir mi?
woojoo666

biraz daha fazla test yaptı, çizme sırası konuları gibi görünüyor (önden arkaya çizim, derinlik testinin doğru çalışmasını sağlar ve karışım sadece yüzler eş düzlemde olduğunda, arkadan öne her şeyin bir araya gelmesini sağlar). Bunu her şeyi sıralamadan yapmanın bir yolu var mı?
woojoo666

2
@ woojoo666 Aha, kendi başına çözdüğün gibi geliyor. Evet, herhangi bir karışım kullanmadan önce opak bir geçişte derinliği yatırmanız gerekir. Renk yazmaların devre dışı bırakıldığı bir z-ön geçişi olabilir veya başka bir yaygın yol, ilk geçişte harmanlama olmadan ortam / yön ışığı yapmak, daha sonra harmanlama ile daha sonraki geçişlerde nokta / spot ışıklar eklemektir.
Nathan Reed

2

Ertelenmiş oluşturucum için, g arabelleğindeki bilgileri kullanarak tüm ışıkları tek bir ışık oluşturma hedefinde topladım ve daha sonra son backbuffer görüntümü oluştururken ışık yoğunluğu için hedefi oluşturan örneği örnekledim.

Temel olarak, tüm oyun geometrimi g-tamponlarını oluşturmak için geometri geçişimden geçiriyorum. Oradan g-tamponlarını ışık geçişli gölgelendiricime besliyorum. Her ışık tam ekran dörtlü kullanılarak geçişten geçirilir. Bu şekilde piksel gölgelendiricim, g tamponundan tüm görünür yüzeyler için ışık yoğunluğunu hesaplayabilir ve daha sonra bunları hafif oluşturma hedefine ekleyebilir. Her bir ışık için ışık yoğunluğunu ışık arabelleğine eklemeniz yeterlidir, ancak yoğunluğu 0'dan 1'e sıkıştırdığınızdan emin olun.

Farklı ışık türlerini (nokta, spot ışığı, paralel) işlemek için yapmanız gereken tek şey, hangi aydınlatma prosedürlerinin yürütüleceğini belirlemek için muhtemelen sabit bir tampon kullanarak ışığın daha sağlam geçmesini sağlamaktır.


Evet ve soru şu - hafif render hedefine nasıl eklersiniz? Alfa karışımını Nathan Reed'in önerdiği gibi mi kullanıyorsunuz? Çünkü bildiğim kadarıyla aynı çıktı tamponundan (bu durumda ışık tamponu) okuyamaz ve yazamazsınız.
JBeurer

Hata! Çıktı birleşme ek katkı ile işlemesine izin verdim. Son görüntü için örnekleme yaparken, değeri bir yüzeyin alabileceği maksimum ışık yoğunluğu olarak benim için çalışan bir değere sıkıştırmak istediğiniz zamandır. Oradan ışıklarınızı gerektiği gibi ölçekleyebilirsiniz.
KlashnikovKid

Duvarın arkasında bir ışığın olduğu ve duvarın diğer tarafındaki şeyleri aydınlatmaması gereken durumları nasıl ele alırsınız?
jjxtra

@PsychoDad Bu gölgelerin etki alanı, ki bu ... daha karmaşık bir konu. :)
Nathan Reed

0

Muhtemelen bundan daha iyi bir cevap var, ama biliyorum, gölgelendiricinizde ikinci bir ışık yapmak için gerekli kodu tekrarlarsanız, bir tane yerine tek bir nesne üzerinde iki ışığı işleyebilirsiniz. İkinci ışık için çok fazla kod gerektiriyor ve biraz gereksiz dikişler yapıyor, ancak işe yaradığını biliyorum. Ancak, inanıyorum ki, birisi umarım sizin için işaret edeceği gibi, daha zarif bir çözüm olabilir.


Hayır, bu böyle çalışmıyor. Her nokta ışığı için bir küre çiziyorum. İkinci nokta ışık ilk ışığın etki alanına dayanmadıkça, ikinci ışık çizilmeyecektir. Tüm spot ışıkları için tam ekran dörtlü çizersem yönteminiz işe yarayacaktır, ancak küresel ilumination için tam ekran dörtlü kullanıldığı için doğru yaklaşım bu değildir. Diyelim ki 16 küçük nokta ışığım var. Ve genellikle her pikselin bir veya iki ışıkla yandığını söyleyebilirim. Ya 100 ışığım varsa? HAYIR
JBeurer

Bunu söylememin ana nedeni, sadece iki veya birkaç ışık kullanıyorsanız, yardımcı olabilir. Özellikle çok sayıda nesne oluşturuyorsanız, bir karışım kullanmak, sahneyi her ışık için yeniden çizmeniz gerektiği anlamına gelir; . Gölgelendiricide yapmak çok fazla ışık istiyorsanız sorunlara neden olur, ancak çok fazla şekil istiyorsanız karışım sorunlara neden olur. Her ikisinden de çok şey varsa, bir orta yol bulmanız gerekir, ancak genellikle oyunlarda birkaç ışık ve çok sayıda nesne vardır.
CodeNeko

Hayır, ertelenmiş gölgelendirme bu şekilde çalışmaz. Sahneyi yalnızca bir kez çizmem ve ilgili bilgileri G-Buffer'da saklamam gerekiyor. Sonra her ışık için bir etki alanı ve ışık tamponu ile karıştırın. Ve son olarak ışık tamponunu colorbuffer ile birleştirerek son gölgeli renk tamponunu elde ederim. Aydınlatma hesaplarının miktarı sahne karmaşıklığına bağlı değildir. İlk etapta ertelenmiş gölgelemenin ana avantajı budur.
JBeurer

Ah, bu çok daha mantıklı ve çok daha iyi olurdu.
CodeNeko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.