OpenGL: Gölgelendiricileri nereye yerleştirmeliyim?


17

OpenGL ES 2.0 öğrenmeye çalışıyorum ve gölgelendiricileri "yönetmek" için en yaygın uygulamanın ne olduğunu merak ediyorum.
Bu soruyu soruyorum çünkü bulduğum örneklerde (android sdk ile sağlanan API Demosunda yer alan gibi), genellikle GLRenderer sınıfının içindeki her şeyi görüyorum ve bu yüzden sahip olabileceğim şeyler ayırmayı tercih ederim, örneğin, bir OpenGL ES 1.0 kodumda olduğu gibi dokulu bir dörtlü çizmek istediğimde yeniden kullanabileceğim bir GLImage nesnesi (sadece şu anda 2D'ye odaklanıyorum). Bulduğum hemen hemen her örnekte gölgelendiriciler sadece sınıf nitelikleri olarak tanımlanır. Örneğin:

public class Square {

public final String vertexShader =
        "uniform mat4 uMVPMatrix;\n" +
        "attribute vec4 aPosition;\n" +
        "attribute vec4 aColor;\n" +
        "varying vec4 vColor;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vColor = aColor;\n" +
        "}\n";

public final String fragmentShader =
        "precision mediump float;\n" +
        "varying vec4 vColor;\n" +
        "void main() {\n" +
        "  gl_FragColor = vColor;\n" +
        "}\n";
// ...
}

Bu soruların bir kısmı aptal ise şimdiden özür dilerim, ama daha önce gölgelendiricilerle hiç çalışmadım.

1) Yukarıdaki kod gölgelendiricileri tanımlamanın ortak yolu mudur?
2) Ayrı bir Shader sınıfım olmalı mı?
3) Gölgelendiriciler bunları kullanan sınıfın dışında tanımlanırsa, özniteliklerinin adlarını nasıl bilebilirim (örneğin aşağıdaki kod parçasında "aColor"), böylece onları bağlayabilir miyim?

colorHandle = GLES20.glGetAttribLocation(program, "aColor");

Yanıtlar:


16

Her zaman gölgelendiricileri tanımlamaktan hoşlanmadım (bir dize). Bir metin dosyasında benimkini yapmayı ve yüklerken okumayı tercih ederim. Bir dizede tanımlamak hata ayıklamak için can sıkıcı ve sadece dağınık görünüyor. Bir dizginin yerine yazmak ve olması gerektiği gibi biçimlendirilmiş görmek çok daha kolaydır.

Ayrıca gölgelendiricilerde okuma ve gölgelendirici hata ayıklaması için günlük bilgilerini yazdırma gibi ortak gölgelendirici işlevselliğine sahip ayrı bir sınıfım var.

Gölgelendiricilerin tanımlandığı her yerde, örnekte yaptığınız gibi adlara erişebilirsiniz. Dize hazır bilgisini kullanmak gölgelendiriciler için kabul edilebilir, çünkü bu değerleri uyguladıktan sonra değişme olasılığı düşüktür.

Ancak, sonunda size kalmış. Şu anda yaptığınız yol, size herhangi bir sorun yaratmıyorsa, harika çalışıyor.


2
Gölgelendiricilerinizin ayrı dosyalara sahip olması, kullanışlı-zahmetli gölgelendirici düzenleyicilerinizi kullanabileceğiniz ve tam sözdizimi vurgulama yapabileceğiniz ve hatta destekliyorsa, programınızda test etmeden önce önizleme yapabileceğiniz anlamına gelir.
Raceimaztion

6
Bir dizede gölgelendiricilerin olmasının tek gerçek nedeni, hızlı testler ve öğreticilerdir. Burada dosya işleme "gereksiz kod" un büyük kısmını ekler.
Jari Komppa

2
Ayrıca gölgelendirici dosyalarına çalışırken yeniden yükleme uygulayarak oyunu yeniden başlatmadan değişikliklerin hatalarını ayıklamanıza olanak tanır. Verimlilik ++
Liosan

Onları bir dosyadan okuma ve ayrı bir Shader sınıfına sahip olma fikrini seviyorum. Onları her zaman bir dize içinde görmek beni şaşırttı çünkü genellikle tanımlandıkları şekilde mi yoksa sadece öğrenme amaçlı mı olduğunu bilmiyordum. Teşekkürler!
miviclin

8

Gölgelendirici (ve dolayısıyla maddi) yönetimi, grafik sisteminiz daha karmaşık hale geldiğinde karşılaştığınız oldukça zor bir sorundur ve her gölgelendiricinin büyük kod çoğaltmasına yol açacağını fark edersiniz. İşte bunu çözmenin birkaç alternatif yolu:

  • Sadece birkaç gölgelendiricinin bulunduğu küçük örnekler, Jari Komppa'nın yorumladığı gibi dosya işlemeyi önlemek için bunları dize olarak kodlama eğilimindedir
  • Daha iyi, sözdizimi vurgulama ve uygun biçimlendirme yapabileceğiniz ayrı dosyalar kullanmaktır. Ayrıca, bu dosyalardaki değişiklikleri izleyen basit bir hata ayıklama sistemini kodlayabilir ve oyununuz çalışırken değiştirilen gölgelendiriciyi anında uygulayabilirsiniz.
  • Malzeme sayısı arttığında, bir gölgelendirici jeneratörü neredeyse bir zorunluluk haline gelir. Temel olarak "fragman gölgelendirici normal eşleştirme snippet'i" gibi ortak snippet'leri tanımlar ve istenen bileşenleri ekleyerek tüm gölgelendiricilerinizi oluşturur.
    • Sabit kodlu dize snippet'leri kullanabilirsiniz, ancak bu gerçekten hızlı bir şekilde dağınık hale gelir, bu yüzden dosyalar bir kez daha iyi bir fikirdir.
    • Ayrı dosyalarda (veya aynı) kod parçalarına sahip olabilir veya alternatif olarak, şeyleri etkinleştirmek / devre dışı bırakmak için önişlemciyi (veya tek biçimli bayrakları) kullandığınız ubershader / supershader kullanabilirsiniz.

Özellik ve tek tip adlara gelince, sadece tüm gölgelendiricilerde tutarlı bir adlandırma kullanın.


Gölgelendiricileri kesinlikle ayrı bir dosyaya taşıyacağım. Teşekkürler!
miviclin
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.