Kimi K3 نے ڈیجیٹل فاؤنٹین پین کی لکیر کیسے بنائی
ہم Lulucat Notes میں Freeform جیسی سمت دار فاؤنٹین پین کی لکیر چاہتے تھے۔ اس کی تفصیلات صرف ہاتھ سے لکھی تحریر کا ایک اسکرین شاٹ تھیں۔ دو ماڈل، ایک فیصلہ کن سوال، اور ایک بیضوی نوک کے بعد واٹر پین ویسے لکھتا ہے جیسے اسے لکھنا چاہیے۔ تحقیق، پروگرام اور جانچ Fireworks پر Kimi K3 نے کی۔

اس پوسٹ میں زیرِ بحث Lulucat Notes کی Metal pipeline سے اسے رینڈر کیا گیا ہے۔
Lulucat Notes میں ایک سادہ پین اور ایک ہائی لائٹر ہے۔ روڈمیپ کا اگلا آلہ واٹر پین تھا — Apple Notes اور Freeform میں نظر آنے والا وہ سمت دار فاؤنٹین پین جس میں عمودی لکیریں موٹی اور افقی لکیریں پتلی نکلتی ہیں۔ اس آلے کی تفصیل کوئی دستاویز نہیں تھی۔ یہ ایک اسکرین شاٹ تھا: ہاتھ سے لکھی تحریر کی تین سطریں، الفاظ “pencilkit”، “无边记”، اور “这种有方向的水笔能力” — یعنی سمت دار واٹر پین کی یہ صلاحیت۔
پہلے Metal pipeline کی طرح یہ کام بھی Kimi K3 نے کیا، جو Moonshot کا open model ہے اور Fireworks پر چلتا ہے: measurement، modeling، code اور validation۔ انسان نے screenshot فراہم کیا، ایک سوال کا جواب دیا، اور ایک حقیقی iPad پر feel کا فیصلہ کیا۔
وضاحت ایک اسکرین شاٹ ہے
ایک جامد تصویر یہ نہیں بتا سکتی کہ لکیر پتلی کیوں ہے۔ یہ صرف بتا سکتی ہے کہ وہ کتنی پتلی ہے اور کہاں ہے۔ اس لیے پہلا قدم پیمائش تھا۔ ہم نے اسکرین شاٹ کو سطر بہ سطر اور کالم بہ کالم scan کیا، ہر لکیر کے centerline drift کو track کر کے سمت نکالی، پھر اس زاویے کے sine کے ذریعے scan width کو اصل width میں تبدیل کیا:
| اسٹروک | سمت | اصل چوڑائی |
|---|---|---|
| “l” کا ascender، “pencilkit” | ≈ 78° | 27.3 px |
| “k” کا stem، “pencilkit” | ≈ 90° | 28 px |
| 力 کا بائیں طرف گرتا ہوا sweep | ≈ 66° | 25.7 px |
| خطِ مسلسل کے جوڑ | ≈ 8° | 11 px |
| چینی افقی لکیریں (横) | ≈ 0° | 6–11 px |
موٹائی سے باریکی کا ratio ≈ 2.5 ہے۔ 66° والے point پر
پہلا version: direction سے width
پہلا model سیدھا تھا: ہر input point کے لیے سمت compute کریں، fitted curve کے ذریعے سمت کو width میں map کریں، اور capture کے وقت نتیجے کو point کے radius میں bake کریں۔ سمت کا causal estimate لیا گیا — arc کے آخری چند points پر exponentially decaying weighted average، جسے doubled-angle space میں compute کیا گیا تاکہ سفر کا رخ الٹنے سے estimate cancel نہ ہو۔ صرف ماضی کے points استعمال ہوئے، اس لیے live stroke اور committed stroke byte بہ byte ایک جیسے رہے۔
Builder نے اپنا unit check پاس کیا: synthetic horizontal، vertical، 45° اور reversal paths سب نے theoretical widths bake کر لیں — 0.99، 2.52، 2.00 اور 0.99 points۔ Rendering کے لیے کوئی نیا code درکار نہیں تھا: baked-radius stroke صرف round stamps کی ایک chain ہے، اور ہماری point-sprite pipeline پہلے ہی انہیں draw کر رہی تھی۔
iPad پر انسان نے اسے رد کرنے میں تقریباً دس seconds لیے: “یہ آرٹ پین ہے، واٹر پین نہیں۔”
دو وضاحتیں ایک ہی تصویر پر پوری اترتی ہیں
یہ غلط کیوں محسوس ہوئی؟ دو candidate explanations تھیں، اور screenshot ان میں فرق نہیں کر سکتی تھی:
- سمت کا قفل۔ نوک کی geometry ہاتھ کچھ بھی کرے، افقی لکیروں کو پتلا اور عمودی لکیروں کو موٹا رکھتی ہے۔ پہلے ورژن نے یہی نافذ کیا تھا۔
- دباؤ اور رفتار۔ قلم دباؤ سے چلتا ہے، اور sample کا pattern صرف ہاتھ کی تحریر کی dynamics ہے: نیچے جانے والی لکیروں پر قدرتی طور پر زیادہ دباؤ پڑتا ہے، جوڑ قدرتی طور پر تیز اور ہلکے ہوتے ہیں۔
دونوں پتلی افقی اور موٹی عمودی لکیروں والا screenshot بنا سکتے ہیں۔ فرق یہ ہے کہ افقی لکیر پر زور سے دبانے پر کیا ہوتا ہے۔ پہلا ورژن اسے پتلا رکھتا ہے۔ دباؤ سے چلنے والا قلم اسے موٹا کر دیتا ہے۔ اس لیے ہم نے انسان سے ایک سوال پوچھا: کیا زور سے دبائی گئی افقی لکیر موٹی ہونی چاہیے؟
“نہیں۔ افقی لکیریں پتلی رہتی ہیں۔”
سمت کے قفل کی تصدیق ہو گئی۔ لیکن کوئی اور چیز بھی غلط تھی، کیونکہ پہلا ورژن بھی سمت کے قفل والا تھا۔
جواب لکیر کے سروں میں تھا
اگلا clue اوپر اٹھنے والی لکیروں کے اوپر تھا۔ Sample میں “l” اور “k” کے stems کو zoom کرنے سے دو باتیں سامنے آئیں: ایک سیدھی لکیر شروع سے آخر تک ایک ہی width رکھتی ہے، اور لکیر کے سرے چپٹے ترچھے کٹ ہیں — chisel nib کے کاغذ سے اٹھنے کی شکل۔ یہ round dots نہیں ہیں، اور pressure tapers بھی نہیں۔

