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