GLSL - Global değişkenleri ana işlev kapsamı dışında bildirme


12

GLSL'deki ana işlev kapsamınızın dışındaki değişkenleri bildirmenize yardımcı olur mu? Bu değişkenler gerçekten yeniden kullanılıyor mu ve daha verimli mi?

Söz konusu kod:

varying vec2 vposition;
uniform float seed;
uniform float top;
uniform float bottom;
uniform float phi;
uniform float theta;
uniform float scaledPI;
uniform float yn;
uniform float ym;
uniform float rx;
uniform float ry;
uniform float radius;

const float PI = 3.141592653589793238462643383;

float left;
float right;
float mscaled;
float xn;
float xm;
void main() {
    float t = vposition.y * yn + ym;

    if(t <= 0.0 || t >= PI){
        left = phi - PI;
        right = phi + PI;
    }else{
        mscaled = scaledPI / (1 - abs(Math.cos(theta)));
        mscaled = mscaled < PI ? mscaled : PI;
        left = phi - mscaled;
        right = phi + mscaled;
    }
    xn = (left - right) / ((-rx / 2.0) - (rx / 2.0));
    xm = left - ((-rx/2.0) * xn);
    float p = vposition.x * xn + xm;

    vec3 coords = vec3( sin(p) * sin(t), cos(t), cos(p) * sin(t) );
    float nv = surface( vec4( coords, seed ) );
    gl_FragColor = vec4( vec3( nv, nv, nv ), 1.0 );
}

3
Bu soru kafa karıştırıcı. GLSL'nin bir ana döngüsü yoktur. main()Fonksiyonu mu demek istediniz ? Değerleriniz aslında küresel değişkenler mi (GLSL paritedeki üniformalar veya nitelikler) mi yoksa sabit değerler mi?
Sean Middleditch

Neden bahsettiğinize örnek olarak bazı kodlar gönderebilir misiniz?
Nathan Reed

Soruyu kodla güncelledim.
RodgerDodger

@ user1286792: Bu, GLSL'nin bir ana döngüsü olmadığı gerçeğini değiştirmez . Ne hakkında konuştuğunuz belli değil. Bunu yaparak tam olarak ne kurtarılacağını düşünüyorsun?
Nicol Bolas

@NicolBolas Soruyu daha açık olacak şekilde güncelledim. Umarım gelecekte birileri için faydalıdır.
RodgerDodger

Yanıtlar:


33

Sanırım sormaya çalıştığın şeyi alıyorum. Ben birincil endişe dışında tanımlanan tek tip olmayan değişkenler olduğunu varsayalım main():

float left;
float right;
float mscaled;
float xn;
float xm;

GPU ve GLSL'nin nasıl çalıştığına bir göz atalım. GPU'da bir yığın veya çağrı etkinleştirme kayıtları yoktur. C derleyicisinin çoğu CPU'da yapabileceği gibi GLSL'de kapsamı veya yerel değişkenleri simüle etmenin bir yolu yoktur. Var olan tek şey, ya tekdüze kayıtlar, gölgelendirici sahne girişleri, çıkışlar ve gölgelendiricinin çağrılmasına özgü yerel kayıt dosyasıdır.

Başka bir deyişle, bir işlev veya yığın veya yığın diye bir şey olmadığından, herhangi bir yerde bildirilen tüm değişkenler bir kayıt defterinde yaşar. GLSL'de bir kapsam için yerel veya tüm dosya için global olmaları fark etmez. Onlar sadece kayıt.