“آرٹ پین جیسا احساس” سے مراد یہی تھی۔ پہلے ورژن نے sample کی شکل model کی — width کو estimated direction کے function کے طور پر — مگر pen کو model نہیں کیا۔ سمت کا estimator ایک sensor ہے: noisy input پر jitter کرتا ہے، corners کے آس پاس lag کرتا ہے، اور ہر لکیر کے سرے کو circle میں round کر دیتا ہے۔ اصلی نوک میں یہ مسائل نہیں ہوتے، کیونکہ وہ کچھ compute نہیں کرتی۔ Width ہی geometry ہے۔
دوسرا ورژن: ایک بیضوی نوک
حتمی model میں direction estimator بالکل نہیں ہے۔ نوک ایک oriented ellipse ہے: long axis horizontal، short axis fixed۔ اس ellipse کے stamps کو لکیر کے path پر گنجان رکھا جاتا ہے، اور باقی سب geometry سے نکلتا ہے:
-
ایک افقی لکیر open edge کے ساتھ چلتی ہے، اس لیے وہ ہر بار
چوڑی نکلتی ہے — کسی بھی دباؤ پر ایک مستقل پتلی لکیر۔ یہی confirmed spec ہے۔ -
ایک عمودی لکیر پوری long axis کو cross کرتی ہے:
، یعنی موٹا سرا۔ -
ایک ترچھی لکیر، سفر کی سمت کے عمود پر موجود ellipse کی chord width لیتی ہے،
-
لکیر کے سرے elliptical cuts ہیں — sample والے flat nib-shaped ends، بغیر کسی اضافی کام کے۔
-
دباؤ صرف long axis کو scale کرتا ہے،
، اس لیے نیچے جانے والی لکیروں پر ink volume بڑھتا ہے اور افقی لکیر کبھی موٹی نہیں ہو سکتی۔
Sample کی measurements سے ہم نے
Rendering کے لیے صرف ایک نیا fragment shader درکار تھا۔ Vertex format — position، diameter، color — پہلے ہی سب کچھ رکھتا تھا: diameter long axis ہے، اور short axis ہر pass کا uniform ہے۔ Shader ہمارے round stamps جیسا ہی half-pixel coverage ramp استعمال کرتے ہوئے ellipse SDF evaluate کرتا ہے؛ اسی وجہ سے اسے Core Graphics کی reference implementation (fillEllipse per stamp) کے ساتھ pixel سطح پر compare کیا جا سکتا ہے۔ Validation معمول کے gate سے گزری: دو fountain strokes والے synthetic corpus کو دونوں طریقوں سے render کر کے pixel by pixel compare کیا گیا — structural differences صفر تھے، اور spot-check کیا گیا horizontal stroke دونوں renderers میں 12 px نکلا۔

