Toplamda yalnızca bir düzine karakter oluşturmadığınız sürece oluşturma anahatları, eğriliğe yaklaşmak için karakter başına gereken köşe sayısı nedeniyle "hareketsiz" kalır. Piksel gölgelendiricideki çerçeve eğrilerini değerlendirmek için yaklaşımlar olmasına rağmen, bunlar kolayca antialiasize edilmekten muzdariptir, bu da mesafe haritası dokulu bir dörtlü kullanarak önemsizdir ve gölgelendiricideki eğrileri değerlendirmek hala hesaplamadan çok daha pahalıdır.
"Hızlı" ve "kalite" arasındaki en iyi değiş tokuş hala imzalı mesafe alanı dokusuna sahip dokulu dörtlüdür. Öyle çok az ama çok değil, daha yavaş bir düz, normal dokulu dörtlü kullanmaktan daha. Kalitesi ise tamamen farklı bir baloda. Sonuçlar gerçekten çarpıcı, elde edebileceğiniz kadar hızlı ve parlaklık gibi efektlerin de eklenmesi çok kolay. Ayrıca, teknik gerekirse eski donanıma güzel bir şekilde indirilebilir.
Teknik için ünlü Valve belgesine bakın .
Teknik kavramsal olarak örtülü yüzeylerin (metaballlar ve benzeri) nasıl çalıştığına benzer, ancak çokgen üretmez. Tamamen piksel gölgelendiricisinde çalışır ve bir uzaklık fonksiyonu olarak dokudan örneklenen mesafeyi alır. Seçilen bir eşiğin (genellikle 0,5) üzerindeki her şey "giriş", diğer her şey "çıkış" tır. En basit durumda, 10 yıllık gölgelendirici özelliği olmayan donanımda, alfa test eşiğini 0,5'e ayarlamak tam olarak bunu yapacaktır (özel efektler ve kenar yumuşatma olmadan da).
Yazı tipine biraz daha fazla ağırlık eklemek isterseniz (sahte kalın), biraz daha küçük bir eşik, tek bir kod satırını değiştirmeden hile yapar (sadece "font_weight" üniformanızı değiştirin). Işıma efekti için, kişi sadece bir eşiğin üzerindeki her şeyi "giriş" olarak ve diğeri (daha küçük) eşiğin üzerindeki her şeyi "dışarı, ama parlaklıkta" ve ikisi arasındaki LERP'ler olarak kabul eder. Kenar yumuşatma benzer şekilde çalışır.
Tek bir bit yerine 8 bitlik imzalı bir mesafe değeri kullanarak, bu teknik doku haritanızın etkin çözünürlüğünü her boyutta 16 kat artırır (siyah ve beyaz yerine, tüm olası tonlar kullanılır, bu nedenle 256 kat aynı depolama alanını kullanan bilgiler). Ancak 16x'in çok ötesinde büyütseniz bile, sonuç hala oldukça kabul edilebilir görünüyor. Uzun düz çizgiler nihayetinde biraz dalgalı olacak, ancak tipik "bloklu" örnekleme eserleri olmayacak.
Dörtlü noktaları noktalardan oluşturmak için bir geometri gölgelendirici kullanabilirsiniz (veri yolu bant genişliğini azaltın), ancak dürüstçe kazançlar oldukça marjinaldir. GPG8'de açıklandığı gibi anında karakter oluşturma için de aynı şey geçerlidir. Örnekleme yükü yalnızca çizilecek çok fazla metniniz varsa itfa edilir . Bence kazanımlar, eklenen karmaşıklık ve indirilemezlik ile hiçbir ilgisi yok. Ayrıca, sabit kayıtların miktarı ile sınırlandırılırsınız veya önbellek tutarlılığı için en uygun olmayan bir doku tampon nesnesinden okumak zorunda kalırsınız (ve amaç, başlamak için optimize etmekti!).
Yüklemeyi zamanında önceden planladıysanız ve son 15 yıl içinde üretilen her donanımda çalışacaksa, basit, sade eski bir köşe arabelleği de hızlıdır (muhtemelen daha hızlıdır). Ayrıca, yazı tipinizdeki belirli sayıda karakterle veya oluşturulacak belirli sayıda karakterle sınırlı değildir.
Yazı tipinizde 256 karakterden fazla olmadığından eminseniz, doku dizileri, geometri gölgelendiricisindeki noktalardan dörtlü üretmeye benzer şekilde veri yolu bant genişliğini ortadan kaldırmaya değer olabilir. Bir dizi dokusu kullanılırken, tüm dörtlülerin doku koordinatları aynı, sabit s
ve t
koordinatlara sahiptir ve yalnızca koordinatta farklılık gösterir r
, bu da oluşturulacak karakter dizinine eşittir.
Ancak diğer tekniklerde olduğu gibi, beklenen kazanımlar önceki nesil donanımlarla uyumsuzluk pahasına marjinaldir.
Uzaklık dokuları oluşturmak için Jonathan Dummer'in kullanışlı bir aracı var: açıklama sayfası
Güncelleme: Programlanabilir Köşe Çekmede (D.Rákos, "OpenGL Insights", s. 239)
daha yakın zamana işaret edildiği gibi , en yeni nesil GPU'larda köşe verisinin programcıdan gölgelendiriciden çekilmesiyle ilişkili önemli bir ek gecikme veya ek yük yoktur, aynı şeyi standart sabit fonksiyon kullanarak yapmakla karşılaştırılır.
Ayrıca, en yeni nesil GPU'lar gittikçe daha makul büyüklükte genel amaçlı L2 önbelleklere sahiptir (örn. Nvidia Kepler'de 1536kiB), bu nedenle dörtlü köşeler için rasgele ofsetleri bir tampon dokudan çekerken tutarsız erişim sorunu beklenebilir. sorun.
Bu, sabit bir dokuyu (dörtlü boyutlar gibi) bir tampon dokusundan daha çekici bir şekilde çekme fikrini ortaya çıkarır. Varsayımsal bir uygulama böylece PCIe ve bellek aktarımlarının yanı sıra GPU belleğini aşağıdaki gibi bir yaklaşımla en aza indirebilir:
- Bu dizinden geçen bir tepe gölgelendiriciye tek girdi olarak yalnızca bir karakter dizini (görüntülenecek karakter başına bir tane) yükleyin
gl_VertexID
ve bunu geometri gölgelendiricisinde 4 noktaya yükseltin, hala karakter dizini ve köşe kimliği (bu "tepe noktası gölgeleyicisinde kullanılabilir hale getirilen gl_primitiveID") tek özellik olarak görünür ve bunu dönüşüm geri bildirimi yoluyla yakalar.
- Bu hızlı olacaktır, çünkü sadece iki çıkış özelliği (GS'de ana darboğaz) vardır ve aksi takdirde her iki aşamada da "no-op" a yakındır.
- Yazı tipindeki her karakter için dokulu dörtlü taban noktasına göre tepe konumlarını içeren bir arabellek dokusu bağlayın (bunlar temel olarak "yazı tipi metrikleridir"). Bu veriler, yalnızca sol alt tepe noktasının ofsetini saklayarak ve eksene hizalanmış kutunun genişliğini ve yüksekliğini kodlayarak dörtlü başına 4 sayıya kadar sıkıştırılabilir (yarım yüzer varsayarak, bu karakter başına 8 bayt sabit tampon olacaktır - tipik bir 256 karakterlik yazı tipi 2KB L1 önbelleğine tamamen sığabilir).
- Taban çizgisi için üniforma oluşturma
- Bir tampon dokusunu yatay ofsetlerle bağlayın. Bunlar olabilir belki de GPU hesaplanan, ancak kesinlikle sıralı bir işlemdir ve tüm önemsiz de (karakter aralığı düşünün) değil gibi, çok daha kolay ve CPU üzerinde bu tür şeyler için daha verimlidir edilebilir. Ayrıca, başka bir senkronizasyon noktası olan başka bir geri bildirim geçişine ihtiyaç duyar.
- Önceden oluşturulmuş verileri geri bildirim arabelleğinden işler, tepe gölgelendirici, temel noktanın yatay ofsetini ve tampon nesnelerinden köşe ilkelerinin ofsetlerini (ilkel id ve karakter dizinini kullanarak) çeker. Gönderilen köşelerin orijinal tepe kimliği artık "ilkel kimliğimiz" dir (GS'nin köşeleri dörtlü hale getirdiğini unutmayın).
Bu şekilde, ideal olan tekdüze bant genişliğini ideal olarak% 75 azaltabilir (amortismana tabi tutulabilir), ancak yalnızca tek bir satır oluşturabilir. Bir çizim çağrısında birden fazla çizgi oluşturabilmek istendiğinde, tekdüze (bant genişliği kazançlarını daha küçük hale getirmek) yerine tampon çizgisine taban çizgisi eklemek gerekir.
Bununla birlikte,% 75 azalma varsayıldığında bile - "makul" miktarda metin görüntülemek için köşe verileri yalnızca 50-100kiB civarında (pratikte sıfır olan)GPU veya PCIe veriyoluna) - Yine de eklenen karmaşıklığın ve geriye dönük uyumluluğu kaybetmenin gerçekten zahmete değdiğinden şüpheliyim. Sıfırı% 75 azaltmak hala sıfırdır. Kuşkusuz yukarıdaki yaklaşımı denemedim ve gerçekten nitelikli bir açıklama yapmak için daha fazla araştırmaya ihtiyaç duyulacaktı. Ama yine de, birisi gerçekten çarpıcı bir performans farkı gösteremedikçe (milyarlarca karakter değil, "normal" miktarda metin kullanarak!), Benim bakış açım, köşe verileri için basit, sade eski bir köşe arabelleğinin haklı olarak iyi olduğu anlamına geliyor. "son teknoloji çözümün" bir parçası olarak görülmelidir. Basit ve anlaşılır, işe yarıyor ve iyi çalışıyor.
Yukarıda " OpenGL Insights " a daha önce atıfta bulunarak , Stefan Gustavson tarafından "Mesafe Alanlarına Göre 2D Şekil Oluşturma" bölümüne de dikkat çekerek mesafe alanı oluşturmayı ayrıntılı olarak açıklamaya değer.
Güncelleme 2016:
Bu arada, aşırı büyütmelerde rahatsız edici olan köşe yuvarlama eserlerini kaldırmayı amaçlayan birkaç ek teknik var.
Bir yaklaşım, yalnızca mesafe alanları yerine sözde mesafe alanları kullanır (fark, mesafenin gerçek çerçeveye değil, dış çizgiye veya kenarın üzerine çıkıntı yapan hayali bir çizgiye olan en kısa mesafedir ). Bu biraz daha iyidir ve aynı miktarda doku belleği kullanarak aynı hızda (özdeş gölgelendirici) çalışır.
Başka bir yaklaşım, üç medyan üçünü üç kanallı doku detaylarında ve github'da bulunan uygulamada kullanır . Bu, konuyu ele almak için daha önce kullanılan ve / veya hack'lerde bir gelişme olmayı amaçlamaktadır. Kaliteli, hafif, neredeyse farkedilmez, daha yavaş, ancak üç kat daha fazla doku belleği kullanır. Ayrıca, ekstra efektlerin (örn. Parlaklık) düzeltilmesi daha zordur.
Son olarak, karakterleri oluşturan gerçek bezier eğrilerini saklamak ve bir parça gölgelendiricide değerlendirmek , biraz daha düşük performansla (ancak bir sorun olduğu kadar değil) ve en yüksek büyütmelerde bile çarpıcı sonuçlar ile pratik hale geldi .
WebGL demosu burada gerçek zamanlı olarak bu teknikle büyük bir PDF oluşturma .