İmzalı Mesafe Alanları Yazı Tipleriyle Keskin Köşeler


49

İmzalı Mesafe Alanları (SDF'ler), bu makalede Valve tarafından çözünürlükte bağımsız font oluşturmayı sağlamak için hızlı bir çözüm olarak sunuldu .

Valve çözümünü zaten çalıştırıyorum ancak köşelerdeki keskinliği korumak istiyorum. Valve, yönteminin, taban bir ile ANDed ikinci bir doku kanalı kullanarak keskin köşeler elde edebileceğini belirtir, ancak bu ikinci kanalın nasıl oluşturulacağını açıklayamaz.

Aslında bu yazının dışında kalan birçok uygulama detayı var.

Herhangi birinizin SDF'lerin yazı tipini keskin köşelerle oluşturmasını sağlayacak bir yönü gösterip göstermediğini bilmek isterim.


Aslına bakarsan, Adam zaten shadertoy üzerine kaynak kodu yayınladı. İşte link: shadertoy.com/view/ltXSDB
Felipe Lira

Beni heyecanlandırdın. Bezier malzemelerini gölgelendirme üzerine koydular, ancak dokudaki uzaklık alanını değil!
Alan Wolfe

@AlanWolfe Ben sadece prosedürel olarak belirlenmiş bezier eğrileri için yaptığını düşünüyorum. Bunu bir ttf render lib'sine entegre etmek için gerekli çabanın olduğundan emin değilim. Biraz zamanım olduğunda bir göz atacağım.
Felipe Lira

Görünüşe göre, bir dokudan mesafeleri saklamak ve almak konusunda bir miktar sihirli sos var. Oyunda bir doku olmadan, shadertoy örnekleri denklemin bu bölümünü eksik.
Alan Wolfe

Partiye biraz geç kaldık ama
reddit'in

Yanıtlar:


7

Adam Simmons bu alanda bazı ilginç çalışmalar yaptı. Özellikle nasıl başardığını bilmiyorum, ama SDF tabanlı vektör çizimleri Vana dışında pratikte gördüğüm en keskin şey. http://twitter.com/adamjsimmons/status/611677036545863680


Tabii ki tüm ayrıntılara sahip değilim, ama bana göre bu kişi, 2006’da Qin, McCool ve Kaplan’ın makalesinde gösterilmiş olan normal bir yer yerine sadece sahte bir mesafe alanı kullandı. ” Vana kağıdında da atıfta bulunulan "Gerçek zamanlı doku eşlemeli vektör glifleri". Yalnızca ana hatların miterlerini etkiler ve köşelerin görünümünü iyileştirmek için hiçbir şey yapmaz. Keskin görünmesinin sebebinin pratik olmayan geniş mesafeli alan dokuları kullanmasından şüpheleniyorum. Yine de yanlış olabilirim.
Detheroc

69

EDIT: Lütfen diğer cevabımı somut bir çözümle görün.

Bu kesin problemi bir yıl önce yüksek lisans tezim için çözdüm. Valf kağıdında, bunu yapabilmek için VE tek bir dışbükey köşeye sahip olduğunuz sürece çalışan iki mesafe alanı elde edebileceğinizi gösterirler. İçbükey köşeler için ayrıca VEYA işlemine ihtiyacınız vardır. Bu adam aslında dört doku kanalı kullanarak iki operasyon arasında geçiş yapmak için bazı karanlık bir sistem geliştirdi.

Ancak, duruma bağlı olarak hem VEYA VEYA hem de kolaylaştırabilen çok daha basit bir işlem var ve bu tezimin temel fikri: üçün ortancası . Bu yüzden, temel olarak, tamamen birbiriyle değiştirilebilir tam olarak üç kanal (RGB için ideal) kullanıyorsunuz ve bunları medyan işlemini kullanarak birleştiriyorsunuz (üçünden orta değeri seçin).

Kenar yumuşatmayı gidermek için yalnızca booleanlarla çalışmaz, ancak kayan nokta değerleriyle çalışırız ve AND işlemi minimum olur ve VEYA iki değerin maksimum olur. Üçün ortancası gerçekten her ikisini de yapabilir: eğer a < b ( a , a , b ) için, medyan minimumdur ve ( a , b , b ) için maksimumdur.

Render işlemi hala oldukça basittir. Kenar yumuşatma dahil tüm parça gölgelendirici şöyle görünebilir:

int main() {
    // Bilinear sampling of the distance field
    vec3 s = texture2D(sdf, p).rgb;
    // Acquire the signed distance
    float d = median(s.r, s.g, s.b) - 0.5;
    // Weight between inside and outside (anti-aliasing)
    float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
    // Combining the background and foreground color
    gl_FragColor = mix(outsideColor, insideColor, w);
}

Yani orijinal yöntemden tek fark, dokuyu örnekledikten hemen sonra medyanı hesaplamak. Sadece 4 dak / max işlemleriyle yapılabilecek ortanca işlevini uygulamanız gerekecek .

Tabii ki soru şu ki, böyle üç kanallı bir mesafe alanı nasıl kurarım?Ve bu zor kısmı. Başlangıçta uyguladığım en belirgin yaklaşım, girdi şeklinin / glifin üç bileşene ayrıştırılması ve ardından her birinden geleneksel bir mesafe alanı oluşturmaktı. Bu ayrışmanın kuralları o kadar da karmaşık değil. İlk önce, en az 2 kanalın 2'sinin bulunduğu alan iç kısımdır. Ardından, bunu RGB renk kanalları olarak hayal ederseniz, dışbükey köşelerinin ikincil renkten yapılması gerekir ve iki ana bileşeni dışa doğru devam eder. İçbükey köşeler terstir: İki ikincil renk ortak ana renklerini çevreler ve her iki kenarın içe doğru devam ettiği kama beyazdır. Ayrıca, iki birincil veya iki ikincil rengin yapay nesneleri önlemek için başka şekilde temas edebileceği yerlerde (örneğin, "N" nin orta vuruşunda) bazı dolguların gerekli olduğunu buldum.

Aşağıdaki görüntü, tez tarafından program tarafından üretilen örnek bir ayrıştırmadır:

Gliflerin çok kanallı ayrışımı

Ancak bu yaklaşımın bazı dezavantajları vardır. Bunlardan biri, ana hatlar ve gölgeler gibi özel efektlerin artık doğru çalışmayacağıdır. Neyse ki, uzak mesafeleri doğrudan üreten ve hatta tüm grafiksel efektleri bile destekleyen ikinci, çok daha zarif bir yöntem buldum. Aynı zamanda tezime de dahildir ve bir yaşından fazladır. Şu anda daha fazla ayrıntı vermeyeceğim, çünkü şu anda bu ikinci tekniği ayrıntılı bir şekilde açıklayan bir makale yazıyorum, ancak işim biter bitmez buraya göndereceğim.

Her neyse, burada kalite farkına bir örnek. Doku çözünürlüğü her görüntüde aynıdır, ancak soldaki normal bir doku, ortadaki ise normal bir mesafe alanı, sağdaki ise üç kanallı mesafe alanımı kullanır. Performans ek yükü yalnızca bir tek renkli olana karşı bir RGB doku örneklemesi arasındaki farktır.

görüntü tanımını buraya girin


5
Harika bir cevap, Computer Graphics SE’e hoş geldiniz! :) Tezin halka açık mı? (Ya da söylediğini bitirdikten sonra olacak mı?) Eğer öyleyse, muhtemelen bununla da bağlantı kurmak çok yardımcı olacaktır.
Martin Ender

