Skip to content

Üretilen meshlerdeki delikler nereden geliyor ​

Cinevva CTO'su ve Kurucu Ortağı Oleg Sidorkin tarafından

Düzeltmeden önce ve sonra üretilmiş bir kuşun kanat kökü: solda parlak yeşil yarıkların göründüğü gri bir çıkıntı, sağda kanat ile gövde arasında temiz bir kıvrım
Aynı görüntü, aynı üretici, aynı ayarlar. Soldaki bu haftaya kadar sunduğumuz sonuç. Sağdaki ise artık sunduğumuz sonuç.

TRELLIS.2 ile bir kuş ürettim, rigledim ve animasyon oynatıldığı anda iki kanadın altında da delikler belirdi. Gövdenin içinden karşı tarafı doğrudan görebildiğiniz parlak yarıklar vardı. Önce rig aracı suçlandı; gerçekten de kendine özgü bir sorunu vardı, ancak delikler herhangi bir kemik meshe dokunmadan önce zaten oradaydı. Bu yazı, ardından yürüttüğümüz araştırmayı anlatıyor: deliklerin aslında ne olduğunu, onları düzeltmeyen dokuz yöntemi, bunların neden işe yaramadığını ve işe yarayan tek yöntemi. Çıkmaz yolları bilerek dâhil ediyorum. Bunların çoğu ilk akla gelen yöntemlerdi ve her biri, sonunda bulduğumuz çözümün dayandığı bir şeyi bize öğretti.

Birinci adım: deliğin ne olduğu konusunda anlaşmak ​

Mesh denetleyicimiz sıfır sınır kenarı bildirdi ve ışın paritesi testi yüzeyin kapalı olduğunu söyledi. Bu yüzden ekibe meshin temiz olduğunu söyledim. Değildi ve yarıkları kırmızıyla işaretleyen kişi itiraz etmekte haklıydı. Bir mesh kapalı olup yine de tüneller içerebilir. Bunları yakalayan tek ölçü, kabuk başına kulp sayısını veren Euler karakteristiğidir: V eksi E artı F. Kuşta bunlardan 69 tane vardı. Dışa aktarımdaki her duvar çift katmanlıydı; dolayısıyla dış duvardaki bir yarığın arkasındaki boşluğa bağlanması bir açıklık değil, kulptur ve açık kenar arayan hiçbir yöntem bunu göremez.

İkinci ve daha utanç verici ders: Delikler karanlık olur diye bir süre karanlık pikselleri inceleyerek delik aradım; sonunda biri önce resme bakmamı söyledi. Delikler parlaktı. Gri bir kıvrımın arkasından görünen, karşı duvardaki yeşil dokunun ince parçalarıydı. Doğru şeye yöneltmediğiniz bir algoritma size hiçbir şey söylemez ve onu yöneltmenin en ucuz yolu bakmaktır.

İkinci adım: onları oluşturan aşamayı bulmak ​

TRELLIS.2 bir meshi üç adımda oluşturur. Bir kod çözücü, 1024 küp çözünürlükte ham bir yüzey üretir. Dar bantlı bir dual contouring geçişi yüzeyi yeniden meshler. Bir sadeleştirici yüz sayısını yüz bine indirir ve doku bake edilir. Her adımın ardından geometriyi dışa aktarıp her seferinde aynı ışın demetini kanat kökünden geçirdik.

Sorun ham yüzeyde başlıyor. Bu yüzey açık yapraklardan oluşan bir yığın: Çoğu eksik tek bir quaddan oluşan 266.242 sınır döngüsü ve 65.371 manifold dışı kenar. Kanat kökünde test ışınlarının üçte biri doğrudan karşıya geçti. Ardından çalışan delik doldurma işlemi neredeyse hiçbir şeyi kapatmıyor; beş milyon yüzden yalnızca 144'ünü. Yeniden meshleme aracı, zorunlu olarak işaretsiz bir mesafe alanı üzerinde çalışıyor. Kullanabileceği bir iç veya dış bilgisi olmadığı için her yaprağın çevresine ince, ofsetli bir kabuk sarıyor. Bu nedenle her duvar, aralarında yaklaşık dört voksel olacak şekilde çift katmanlı hâle geliyor ve her gözenekli şerit bu şekilde içinde yarık bulunan bir kıvrıma dönüşüyor. Sadeleştirme daha sonra sorunu kötüleştiriyor ve bunu rastgele yapıyor: Aynı ham mesh iki kez sadeleştirildiğinde 69 ve 107 tünel oluştu.

