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:
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.