Lulucat

Kimi K3 Dijital Bir Dolma Kalem Çizgisini Nasıl Oluşturdu

Gaoge ZhangGaoge Zhang

Lulucat Notes'a Freeform'daki gibi yönlü bir dolma kalem çizgisi istedik. Özellik tanımı bir el yazısı ekran görüntüsünden ibaretti. İki model, ayırt edici tek bir soru ve elips biçimli bir uçtan sonra su kalemi olması gerektiği gibi yazıyor. Araştırma, kod ve doğrulama Fireworks üzerindeki Kimi K3 tarafından yapıldı.

Güncellendi

Krem rengi kâğıt üzerinde elips uçlu dolma kalemle çizilmiş el yazısı: üstte İngilizce kursif “fountain pen”, altında bir satır Çin kaligrafisi; dikey çizgiler kalın, yatay çizgiler ince.

Bu yazının konusunu oluşturan Lulucat Notes Metal işlem hattı tarafından işlendi.

Lulucat Notes’ta sade bir kalem ve fosforlu kalem var. Yol haritasındaki sıradaki araç bir su kalemiydi — Apple Notes ve Freeform’dan bildiğiniz, dikey çizgileri kalın, yatay çizgileri ince çıkaran yönlü dolma kalem. Bu aracın özellik tanımı bir belge değildi. Bir ekran görüntüsüydü: üç satır el yazısı, “pencilkit”, “无边记” ve “这种有方向的水笔能力” sözcükleri — bu yönlü su kalemi yeteneği.

Önceki Metal işlem hattında olduğu gibi bu işi de Fireworks üzerinde çalışan Moonshot’un açık modeli Kimi K3 yaptı: ölçüm, modelleme, kod ve doğrulama. İnsan ekran görüntüsünü sağladı, tek bir soruyu yanıtladı ve gerçek bir iPad’de hissi değerlendirdi.

Özellik tanımı bir ekran görüntüsüdür

Durağan bir görüntü bir stroke’ın neden ince olduğunu söyleyemez. Yalnızca ne kadar ince olduğunu ve nerede olduğunu söyleyebilir. Bu yüzden ilk adım ölçümdü. Ekran görüntüsünü satır satır ve sütun sütun taradık, yönünü bulmak için her stroke’ın merkez çizgisi kaymasını izledik, ardından tarama genişliğini o açının sinüsüyle gerçek genişliğe dönüştürdük:

ÇizgiYönGerçek genişlik
“l” üst uzantısı, “pencilkit”≈ 78°27.3 px
“k” gövdesi, “pencilkit”≈ 90°28 px
力 karakterinin sola düşen süpürmesi≈ 66°25.7 px
Kursif bağlantılar≈ 8°11 px
Çince yataylar (横)≈ 0°6–11 px

Kalınlık-incelik oranı ≈ 2.5. eğrisini 66° noktasına uydurunca elde ediyoruz — üzerinde neredeyse doğrusal ve dikey eksende tepe yapıyor. Etkili olarak bu bir italik uç: yatay yazının asla açmadığı yatay bir yarık.

Birinci sürüm: yönden genişlik

İlk model basitti: her girdi noktası için bir yön hesaplamak, uydurulmuş eğriyle yönü genişliğe eşlemek ve sonucu yakalama anında noktanın yarıçapına gömmek. Yön nedensel olarak tahmin edildi — yay üzerindeki son birkaç noktaya uygulanan üstel azalan ağırlıklı ortalama, hareketin tersine dönmesinin tahmini iptal etmemesi için çift açı uzayında hesaplandı. Yalnızca geçmiş noktalar kullanıldığı için canlı çizgi ile kaydedilmiş çizgi bayt bayt aynıydı.

Oluşturucu birim denetimini geçti: sentetik yatay, dikey, 45° ve tersine dönüş yollarının hepsi kuramsal genişlikleri — 0.99, 2.52, 2.00 ve 0.99 points — içine yazdı. İşleme için hiç yeni kod gerekmedi: yarıçapı önceden yazılmış bir çizgi yalnızca yuvarlak damgalardan oluşan bir zincirdir ve point-sprite işlem hattımız bunları zaten çiziyordu.