Açık kenar yoğunluğunu gösteren ısı haritasıyla kuş: boyun halkası, iki kanat kökü, kalçalar ve kuyruk tüylerinin uçları parlıyor; gövde ve baş temiz
Ham çıkarımdaki açık kenar yoğunluğu. Yalnızca parçaların birleştiği yerler parlıyor: boyun halkası, kanat kökleri, kalçalar ve kuyruk uçları. Gövde ve baş temiz.

Bu harita ilk gerçek ipucuydu. Gözeneklilik rastgele değil. Parçalar arasındaki her birleşim noktasında bulunuyor, başka hiçbir yerde bulunmuyor.

İşe yaramayan yöntemler ​

Bunları kabaca ne kadar bariz göründüklerine göre sırayla denedik.

denemesonuç
1024 yerine 1536 çözünürlükbeş test modelinin üçünde daha kötü. Daha yüksek çözünürlük daha fazla ince teması yakalıyor ve bunların her biri yeni bir birleşim oluşturuyor
yerleşik temizleme zincirimanifold dışı kenarları azaltmak yerine artırdı
MeshLib ile her küçük deliği doldurmak266 bin döngü dolduruldu, kanat kökü değişmedi. Oradaki yüzey hiç üretilmemişti, dolayısıyla doldurulacak bir döngü yoktu
winding number ile işaretli yeniden meshlememeshi binlerce kabuğa ayırıyor. Ham çıktının işaret atanabilecek bir iç bölgesi yok
2 ve 3 voksellik daha geniş contouring bandıtoplamda daha az tünel, ancak yarık daralmak yerine genişliyor. Küçük tüneller birleşip büyük tünellere dönüşüyor
voksel yapısına morfolojik kapatma uygulamakkabuğu katılaştırıyor; kod çözücü daha sonra içerideki her vokselin içinde yüzey üretiyor, yüz sayısı 4 katına çıkıyor, 969 tünel oluşuyor
nihai meshi genel olarak yeniden vokselle meshlemekgenus 0 ve yarık kapalı. Ayrıca her tüy kenarı yumuşadı. Görülür görülmez, haklı olarak reddedildi
kod çözücünün kesişim eşiğini bias etmekaçık kenarlar 65 binden 58 bine düştü. Gürültü
eksik komşu vokselleri tamamlamakkuşun tamamında 560 örnek. Gürültü
Dört sütun: orijinal kuş ve giderek artan yarıçaplarla yeniden voksellenerek meshlenmiş üç sürüm; kanat kökü, on kat yakınlaştırma, kesit dilimi, kuşun tamamı ve alttan görünüm
Genel kapatma. Üçüncü sütun yarığı kapatıp ayak parmaklarını ayrı tutuyor, ancak kuştaki her kıvrımı da yuvarlatıyor. Geometride "bulanıklık" böyle görünür.

Genel kapatma üzerinde biraz durmaya değer, çünkü bir modelleme sanatçısının ilk başvuracağı yöntem budur: Voksel yeniden meshlemeyi aralıktan biraz daha büyük bir boyutta çalıştırmak. Topolojik olarak işe yarıyor. Ancak model hakkında da yalan söylüyor. Üretici keskin tüy kenarları oluşturmuştu; bizse kapalı bir kanat kökü uğruna bunlardan vazgeçmiş olacaktık. Dokuz denemeden ikisi tünel sayısını azalttı ve ikisi de herhangi biri yalnızca sayıya değil kuşa baktığı anda reddedildi.

Kodu okumak ​

Bu noktada yapılabilecek tek dürüst şey, kod çözücüyü bir kutu gibi ele almayı bırakıp çıktısının nasıl meshe dönüştürüldüğünü okumaktı. TRELLIS.2, O-Voxel adlı bir temsil kullanıyor ve çıkarım kodu kısa. Her aktif voksel bir dual vertex ve köşesinden çıkan her grid kenarı için bir tane olmak üzere üç logit barındırıyor; her biri "yüzey bu kenarı kesiyor" anlamına geliyor. Sıfırın üzerindeki bir logit, o kenarın çevresindeki dört vokseli bağlayan bir quad üretiyor. Dört vokselden herhangi biri eksikse quad hiçbir uyarı vermeden atılıyor. Hepsi bu. Modelin hiçbir yerinde işaret alanı, doluluk ya da iç ve dış bilgisi yok.

Kod çözücüyü, eşik uygulanmadan önce aynı kuş üzerindeki bu logitleri dökecek şekilde yamaladık ve saydık.