Kamuya açık olması gerekiyordu, ancak okul henüz koymadı gibi görünüyor. Her neyse, şu anda yaymamayı tercih ederim, çünkü yazdığım makale önemli kısımları daha iyi açıklayacak ve nasıl uygulanacağına odaklanacak ve çok yakında tamamlanacak.
Detheroc

@Detheroc Lütfen makaleyi tamamladığınızda, burada ve gamedev Q ile ilgili bilgi verin. Açıklama hala benim için% 100 net değil. Kompozisyonun adım adım görüntülerle gösterilmesini tavsiye ederim.
Mühendis

1
Gelecekteki sonuçlarınız kadar iyi olmasalar bile, mevcut sonuçlarınızı tekrarlayabilmeyi çok isterdim, + 1, yapabileceklerinizi paylaşmak için. çok heyecan verici. Her iki tekniğin de ışın yürüyüşüne (küre izleme) uygulanmasını düşündünüz mü? Cilt dokularında veya benzerlerinde ...
Alan Wolfe


43

Uzun süre beklettiğim için üzgünüm, ancak söz verdiğim makale temelde tamamlanmış olsa da yayın sürecinin biraz zaman alacağı açıkça ortaya çıktı. Bu nedenle, şu anda deneyebileceğiniz yeni çok kanallı mesafe alan inşaat algoritmam olan msdfgen ile açık kaynaklı bir program hazırladım .

