GLSL

2011-07-03 17 views
6

'da birden fazla dokuyu harmanlamak Bu uzun ama söz veriyorum. :)GLSL

jMonkeyEngine kullanarak başka bir uygulamanın tekstüre görünümünü taklit etmeye çalışıyorum. Ben bir köşeler listesi ve yüzler (üçgenler) bir "peyzaj ağı" oluşturan yaklaşık 7-15 farklı doku ile dokulu olmalıdır ("peyzaj" arazisine bağlı olarak). Her üçgenin, ilgili üçgenden hangisinin büyük ölçüde oluşması gerektiğini gösteren bir doku kodu vardır. Ve elbette, dokular her yüz arasında düzgün bir şekilde karıştırılmalıdır.

Bu yüzden buna izin veren bir strateji geliştirmeye çalışıyorum (önceden oluşturulmuş alfa map png dosyalarını KULLANMAYIN, doku alfalarının çalışma zamanında yapılması gerekir). Şu anda, her bir komşunun her bir köşesinde (köşe gölgelendiricisinde) her bir yaprağın "mukavemetini" hesaplarsam, tüm komşu yüzlerin arazi tiplerini hesaba katıp (bunu nasıl yapacağınızdan emin değilim) - Bir pikselin bir tepe noktasından ne kadar uzak olduğuna bağlı olarak alfa değerlerini ayarlamak için kullanılır. Oluşturulan "alfa haritası", parça gölgelendirici tarafından piksel başına her dokuyu harmanlamak için kullanılacaktır.

Bu mümkün mü, yoksa tamamen farklı bir stratejiye bakmalı mıyım? Ben taklit çalışıyorum uygulama için Shader kod var (ama HLSL ve ben GLSL kullanıyorum), ancak başka bir yerde bu harmanlama adımı yapıyoruz gibi görünüyor: Ben

sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; }; 

Bu HLSL "MeshTextureSampler" ın ne olduğundan emin değil, ancak bu uygulama tüm dokular gerektiği gibi önceden harmanlanmış gibi görünebilir ve yüz/arazi kodu verilerine dayanarak tüm ağ için tek bir doku oluşturdu. Hiç bildiğim kadarıyla söyleyebilirim doku harmanlanmış hiçbir tür hangi beni götürür -

etc sadece gölgeler, aydınlatma, olduğunu
float4 tex_col = tex2D(MeshTextureSampler, In.Tex0); 

sonra: pixel/parça gölgelendirici onlar gerçekten ne yorgunluğu şudur Bu doku karıştırma işleminin önceden CPU üzerinde yapıldığına inanmak gerekirse, sanırım. Herhangi bir öneri hoşgeldiniz. Ben doğru anlamak

+0

+1. –

cevap

3

, burada benim ilk atış ne olacağını ise:

Senin sorunun az ya da çok, nasıl köşeler üzerinde senin başına yüze değerini dağıtmak için vardır. Bu aslında bir örgü üzerindeki normal jenerasyona benzer: ilk önce her üçgen için bir normal oluşturacaksınız ve daha sonra bunları her bir köşe için hesaplayacaksınız. Google "normal nesil" ve oraya varırsınız, ama işte burada. Her bitişik üçgeni için, bir tartım faktörü (genellikle köşeyi veya köşenin üçgenin yüzey alanını veya bir birleşimini kullanan köşenin açısını) bulun ve sonra değeri (normal veya kuvvetli olmanız) çarpın. Tartım faktörü ile toplam sonuca. Normalleştir ve bitirdin.

Bu durumda, vertex shader'ınıza gönderebileceğiniz doku "güçlü" leriniz var. Modern çözüm, chars değerlerini biraz daha güzel transferler vermek için birazcık kullanmanızdan sonra, chars kullanmak ve piksel gölgesinde bir doku dizisini örneklemek olacaktır.

Yani, doğru sorun olsun:

Preprocess:

forearch vertex in mesh 
    vertexvalue = 0 
    normalization = 0 
    foreach adjacent triangle of vertex 
     angle = calculateAngleBetween3Vertices(vertex,triangle.someothervertex,triangle.theotherothervertex) 
     vertexvalue += triangle.value * angle 
     normalization += angle 
    vertexvalue/=normalization 

Rendering zaman: fragmentshader için Tepe noktalarının değer (ler) ve bunu

boru Parça gölgelendiricisi:

basecolour = 0; 
foreach value  
    basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value) 
    //this is simple, but we could do better once we have this working 

Veya alternatif olarak iyi bir görünüm elde edebilirsiniz. geometrinizde. Büyük üçgenler ve minik olanlar birleşiminiz varsa, eşit olmayan bir veri dağılımına sahip olacaksınız ve verileriniz her köşe için olduğundan, daha fazla geometrinin olduğu yerde daha fazla ayrıntıya sahip olacaksınız. Bu durumda, muhtemelen herkesin yaptıklarını yapmak ve karışım haritalarını kullanarak dokusallığınızı geometrinizden ayırmak isteyeceksiniz. Bunlar düşük çözünürlükte olabilir ve bellek tüketiminizi veya shader yürütme sürenizi o kadar artırmamalı. İlk cümleniniz için

+0

Takılıyorum, genellikle "Her bitişik üçgenin için, bir tartım faktörü bul ..." - bunu nerede yapardım ve gölgelendiricilerden nasıl erişilebilir? Hala bunu görselleştirmek için zor bir zaman geçiriyorum. – Manius

+0

Yapmıyorsunuz. Bu sadece ön işlem aşamasıdır (değerleriniz oluşturma zamanında statiktir, değil mi?). Her üçgen için 1'lik bir tartım faktörü çalışmalıdır, bu kaliteli bir şeydir. Aksi halde onu köşe çizgisine dokunan üçgen köşesinin açısı olarak alabilirdiniz. Daha sonra, tepe noktasındaki değer FOREACHN değeri + = angle_of_triangle * değer_at_triange –

+0

olur. Ben sadece olası bir çözümü düşündüm, ama bunu tekrar okudum sanırım bunu temel olarak önerilenle aynı şeydir (şekil). Her köşe için 'ağırlıklı' alfa değerlerini (her doku için) geçmeyi deneyeceğim ve fragmandakileri doku alfaları olarak kullanacağım. (Demek istediğin bu mu?) Bunu jMonkeyEngine ile nasıl yapacağımı belirleyen zor bir zaman geçirdim ama umarım bu verileri vertex özniteliklerini "texCoordX" köşe tipi tampon türleri olarak iletebilirim. (Bu biraz jME özel şeyler var.) Bu çalışırsa, sadece önermek gibi ağırlıkları hesaplamak için alan/açı kullanarak hile yapabilirsiniz ... – Manius