iPad’de insanın onu reddetmesi yaklaşık on saniye sürdü: “Bu bir sanat kalemi, su kalemi değil.”

İki açıklama tek görüntüye uyuyor

Neden yanlış hissettiriyordu? İki olası açıklama vardı ve ekran görüntüsü bunları birbirinden ayıramıyordu:

  • Yön kilidi. Uç geometrisi, el ne yaparsa yapsın yatayları ince, dikeyleri kalın olmaya zorlar. Birinci sürümün uyguladığı şey buydu.
  • Basınç ve hız. Kalem basınçla çalışır; örnekteki desen ise yalnızca el yazısının dinamikleridir: aşağı vuruşlara doğal olarak daha fazla basılır, bağlantılar doğal olarak hızlı ve hafif olur.

İki açıklama da ince yataylar ve kalın dikeyler içeren bir ekran görüntüsü üretir. Fark, yatay bir çizgiye sertçe bastığınızda ne olduğudur. Birinci sürüm onu ince tutar. Basınçla çalışan kalem onu kalınlaştırır. Bu yüzden insana tek bir soru sorduk: Sertçe bastırılan bir yatay çizgi daha kalın olmalı mı?

“Hayır. Yataylar ince kalır.”

Yön kilidi doğrulandı. Ancak başka bir şey daha yanlıştı, çünkü birinci sürüm de yön kilidine sahipti.

Yanıt çizgi uçlarındaydı

Sıradaki ipucu üst uzantıların tepesindeydi. Örnekteki “l” ve “k” gövdelerini büyütünce iki şey ortaya çıktı: düz bir çizgi baştan sona aynı genişliği koruyor ve çizgi uçları düz çapraz kesitler — keski uçlu kalemin kâğıttan kaldırılırken oluşturduğu şekil. Yuvarlak noktalar değil. Basınçla incelen uçlar değil.

Örnekteki iki el yazısı üst uzantı gövdesinin yakın kırpımı; her biri üstte düz çapraz bir kesitle bitiyor ve gövde boyunca kalınlık aynı kalıyor.

“Sanat kalemi hissi”nin anlamı buydu. Birinci sürüm örneğin görünüşünü — genişliği tahmin edilen yönün bir fonksiyonu olarak — modelledi, ancak kalemi modellemedi. Yön tahmincisi bir sensördür: gürültülü girdide titrer, köşelerde gecikir ve her çizginin ucunu bir çembere yuvarlar. Gerçek bir uçta bu sorunların hiçbiri yoktur, çünkü hiçbir şey hesaplamaz. Genişliği belirleyen geometridir.

İkinci sürüm: elips uç

Son modelde hiç yön tahmincisi yok. Uç, yönlendirilmiş bir elips biçimindedir: uzun eksen yatay, kısa eksen sabit. Bu elipsin damgaları çizginin yolu boyunca sık aralıklarla yerleştirilir; geri kalan her şey geometriden çıkar:

  • Yatay bir çizgi açık kenar boyunca ilerler, bu yüzden her zaman genişliğinde çıkar — her basınçta sabit ince bir çizgi. Doğrulanmış özellik tam olarak budur.

  • Dikey bir çizgi tüm uzun ekseni keser: genişliğinde, yani kalın uçta.

  • Diyagonal bir çizgi, hareket yönüne dik olan elipsin kiriş genişliğini alır,

  • Çizgi uçları eliptik kesitlerdir — örnekteki düz, uç biçimli kesitler; ek işlem olmadan elde edilir.

  • Basınç yalnızca uzun ekseni ölçekler, ; böylece aşağı vuruşlarda mürekkep hacmi artar, ancak yatay bir çizgi asla kalınlaşmaz.