Eksik komşular: 2,7 milyon vokselin 560'ı. Sıfıra yakın logitler: 8 milyonun 8.600'ü. Sorun bunların hiçbiri değil. Asıl sorun, her grid yüzünün çevresindeki dört kenara baktığınızda ortaya çıkıyor. Kapalı bir yüzey, bir yüzün sınırını çift sayıda keser. 126.542 yüzde, yani yüzlerin %2,3'ünde dört bayrak birbiriyle uyuşmuyor ve her tek sayılı yüz tanım gereği açık ya da manifold dışı bir kenar oluşturuyor. Üstelik güvenle uyuşmuyorlar. Tek kesişimli bir yüzdeki yalnız bayrağın logiti +10 iken komşuları -4'te duruyor. Bir bayrağı tersine çevirip pariteyi geri getirmenin medyan maliyeti 2,3 logit. Bu, eşikteki küçük bir sapma değil. Model, kapanması mümkün olmayan bir yüzeyden emin.

Koyu arka plan üzerinde üç sütun: dışa aktarılmış kuş, kod çözücünün ham çıktısı ve işareti onarılmış bir sürüm. On ve otuz kat yakınlaştırmada kanat birleşimi her iki ham sürümde de parçalanmış, testere dişli bir şerit
Kod çözücünün kanat kökündeki ham çıktısı; koyu alanlar içinden karşı tarafın görülebildiği yerleri gösteriyor. Birleşim yerinde eksik quadlar yok. Orası bir tarak.

Ardından, sabit kameramızın bütün hafta baktığı yüzey noktasında şeridin kendisini ölçtük. Bu noktanın on iki voksel çevresinde, tek bir düz yaprağın gerektireceğinden 2,1 kat fazla aktif voksel var. Karşılaştırma için göğüste bu oran 1,2. Kanadın altı ile gövde, tek bir voksel katmanının içinde ilerleyen iki ayrı yüzey. Temsil, voksel başına tek bir vertex barındırdığı için ikisini birden tutamıyor. Eğitim sırasında böyle bir vokselin ground truth'u, her iki yüzeyin "herhangi bir kesişim" bayraklarıyla birlikte alınan en küçük kareler ortalaması oluyor; bu da kendi içinde tutarsız. Dolayısıyla model orada bir tarak üretmeyi sadakatle öğrenmiş. Yeniden meshleme aracı tarağı bir plaka içine sarıyor ve plakada tüneller oluşuyor.

Şeridin genişliği geometriden çıkarılabilir: kabaca bir vokselin temas açısının tanjantına bölünmesi. Doksan derecede birleşen iki yüzey, bir voksellik bir kıvrım oluşturuyor ve sorun çıkarmıyor. Gövdeye düz biçimde yaslanan bir kanat, tüy üstüne tüy, zemine basan ayak parmakları; bunların tümü on ya da on beş voksel genişliğinde bir şerit oluşturuyor. Gözeneklilik haritasının açıklaması bu.

Bayrakları en iyi açıklayan köşe başına bir iç/dış işareti çıkarıp ardından bayrakları yeniden türeten prensipli onarımı da denedim. İşe yaraması mümkün değil. İşaret alanı yalnızca kod çözücünün ürettiği bir voksellik kabukta mevcut ve bu kabuğun dışına yapılan her uzatma kontrolden çıkıyor. On iki tur sonunda voksel sayısı işe yaramaz verilerle ikiye katlandı.

Bir modelleme sanatçısının yapacağı şey ​

Bir modelleme sanatçısı iki yüzeyi asla aralarında kıl payı mesafe kalacak şekilde bırakmaz. Kanadı gövdeyle birleştirir ve arada bir kıvrım oluşmasına izin verir. Genel kapatma bunu her yerde yapıyor; sorun da bu. Öyleyse yalnızca iki yüzeyin bulunduğu yerde yapın.

Dedektörün arkasındaki fikir tek satırda anlatılabilir. Her vokselin dört voksel içindeki aktif komşularını sayın. Tek bir yüzeyde bu sayı her yerde aynıdır ve medyana eşittir. İki yüzey aynı katmanı paylaştığında sayı yaklaşık iki katına çıkar. Medyanın 1,5 katının üzerindeki her şeyi işaretleyin, işaretli kümeyi bir voksel büyütün ve her noktaya birim küp yerleştirin. Yüzeylerin arasındaki boşluk katılaşır, contouring geçişi tek bir duvar görür ve modeldeki başka hiçbir şeye dokunulmaz.