GitHub'da kullanılabilir: https://github.com/Chlumsky/msdfgen

(Bu konuda yeniyim, bu nedenle lütfen depoda bir sorun olup olmadığını bana bildirin.)

Birisi ayrıca daha büyük tek renkli bir mesafe alanıyla nasıl kıyaslanacağını da sordu, işte kalite farkının bir teaser'ı. Ancak, gerçekten belirli bir yazı tipine bağlıdır ve her zaman ek veriye değdiğini söyleyemem.

Çok kanallı mesafe alanı 16x16 Tek renkli mesafe alanı 32x32


3

Oldukça ilginç! Ben vana imzalı mesafeli kağıdın yazarıyım. Maalesef uygulama detaylarında biraz seyreklik var. İki kanal örneğini sadece gelecekteki çalışma olarak dahil ettim - jeneratörüm yoktu. Yüksek çözünürlüklü bir sdf oluşturmak gibi bir şey buldum ve sdf'in gradyanının açısına göre ayırmak makul bir taktik olurdu. Ama asla başaramadım. Herhangi bir çok kanallı şema, uygulamanızın ihtiyaç duyduğu büyütme oranlarının aynı olması için aynı bellek ayak izinin daha yüksek çözünürlükte tek kanallı verilerinin kullanılmasına karşı tartılmalıdır.


0

Konuyla ilgili hiçbir uzman değilim ama en azından teoride, standart bir Bilinear filtre yerine bir Yönlü Bikübik filtre ya da iki taraflı bir filtre kullanıyorsanız, monokromatik bir sözde SDF'deki keskin köşeleri koruyabilirsiniz. Belleği kaydetmenin bariz avantajının yanı sıra, çok renkli SDF etiketleri için birden fazla kanalınız da olabilir.

Alternatif olarak, ikinci bir kanal kullanmaya aldırış etmezseniz, o zaman Yatay Mesafe için bir kanala ve Dikey Mesafe için diğer bir kanala sahip olmayı deneyebilir ve doku bilgisini gereksiz kılacak şekilde sıkıştırmak için Laplacean (DoL) enerji piramitini kullanabilirsiniz. kaydedilmedi.

Üçüncü ve son bir teorik çözüm, Dizi Ayarı Adresleme yoluyla Altıgen Örneklemeli Bir Doku ile deneme yapmak olacaktır.

Ne yazık ki, şu anda fikirlerimi test etmek için hiçbir yolum yok ve fikirlerime benzer bir şeyi açıklayan veya test eden herhangi bir belge bulamadım. Bilgi / fikirlerimi kısa sürede aldığım ilgili tüm makaleleri birbirine bağlayacağım.

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.