Örnek ölçümlerinden pt ve pt değerlerini koruduk; oran yine 2.5. Damgalar yay boyunca 0.5 points aralıklarla yerleştiriliyor; 0.55-point kısa yarıçapla en kötü durumdaki kenar dalgalanması yaklaşık bir pikselin onda biri kadar.

İşleme için yalnızca bir yeni fragment shader gerekti, başka hiçbir şey değil. Vertex format — konum, çap, renk — zaten her şeyi taşıyordu: çap uzun eksen, kısa eksen ise her pass için bir uniform. Shader, yuvarlak damgalarımızla aynı yarım piksel kapsama rampasını kullanarak bir elips SDF’si değerlendiriyor; bu da onu Core Graphics referans uygulamasıyla (fillEllipse her damga için) piksel düzeyinde karşılaştırılabilir kılıyor. Doğrulama alışılmış kapıdan geçti: iki dolma kalem çizgisi içeren sentetik bir külliyat iki yöntemle işlendi ve piksel piksel karşılaştırıldı — yapısal fark sıfır; rastgele seçilip kontrol edilen yatay bir çizgi her iki renderer’da da 12 px ölçüldü.

Aynı el yazısıyla yazılmış “fountain” sözcüğünün yan yana iki işlenmiş görünümü: soldaki, yönle ölçeklenen çapa sahip yuvarlak damgalarla çizilmiş ve yuvarlak uçlar gösteriyor; sağdaki, elips damgalarla çizilmiş ve düz uç kesitleri ile daha sabit bir genişlik gösteriyor.

Solda birinci sürüm, sağda ikinci sürüm. Aynı el yazısı girdisi, aynı işlem hattı. Uçlar hikâyeyi anlatıyor.

iPad’de yeni kalem ilk denemede onaylandı: “好,很好” — iyi. Çok iyi.

Iskalananı korumak

Birinci sürüm çöpe atılmadı. Gerçekten ilginç bir fırça; yalnızca su kalemi değil. Bu nedenle insanın verdiği adla, 漏水的圆珠笔 yani sızdıran tükenmez kalem adı altında, yeni deneysel fırça menüsünün ilk girdisi olarak gönderildi. Araç çubuğuna bir şişe düğmesi eklendi; bu düğme deneylerin bir metin listesini açıyor. Sıradakini eklemek kayıt defterine tek satır eklemekten ibaret. Açıkça etiketlenmiş bir deney olarak gönderilebildiği sürece reddedilmiş bir model boşa gitmiş sayılmaz.

Tek akşamlık döngüler

Tüm yay — ölç, modelle, inşa et, cihaza taşı, sor, yeniden modelle, yeniden inşa et, doğrula — bir akşam sürdü. Fireworks’teki Kimi K3 döngünün teknik tarafının tamamını yürüttü: ölçüm taramalarını tasarladı, ikinci kez tahmin etmek yerine ayırt edici soruyu önerdi, kanıt yön değiştirince kendi yön tahmincisini kaldırdı ve uygulamaya dokunmadan önce pixel-diff harness’ini genişletti. Fireworks’un çıkarım hızı döngüyü etkileşimli tuttu — uzun Metal ve Swift diff’leri, piksel analizi betikleri ve külliyat araçları, geriye yalnızca insan yargısının darboğaz kalacağı kadar hızlı geldi.

İş birliği deseni, Metal işlem hattı yazısında anlattığımızın aynısıydı ve yine işe yaradı: model hızlı ve kesin; insan ise zevkten ve uçtan uca doğrulamadan sorumlu. His tabanlı tek bir geri bildirim cümlesi — “sanat kalemi, su kalemi değil” — modelin kesin modelleme hatasını bulup yerine daha basit bir tasarım koyması için yeterliydi.

Doğru model yanlış modelden daha küçük çıktı. İkinci sürüm birinci sürümden daha az hareketli parçayla gönderildi — tahminci yok, yumuşatma penceresi yok, uydurulmuş üs yok. Uç genişliği hesaplamaz. Uç genişliğin kendisidir.