IF ifadeleriyle bir yerine iki gölgelendirici kullanma


9

ES 2.0'a nispeten büyük bir opengl ES 1.1 kaynağı taşımak için çalışıyorum.

OpenGL ES 2.0'da (yani her şey gölgelendiriciler kullanır), üç kez bir çaydanlık çizmek istiyorum.

  1. Birincisi, tek tip bir renkle (ala eski glColor4f).

  2. İkincisi, köşe başına renk ile (çaydanlık köşe rengi de içerir)

  3. Üçüncüsü, köşe başına dokuya sahip

  4. Ve belki de tepe noktası dokusu ve rengi ile dördüncü olanı. Ve sonra belki de normal olan 5'inci.

Bildiğim kadarıyla uygulama ile ilgili iki seçeneğim var. Birincisi, davranışı değiştirmek için ayarlanmış bir üniforma ile yukarıdakilerin tümünü destekleyen bir gölgelendirici yapmaktır (örneğin, tekil renk üniforma veya tepe noktası renk üniforma kullanın).

İkinci seçenek, her durum için farklı bir gölgelendirici oluşturmaktır. Bazı özel gölgelendirici önişlemleriyle, yapmak o kadar karmaşık değildir, ancak endişe verici, çizim nesneleri arasında gölgelendiricileri değiştirmenin performans maliyetidir. Önemsiz derecede küçük olmadığını okudum.

Yani, bununla ilgili en iyi yol hem inşa etmek hem de ölçüm yapmaktır, ancak herhangi bir girişi duymak iyi olur.

Yanıtlar:


10

Dallanmanın performans maliyeti de önemsiz derecede küçük olmayabilir. Sizin durumunuzda çizilen tüm köşeler ve parçalar gölgelendiricilerinizden aynı yolu alacaktır, bu nedenle modern masaüstü donanımında olabildiğince kötü olmayacaktır, ancak modern kullanmamanız anlamına gelen ES2 kullanıyorsunuz masaüstü donanımı.

Dallanma ile ilgili en kötü durum şöyle bir şey olacaktır:

  • şubenin her iki tarafı değerlendirilir.
  • gölgelendirici derleyicisi tarafından bir "mix" veya "step" komutu oluşturulur ve hangi tarafın kullanılacağına karar vermek için kodunuza eklenir.

Ve tüm bu ekstra talimatlar çizdiğiniz her köşe veya parça için çalıştırılacaktır. Bu , gölgelendirici değişikliğinin maliyetine karşı tartılması gereken milyonlarca ekstra talimat anlamına gelir.

Apple'ın " iOS için OpenGL ES Programlama Kılavuzu " (hedef donanımınız için temsilci olarak alınabilir) dallanma hakkında şunları söyler:

Dallanmadan Kaçının

3D grafik işlemcilerde paralel olarak işlemleri yürütme yeteneğini azaltabildiğinden, dallar gölgelendiricilerde önerilmez. Gölgelendiricilerinizin dal kullanması gerekiyorsa, şu önerileri izleyin:

  • En iyi performans: Gölgelendiricinin derlendiği zaman bilinen bir sabit üzerindeki dal.
  • Kabul edilebilir: Düzgün bir değişken üzerinde dal.
  • Potansiyel olarak yavaş: Gölgelendiricinin içinde hesaplanan bir değerin dallanması.

Birçok düğme ve kolu olan büyük bir gölgelendirici oluşturmak yerine, belirli oluşturma görevleri için özelleştirilmiş daha küçük gölgelendiriciler oluşturun. Gölgelendiricilerinizdeki dal sayısını azaltmak ve oluşturduğunuz gölgelendiricilerin sayısını artırmak arasında bir denge vardır. Farklı seçenekleri test edin ve en hızlı çözümü seçin.

Buradaki "Kabul Edilebilir" slotta olduğunuzdan memnun olsanız bile, aralarından seçim yapabileceğiniz 4 veya 5 vakada gölgelendiricilerinizdeki talimat sayısını artıracağınızı düşünmeniz gerekir. Hedef donanımınızdaki talimat sayısı sınırlarının farkında olmalı ve yukarıdaki Apple bağlantısından tekrar alıntı yaparak bunların üzerine çıkmadığınızdan emin olmalısınız:

Bu sınırlar aşıldığında bir yazılım yedeklemesi uygulamak için OpenGL ES uygulamaları gerekli değildir; bunun yerine, gölgelendirici derleme veya bağlantı kuramaz.

Bunların hiçbiri, dallanmanın ihtiyacınız için en iyi çözüm olmadığını söylemez . Her iki yaklaşımı da tercih etmeniz gerektiğini doğru bir şekilde belirlediniz, bu yüzden son öneri bu. Ancak, gölgelendiricilerin daha karmaşık hale geldikçe, dallanma temelli bir çözümün birkaç gölgelendirici değişikliğinden çok daha yüksek ek yük verebileceğini unutmayın.


3

Bağlayıcı gölgelerin maliyeti önemsiz olmayabilir, ancak aynı gölgelendiricileri kullanan tüm nesneleri toplulaştırmadan binlerce öğe oluşturmazsanız, bu sizin darboğazınız olmayacaktır.

Bunun mobil cihazlar için geçerli olup olmadığından emin değilim, ancak koşul sabit ve üniforma arasındaysa GPU'lar şubelerle korkunç derecede yavaş değildir. Her ikisi de geçerli, her ikisi de geçmişte kullanılmış ve gelecekte kullanılmaya devam edecek, hangisinin sizin durumunuzda daha temiz olacağını düşündüğünüzü seçin.

Ayrıca, bunu gerçekleştirmenin birkaç yolu daha vardır: "Uber-gölgelendiriciler" ve OpenGL gölgelendirici programlarının bağlanma şekliyle ilgili biraz hile.

"Über gölgelendiriciler" esasen dallanma eksi olmak üzere ilk tercihtir, ancak birden fazla gölgelendiriciniz olacaktır. Bunun yerine kullanmanın if- ifadelerini, sen önişlemci kullanmak #define, #ifdef, #else, #endif, ve uygun dahil olmak üzere farklı sürümleri, derlemek #definegerekenler için s.

vec4 color;
#ifdef PER_VERTEX_COLOR
color = in_color;
#else
color = obj_color;
#endif

Ayrıca gölgelendiriciyi ayrı işlevlere bölebilirsiniz. Tüm işlevler için prototipleri tanımlayan ve çağıran bir gölgelendiriciye sahip olun, uygun uygulamaları içeren bir grup ekstra gölgelendiriciyi bağlayın. Tüm hileleri değiştirmek zorunda kalmadan tüm nesneler üzerinde filtrelemenin nasıl yapıldığını değiştirmeyi kolaylaştırmak için gölge eşleme için bu hileyi kullandım.

//ins, outs, uniforms

float getShadowCoefficient();

void main()
{
    //shading stuff goes here

    gl_FragColor = color * getShadowCoefficient();
}

Sonra, getShadowCoefficient()gerekli üniformaları tanımlayan birden fazla gölgelendirici dosyam olabilir ve başka bir şey yoktu. Örneğin, aşağıdakileri shadow_none.glsliçerir:

float getShadowCoefficient()
{
    return 1;
}

Ve shadow_simple.glsliçerir (CSM'leri uygulayan gölgelendiricimden basitleştirilmiş):

in vec4 eye_position;

uniform sampler2DShadow shad_tex;
uniform mat4 shad_mat;

float getShadowCoefficient()
{
    vec4 shad_coord = shad_mat * eye_position;
    return texture(shad_tex, shad_coord).x;
}

Ve sadece farklı bir shadow_*gölgelendiriciyi bağlayarak gölgelendirmeyi isteyip istemediğinizi seçebilirsiniz . Bu çözüm çok daha fazla ek yüke sahip olabilir, ancak GLSL derleyicisinin bunu yapmanın diğer yollarına kıyasla ekstra ek yükü optimize edecek kadar iyi olduğunu düşünmek istiyorum. Bu konuda hiç test yapmadım, ama bunu yapmayı seviyorum.

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.