Tajam Sudut dengan Font Bidang Bidang yang Ditandatangani


49

Signed Distance Fields (SDFs) disajikan sebagai solusi cepat untuk mencapai rendering font independen resolusi oleh Valve dalam makalah ini .

Saya sudah memiliki solusi Valve yang berfungsi, tetapi saya ingin mempertahankan ketajaman sudut. Valve menyatakan bahwa metode mereka dapat mencapai sudut yang tajam dengan menggunakan saluran tekstur kedua ANDed dengan yang dasar, tetapi tidak menjelaskan bagaimana saluran kedua ini akan dihasilkan.

Faktanya ada banyak detail implementasi yang tertinggal dari tulisan ini.

Saya ingin tahu apakah ada di antara Anda yang bisa menunjukkan saya arah untuk mendapatkan rendering font SDF dengan sudut tajam.


Faktanya Adam sudah memposting kode sumber di shadertoy. Inilah tautannya: shadertoy.com/view/ltXSDB
Felipe Lira

Anda membuat saya bersemangat. Dia memposting barang-barang bezier di shadertoy tetapi bukan hal-hal bidang tekstur jarak!
Alan Wolfe

@AlanWolfe Saya pikir dia telah melakukan hanya untuk kurva bezier yang diatur secara prosedural. Saya tidak yakin upaya yang diperlukan untuk mengintegrasikan ini ke dalam ttf render lib. Ketika saya punya waktu, saya akan melihatnya.
Felipe Lira

kelihatannya ia memiliki beberapa saus ajaib di samping sebenarnya menyimpan dan mengambil jarak dari tekstur. Tanpa tekstur dalam permainan, contoh shadertoy kehilangan bagian persamaan itu.
Alan Wolfe

Agak terlambat ke pesta tetapi utas lama dari reddit ini memiliki banyak info tentang berbagai metode untuk meningkatkan ketajaman rendering berbasis SDF: reddit.com/r/gamedev/comments/2879jd/…
Necrolis

Jawaban:


7

Adam Simmons telah melakukan beberapa pekerjaan menarik di bidang ini. Saya tidak tahu secara spesifik bagaimana dia mencapainya, tetapi rendering vektor berbasis SDF-nya adalah yang paling tajam yang pernah saya lihat dalam praktik di luar Valve. http://twitter.com/adamjsimmons/status/611677036545863680


Tentu saja saya tidak memiliki semua detailnya, tetapi bagi saya tampaknya orang ini hanya menggunakan bidang jarak semu sebagai ganti bidang biasa, yang telah ditunjukkan dalam makalah 2006 oleh Qin, McCool dan Kaplan, " Mesin terbang vektor dipetakan tekstur waktu nyata ", yang juga dirujuk dalam kertas Valve. Ini hanya memengaruhi miters outline dan tidak melakukan apa pun untuk meningkatkan penampilan sudut. Saya curiga alasannya terlihat tajam adalah karena dia menggunakan tekstur bidang jarak jauh yang terlalu jauh. Tapi saya mungkin salah.
Detheroc

69

EDIT: Silakan lihat jawaban saya yang lain dengan solusi konkret.

Saya sebenarnya telah memecahkan masalah yang tepat ini lebih dari setahun yang lalu untuk tesis master saya. Di kertas Valve, mereka menunjukkan bahwa Anda dapat DAN dua bidang jarak untuk mencapai ini, yang berfungsi selama Anda hanya memiliki satu sudut cembung. Untuk sudut cekung, Anda juga memerlukan operasi ATAU. Orang ini sebenarnya mengembangkan beberapa sistem yang tidak jelas untuk beralih antara dua operasi menggunakan empat saluran tekstur.