بائیں version one، دائیں version two۔ وہی handwritten input، وہی pipeline۔ سرے کہانی سناتے ہیں۔
iPad پر نئی pen فوراً پاس ہو گئی: “好,很好” — اچھا۔ بہت اچھا۔
اس ناکام کوشش کو رکھنا
پہلا ورژن پھینکا نہیں گیا۔ یہ واقعی ایک دلچسپ برش ہے، بس واٹر پین نہیں ہے۔ اس لیے اسے انسان کے دیے ہوئے نام 漏水的圆珠笔، یعنی لیک کرنے والا بال پوائنٹ قلم، کے ساتھ نئے تجرباتی برش مینو کی پہلی entry کے طور پر ship کیا گیا۔ Toolbar میں flask button شامل ہوا جو experiments کی text list کھولتا ہے؛ اگلا experiment شامل کرنے کے لیے registry میں ایک line کافی ہے۔ Rejected model ضائع شدہ کام نہیں، اگر اسے واضح label والے experiment کے طور پر ship کیا جا سکے۔
ایک شام کے چکر
پورا سلسلہ — measure، model، build، device، question، remodel، rebuild، validate — ایک شام میں مکمل ہوا۔ Fireworks پر Kimi K3 نے loop کا پورا technical حصہ چلایا: measurement scans وضع کیے، دوسری بار اندازہ لگانے کے بجائے discriminating سوال تجویز کیا، evidence بدلنے پر اپنا direction estimator حذف کیا، اور app کو چھونے سے پہلے pixel-diff harness کو وسیع کیا۔ Fireworks کی inference speed نے loop کو interactive رکھا — لمبے Metal اور Swift diffs، pixel-analysis scripts اور corpus tooling اتنی تیزی سے آئے کہ باقی رہنے والا bottleneck انسانی فیصلہ تھا۔
Collaboration pattern وہی تھا جس کے بارے میں ہم نے Metal pipeline والی پوسٹ میں لکھا تھا، اور یہ دوبارہ بھی کارگر رہا: model تیز اور درست ہے، جبکہ انسان taste اور end-to-end verification کا ذمہ دار ہے۔ Feel پر مبنی feedback کا ایک جملہ — “آرٹ پین، واٹر پین نہیں” — model کے لیے exact modeling error تلاش کر کے اس کی جگہ ایک سادہ design رکھنے کے لیے کافی تھا۔
صحیح model غلط model سے چھوٹا نکلا۔ Version two، version one کے مقابلے میں کم moving parts کے ساتھ ship ہوا — نہ estimator، نہ smoothing window، نہ fitted exponent۔ Nib width compute نہیں کرتا۔ نوک ہی چوڑائی ہے۔