2013-08-03 29 views
17

GL_TRIANGLES ve düz bir renk, 2d simülasyonu kullanarak, basit bir xy düzleminde düzlük oluşturan bazı basit çokgenler (20'den az köşe noktası) var.Bir parça gölgelendiriciye sahip 2d çokgen üzerinde kenarlık çizme

Bu çokgenlere değişken kalınlıkta bir kenarlık ve farklı bir renk eklemek istiyorum. Çalıştığım aynı köşeleri ve glLineWidth/GL_LINE_LOOP kullanarak uygulanan bir şey var, ama başka bir render geçişi ve tüm verteks dönüşümleri tekrarlar.

Bunu gl_FragCoord ve vertex verileri ve/veya doku koordinatlarını kullanarak parça gölgelendiricisinde yapabilmem gerektiğini düşünüyorum, fakat emin değilim ve benim saf denemelerim açıkça yanlış.

Aşağıdaki gibi bir şey hayal ediyorum.

uniform vec2 scale; // viewport h/w 
uniform float line_width; 
uniform vec4 fill_color; 
uniform vec4 border_color; 

varying vec4 vertex; // in world coords 

void main() 
{ 
    if (distance_from_edge(gl_FragCoord, vertex, scale) < line_width) 
    { 
     // we're close to the edge the polygon, so we're the border. 
     gl_FragColor = border_color; 
    } 
    else 
    { 
     gl_FragColor = fill_color; 
    } 
} 

ben anlamaya çalışıyorum parçası distance_from_edge fonksiyonudur - nasıl hesaplanabilir? Gl_FragCoord'un yanlış yaklaşımı kullanıyor mu - bir çeşit doku eşlemesi kullanmalı mıyım?

Bir deneme olarak, köşeyi pixel alanına ölçekle dönüştürmeyi denedim ve ardından pikselle gl_FragCoord arasındaki mesafeyi hesapladım, ancak bu gerçekten anlamadığım garip sonuçlar verdi. Artı vertex değil kenar arasındaki mesafeye ihtiyacım var, ama nasıl elde edeceğimi bilmiyorum.

Herhangi bir fikrin var mı?

DÜZENLEME: kenar köşeler olarak işaretlenmiş 3 köşe renklerde bir üçgen var varsayarsak

ve ortasında bir tepe (yani 3 üçgenler halinde olan render kenardan olarak değil işaretli: Nicol yanıtına dayalı, sorum olur toplam), o zaman belirli bir kalınlık sınırını çizmek için parça gölgelendiricisinde nasıl enterpolasyon yapabilirim? Kenar bayrağını parça gölgelendiriciye ve istenen çizgi kalınlığına geçirdiğimi ve kenar ile kenar köşeleri arasındaki mesafeyi belirlemek için bazı enterpolasyon hesaplamaları yaptığımı ve rengin uygun şekilde kenar/dolgu olarak eşiğini aldığımı farz ediyorum. ?

+1

'gl_FragCoord' kitlesel olacak size yardımcı olmuyor. Bu sadece parçanın ekranda nerede olduğunu söyler; parçanın üçgene göre nerede olduğu hakkında hiçbir şey söylemez. Köşe pozisyonu benzer şekilde kitlesel olarak yararsızdır. Bir köşe noktası olsun ya da olmasın, köşeleri değerlere koyan ve değeri enterpoze eden vertex shader/kullanıcı tarafından sağlanan verilerin yardımına ihtiyacınız olacak. Bu, tek bir üçgenin kenarını algılayamayacağınız anlamına gelir; Üçgeni birkaç üçgen şeklinde bölmeniz gerekir, böylece iç köşeler ve kenar köşeleri ayırt edilebilir. –

+0

Teşekkürler, bir şeyleri kaçırdığımı sanmıştım. Öyleyse, kenar köşesi olarak işaretlenmiş 3 köşeli bir üçgene sahipse ve ortadaki bir tanesi (bu yüzden 4 üçgenle işlenmiş) değilse, o zaman kenarlık için belirli bir çizgi genişliğine nasıl enterpolasyon yaparım? – bloodearnest

cevap

23

İhtiyacınız olan tek şey, üçgensle uğraştığınız için, üç yüzlü koordinatlardır. Üçgenin her bir köşesini bir kimlik atayın ve daha sonra parçanın gölgelendiricinizdeki her bir köşeden göreceli mesafeyi belirlemek için donanımın köşe ve parça aşamaları arasındaki dahili enterpolasyonunu kullanın.

Her köşe için eş merkezli koordinatları zıt kenardan uzaklık olarak düşünebilirsiniz. Aşağıdaki şemada, P0'nın köşe kenarı e1'dir ve mesafesi hl ile temsil edilir; onun eş merkezli koordinatı <0.0, h1, 0.0>'dur. GPU'lar rasterleştirme sırasında fragmanlar oluşturulduğunda üçgenler için tepe özniteliklerini enterpolasyon için dahili olarak bu koordinat boşluğunu kullanabilir, üçgen içindeki lokasyona göre ağırlık-verim özelliklerinin ağırlıklandırılmasını çabuklaştırır. Bunun için arama daha şanslı olabilir böylece

Diagram illustrating the calculation of distance from each edge

Aşağıda bunun nasıl izah iki öğreticiler, bu genellikle bir tel kafes bindirme oluşturma için kullanılır. Amacınız için, bu etkili bir şekilde tel kafes işlemenin bir uzmanlığı olduğundan (dış poligon kenarlarına ait olmayan satırları atmak istediğinizde), kenar köşelerini tanımlamanız ve ek işlem yapmanız gerekir.

Örneğin, bir köşe bir dış kenarın parçası değilse, o zaman < 1,100,0> ve bağlanan köşe < 0,100,1> gibi bir eşşekrelik koordinatını atayacaksınız ve iç kenar göz ardı edilmemelidir (aşağıdaki şemada görüldüğü gibi < 0,1,0> olarak belirlenen köşe noktasının karşısındaki bir kenar olduğu varsayılmaktadır). Buradaki fikir, bu kenar boyunca hiçbir noktanın 0.0'a yakın herhangi bir yere (veya sınırın bir parçası olarak bir parçayı gölgelemek için kullandığınız eşiğinize ne olursa olsun) eğilmemesi, böylece üçgenin merkezinden merkezden çok uzak kalmasıdır. ters köşe bunu çözecektir. Geometri Gölgelendiricilere olmadan

Diagram showing how to exclude interior edges

(OpenGL ES dostu):

Burada barycentric koordinatlarını tutmak için köşe verileri değiştirmek mümkün olup olmadığını, bunun nasıl açıklayan bir bağlantı. Daha yüksek depolama ve ön işleme gereksinimlerine sahiptir (özellikle, her bir üçgenin her biri farklı bir giriş ikili merkezli koordinat içeren üç köşeden oluşması gerektiğinden, bitişik kenarlar arasındaki köşe paylaşımı artık mümkün olmayabilir. Bu yüzden geometri gölgelendiricileri bir istenen çözüm). Ancak, geometri gölgelendiricileri gerektiren daha genel çözümlerden çok daha fazla OpenGL ES sınıfı donanım üzerinde çalışacak.

http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/ Geometri Gölgelendiricilere ile

( değil OpenGL ES dostu): Alternatif

, sen de görüldüğü gibi barycentric hale zamanında her üçgenin koordinatlarını hesaplamak için geometri shader kullanabilirsiniz bu eğitim. Şanslar OpenGL ES'de, geometri gölgelendiricilerine erişiminiz olmayacak, bu muhtemelen göz ardı edilebilir.

http://strattonbrazil.blogspot.com/2011/09/single-pass-wireframe-rendering_10.html http://strattonbrazil.blogspot.com/2011/09/single-pass-wireframe-rendering_11.html

bu çözüm için teorik temeli burada bulabilirsiniz (Internet Archive Wayback Machine izniyle):

http://web.archive.org/web/ */http://cgg-journal.com/2008-2/06/index.html

+0

Teşekkürler, bu bana doğru yolda var. Geometri olmayan gölgelendirici wireframing uyguladı ve güzel çalışıyor. Şimdi sadece ek çevre olmayan vertex'leri eklemem ve uygun şekilde işaretlemem gerekiyor. Zaten kendi yolumda bu rotayı kısmen de olsa aşağı inmiştim, ama nasıl olsa da, 1 koordinatla değil, 3. – bloodearnest

+3

Teorik temel linki aşağıdadır, burada [alternatif bir link (web arşivi)] (https: //web.archive). org/web/20130607004602/http: //cgg-journal.com/2008-2/06/index.html). Aynı adamlardan başka bir makale: [Gizli Hat Çıkarma ile Antialiased Tel Çerçeve Çizimi için İki Yöntem] (http: //orbit.dtu.dk/fedora/objects/orbit: 55459/datastreams/file_3735323/content) – fedab

+0

Ne yazık ki, bu teknik sınırların köşelere yaklaştığı eserler doğurmaktadır. İç üçgen kenarları, sınırın kısımlarını "kesebilir": http://imgur.com/Btl6h2Y. – John

İlgili konular