Namun, ada operasi yang jauh lebih sederhana yang dapat memfasilitasi baik AND dan OR tergantung pada situasinya, dan ini adalah gagasan utama dari tesis saya: median tiga . Jadi pada dasarnya, Anda menggunakan tepat tiga saluran (ideal untuk RGB), yang sepenuhnya dapat dipertukarkan, dan menggabungkannya menggunakan operasi median (pilih nilai tengah dari ketiganya).

Untuk mengakomodasi anti-aliasing, kami tidak bekerja hanya dengan boolean, tetapi nilai floating point, dan operasi AND menjadi minimum, dan OR menjadi maksimum dua nilai. Median tiga memang dapat melakukan keduanya: jika a < b , untuk ( a , a , b ), median adalah minimum, dan untuk ( a , b , b ), itu adalah maksimum.

Proses rendering masih sangat sederhana. Seluruh shader fragmen termasuk anti-aliasing dapat terlihat seperti ini:

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);
}

Jadi satu-satunya perbedaan dari metode asli adalah menghitung median tepat setelah sampel tekstur. Anda harus mengimplementasikan fungsi median, yang dapat dilakukan hanya dengan 4 menit / operasi maks .

Sekarang tentu saja, pertanyaannya adalah, bagaimana cara membuat bidang jarak tiga saluran seperti itu?Dan ini bagian yang sulit. Pendekatan yang paling jelas yang saya ambil di awal adalah melakukan dekomposisi bentuk input / mesin terbang menjadi tiga komponen, dan kemudian menghasilkan bidang jarak konvensional dari masing-masing. Aturan untuk dekomposisi ini tidak rumit. Pertama, area dengan setidaknya 2 dari 3 saluran aktif adalah bagian dalamnya. Kemudian, jika Anda membayangkan ini sebagai saluran warna RGB, sudut cembung harus dibuat dari warna sekunder, dan dua komponen utamanya terus keluar. Sudut-sudut cekung adalah kebalikannya: Dua warna sekunder melingkupi warna primer mereka yang umum, dan irisan antara tempat kedua sisi terus ke dalam berwarna putih. Saya juga menemukan bahwa beberapa lapisan diperlukan di mana dua warna primer atau dua warna sekunder akan bersentuhan untuk menghindari artefak (misalnya, pada goresan tengah "N"

Gambar berikut adalah contoh penguraian yang dihasilkan oleh program dari tesis saya:

Dekomposisi multi-channel mesin terbang

Namun pendekatan ini memiliki beberapa kelemahan. Salah satunya adalah bahwa efek khusus, seperti garis besar dan bayangan tidak akan berfungsi dengan benar. Fortunatelly, saya juga datang dengan metode kedua, jauh lebih elegan, yang menghasilkan bidang jarak secara langsung, dan bahkan mendukung semua efek grafis. Ini juga termasuk dalam tesis saya dan juga lebih dari satu tahun. Saya tidak akan memberikan rincian lebih lanjut saat ini, karena saya saat ini sedang menulis makalah yang menjelaskan teknik kedua ini secara rinci, tetapi saya akan mempostingnya di sini segera setelah selesai.

Bagaimanapun, berikut adalah contoh perbedaan kualitas. Resolusi tekstur sama di setiap gambar, tetapi yang kiri menggunakan tekstur biasa, yang tengah menggunakan bidang jarak biasa, dan yang kanan menggunakan bidang jarak tiga saluran saya. Overhead kinerja hanya perbedaan antara pengambilan sampel tekstur RGB versus yang monokrom.

masukkan deskripsi gambar di sini


5
Jawaban pertama yang bagus, selamat datang di Computer Graphics SE! :) Apakah tesis Anda tersedia untuk umum? (Atau akankah setelah Anda selesai mengatakan makalah?) Jika demikian mungkin akan sangat membantu untuk menautkannya juga.
Martin Ender

Seharusnya tersedia untuk umum, tetapi tampaknya sekolah belum memasangnya. Lagi pula, saya lebih suka untuk tidak menyebarkannya sekarang, karena artikel yang saya tulis akan benar-benar menjelaskan bagian-bagian penting lebih baik dan fokus pada bagaimana mengimplementasikannya, dan harus diselesaikan segera.
Detheroc