Bununla birlikte, kayıt ayırıcısı GLSL standardının bir parçası değildir. Farklı OpenGL uygulamaları, GPU'nun anladığı düşük seviye makine koduna yüksek seviye GLSL kodunu dönüştürme söz konusu olduğunda değişen kalite seviyelerine sahip olabilir. Bir derleyicinin daha karmaşık kısımlarından biri (GLSL veya başka türlü) kayıt tahsisidir . Bu, derleyicinin belirli bir değişkeni hangi kayıtların kapladığını belirleyen kısmıdır. C, genellikle çok küçük kayıt dosyalarıyla (özellikle x86'da) uğraşmak zorunda olduğundan biraz daha zorlaşır ve kayıt dökülmesiyle (değişkenleri yığına hareket ettirerek) ve takma adla (işlevleri çağırmadan önce değişkenleri RAM'e geri kazandırır) ve Çıktıyı talep eden tek talimatlar belirli bir sicilde (x86)idivÖrneğin). GPU'larda yığın veya yığın olmaması nedeniyle büyük bir ish kayıt dosyası vardır, bu nedenle ayırıcı daha basit olabilir.

Ancak, kayıt dosyası sonsuz değildir. Donanımınız tarafından desteklenen kayıtlardan daha fazla değişkeniniz varsa, derleyicinin tüm değişkenlerinizi kayıtlara sığdırmayı denemesi gerekecektir. Bu genellikle bir çeşit canlılık aralığı kontrolü gerektirir . Yani, xnbir hesaplama için bir değişken kullanırsanız ve bir daha asla bir daha kullanmazsanız, derleyici bunu belirleyebilir ve daha sonra işgal edilen kaydın xndaha sonra başka bir değişken tarafından kullanılabileceğini bilir , böylece kayıtlardan daha fazla değişkene izin verir (çok uzun çünkü aynı anda çok fazla canlı değişken yoktur).

Ancak derleyici bunu yapamayabilir. Öyle değil. Veya sadece bazı durumlarda yapabilir. Daha basit derleyiciler verilen kapsamları çözmek çok daha kolay bir problemdir. Yerel işlev değişkenlerine tahsis edilen tüm kayıtlar, işlev sona erdikten sonra yeniden kullanılabilir, çünkü değişkenlerin öldüğünü bilir. Küresel değişkenlerin böyle kolay bir garantisi yoktur. Bu nedenle, daha az yetenekli derleyiciler yaşamlarını da optimize etmeyebilir ve küresel değişkenler her zaman bir kayıt yiyecektir. Bu daha yavaş bir şey yapmaz, ancak bazı sürücülerde yazabileceğiniz gölgelendiricinin boyutunu sınırlayabilir.

Genel olarak, tüm değişkenleri yerelleştirmenizi şiddetle tavsiye ederim. Tanımı, değişkenin mantıklı kullanımına yakın tutun. Bu sadece GLSL için değil, tüm programlama dilleri için geçerlidir. Ayrıca mümkün olan her durumda her "değişken" const yapma tavsiye ederim. Yine, bazı daha az yetenekli derleyicilere, bazı optimizasyonların mümkün olduğuna dair bir ipucu olabilir ve daha da önemlisi, kodunuzu daha fazla kendi kendini belgeleyen ve bakımı kolay hale getirir.

Ve tabii ki, sizin zorunlu "test etmek ve kesin olarak öğrenmek için sadece profil" tavsiyeniz. Gölgelendiricinizi küresellerinizle birlikte ve küresel olmadan yazın ve profil oluşturun. Çevrimiçi olarak herhangi bir performans tavsiyesine güvenilmemeli ve ya destek olarak ya da güncelliğini yitirmiş olduğu varsayılmalıdır.


Demek istediğim bu. Soruma mükemmel cevap verdiniz ve ne istediğimi daha iyi açıkladınız.
RodgerDodger

1
Aslında bazen dizileri sabit olmayan yerine sabit olarak bildirmek tüm gölgelendiriciyi yavaşlatır (ÇOK Yavaş). GTX 460'ımda bu sorunu fark ettim.
Tara

Garip bir hatadan kurtuldum ve değişkenlerin ana dışında bildirildiği için gölgelendiriciyi derleyemeyen bir Adreno GPU (OpenGL ES 3.1) olduğundan şüpheleniyorum.
Comodoro

Şimdiye kadar gördüğüm en kapsamlı SO cevaplarından biri - aferin!
duhaime

Bugün yeni bir şey öğreniyorum. Bugün öğreniyorum, glsl'yi gerçekten bilmiyorum veya anlamıyorum. Sadece sylindrical uzay dönüştürülmüş geometri gif yapmak için kullanabilirsiniz çünkü nasıl çalıştığını anlamak anlamına gelmez.
cmarangu
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.