Kanat kökü çevresindeki bir kırpmanın üç farklı contouring sonucu: olduğu gibi, yarıçap üçte iki yüzeyli bölge doldurulmuş ve yarıçap dörtte doldurulmuş. Kırmızı noktalar dikiş boyunca doldurulan vokselleri gösteriyor. Testere dişli dikiş pürüzsüz bir kıvrıma dönüşüyor
Pipeline'a dokunmadan önce bir kırpma üzerinde yapılan kavram kanıtı. Kırmızı, doldurulan vokselleri gösteriyor. Testere dişli dikiş bir kıvrıma dönüşüyor ve çevresindeki tüyler hareket etmiyor.

Önce MeshLib'i GPU contouring işleminin yerine kullanarak bir kırpma üzerinde test ettik. Elli üç kabuk ve on dokuz kulp, iki kabuk ve beş kulba dönüştü. Ardından bunu kod çözücü ile dışa aktarım arasındaki gerçek pipeline'a yerleştirip aynı kuşu gerçek yeniden meshleme aracından ve gerçek doku bake işleminden geçirdik.

Dört sütun; önce dokulu, sonra düz geometri, ardından kesit: orijinal, aynı kod çözücü çıktısının olduğu gibi dışa aktarılmış hâli ve yarıçap üç ile dörtte iki yüzey dolgusu. Son ikisinde gri çıkıntı ve yeşil yarıklar kayboluyor
Gerçek pipeline. Birinci ve ikinci sütunlar, rastgele sadeleştirme uygulanmış ve uygulanmamış aynı kod çözücü çıktısıdır. Üçüncü ve dördüncü sütunlarda dolgu var.
tünellermanifold dışı kenarlarkanat kökü çıkıntısısırttaki delik
olduğu gibi79,5318varvar
dolgu, yarıçap 384,597yokyok
dolgu, yarıçap 47238yokyok

Çıkıntı yok oldu. Kuşun sırtındaki, aynı birleşimin arkadan görülen hâlinde bulunan ve peşinde bile olmadığım ikinci bir delik de yok oldu. Tüyler ayrı kalıyor, ayak parmakları ayrı kalıyor ve küpler, attribute volume'un zaten veri barındırdığı kabuğun içinde bulunduğu için doku normal biçimde bake ediliyor. Dört dakikalık bir işe altı saniye ekliyor. Artık varsayılan olarak açık ve yarıçapı dört.

Dört sütunda kuşun önden, arkadan, dokulu olarak alttan ve düz geometri olarak alttan görünümü: orijinal, olduğu gibi, dolgu yarıçap üç, dolgu yarıçap dört
Kuşun tamamı. Birinci ve ikinci sütunlarda sırtta görülen beyaz delik, aynı birleşimin arkadan görünümü. Üreticinin doğru yaptığı her şey üçüncü ve dördüncü sütunlarda hâlâ yerinde.

Bunun düzeltmediği şeyler ve bize anlattıkları ​

Tünel sayısı neredeyse hiç değişmedi ve nedenini açıkça belirtmek istiyorum. Kalan tüneller, ince bir parçanın sona erdiği ve çift katmanlı duvarın kapanarak sıkıştığı tüy ve ayak parmağı uçlarında. Küçükler, görünmüyorlar ve farklı bir mekanizmadan kaynaklanıyorlar. Dolgu, görünür deliklerin bulunduğu parça temaslarını hedefliyor. Asıl düzeltmenin üretimin önceki aşamalarında yapılması gerekiyor. Kenar başına bayraklar yerine köşe başına işaretleri tahmin eden bir kod çözücü, yapısı gereği parite açısından tutarlı olurdu; bu modelin önceki nesli de böyle çalışıyordu ve bu yüzden ürettiği mesh'ler su geçirmezdi. Bu, çıkarım sırasında yamayabileceğimiz bir şey değil, eğitimde yapılması gereken bir değişiklik. O zamana kadar şerit formülünden iki pratik sonuç çıkarabiliriz. Bir karakter üretiyorsanız, uzuvların gövdeden ayrı durduğu bir poz, uzuvların gövdeye yaslandığı bir poza kıyasla daha temiz bir mesh oluşturur. Böyle bir üreticinin üzerine bir sistem geliştiriyorsanız da bir sayıya güvenmeden önce mesh'lerinizi Euler karakteristiğiyle ölçün ve sonucu kendi gözlerinizle inceleyin. Sayı temiz olduğunu söylüyordu. İki kez yanıldı.

Araçlarla donatılmış kod çözücü, aşama dökümleri, parite analizi ve dolgu artık işlem hattımızın parçası. Böylece delikli sonuçlar üreten bir sonraki modele aynı işlemleri bir hafta yerine dakikalar içinde uygulayabileceğiz.