@Detheroc Mohon beri tahu di sini dan di gamedev Q ketika Anda selesai dengan artikel. Penjelasannya masih belum 100% jelas bagi saya. Saya sarankan menunjukkan komposisi langkah demi langkah dalam gambar.
Insinyur

1
ingin dapat mereplikasi hasil Anda saat ini bahkan jika mereka tidak sebagus hasil masa depan Anda, +1 untuk membagikan detail apa pun yang Anda bisa. sangat menarik. Sudahkah Anda mempertimbangkan penerapan salah satu teknik ini terhadap ray marching (sphere tracing)? Dalam tekstur volume atau sejenisnya ...
Alan Wolfe

4
Tesis ini tersedia untuk umum di sini: dspace.cvut.cz/bitstream/handle/10467/62770/…
Romain Guy

43

Maaf tentang penantian yang lama, tetapi menjadi jelas bahwa meskipun artikel yang saya janjikan pada dasarnya selesai, proses penerbitan akan memakan waktu. Oleh karena itu, saya malah menyiapkan program open source dengan algoritma konstruksi bidang jarak multi-channel baru saya, msdfgen , yang dapat Anda coba sekarang.

Ini tersedia di GitHub: https://github.com/Chlumsky/msdfgen

(Saya baru mengenal hal ini, jadi tolong beri tahu saya jika ada sesuatu yang salah dengan repositori.)

Seseorang juga bertanya tentang bagaimana membandingkannya dengan bidang jarak monokrom yang lebih besar, jadi di sini ada teaser perbedaan kualitas. Namun, itu benar-benar tergantung pada font tertentu, dan saya tidak akan mengatakan itu selalu bernilai data tambahan.

Bidang jarak multi-saluran 16x16 Bidang jarak monokrom 32x32


3

Cukup menarik! Saya penulis kertas jarak yang ditandatangani katup. Maaf sedikit tentang detail implementasi. Saya hanya memasukkan dua contoh saluran sebagai pekerjaan di masa depan - saya tidak memiliki generator. Saya pikir sesuatu seperti menghasilkan res sdf tinggi dan segmentasi berdasarkan sudut gradien sdf akan menjadi taktik yang masuk akal. Tapi tidak pernah berhasil. Skema multisaluran apa pun harus ditimbang terhadap penggunaan data saluran tunggal res yang lebih tinggi dari jejak memori yang sama, untuk rasio perbesaran yang dibutuhkan aplikasi Anda.


0

Saya sama sekali tidak ahli dalam hal ini, tetapi Anda mungkin dapat, setidaknya secara teori, mempertahankan sudut tajam dalam pseudo-SDF monokromatik jika Anda menggunakan salah satu filter Bilateral, filter Directional Bicubic alih-alih filter Bilinear standar. Selain manfaat nyata menghemat memori, Anda juga bisa memiliki beberapa saluran untuk decals SDF multi-warna.

Atau, jika Anda tidak keberatan menggunakan saluran kedua, maka Anda juga dapat mencoba memiliki satu saluran untuk Jarak Horisontal dan saluran lainnya untuk Jarak Vertikal, dan menggunakan piramida energi Sellacean (DoL) untuk mengompresi tekstur sehingga informasi yang berlebihan tidak diperlukan. direkam.

Solusi teoritis ketiga dan terakhir adalah bereksperimen dengan Tekstur Sampel Heksagonal melalui Array Set Addressing.

Sayangnya, saya tidak memiliki sarana untuk menguji ide-ide saya saat ini, dan tidak dapat menemukan dokumen yang menggambarkan atau menguji sesuatu yang mirip dengan ide-ide saya. Saya akan menautkan semua artikel yang relevan di mana saya mendapatkan informasi / ide saya segera.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.