Troika: فكرة سريعة لتحسين التنعيم النص

تم إنشاؤها على ١٧ يونيو ٢٠٢١  ·  7تعليقات  ·  مصدر: protectwise/troika

لست متأكدًا مما إذا كنت قد قمت بتحديث رمز منع التشويش مؤخرًا ، حيث إنني أستخدم إصدارًا قديمًا ، ولكن بعد العثور على طريقة لطيفة للقيام بتحويل الدوائر المرسومة بالتظليل ، أردت تجربتها على النص أيضًا ، لأن النص يستند إلى SDF ، كما أن تشويش الدائرة يعتمد على المسافة أيضًا.

في الإصدار الحالي من Troika ، تقوم بعمل return length(fwidth(vTroikaGlyphUV * vTroikaGlyphDimensions)) * 0.5; للمسافة aa. يحتوي هذا على ميزة أنه عند المشاهدة بزاوية ، تحصل الحواف الموجودة في أقصى اليسار وأقصى اليمين على تمويه مرئي إلى حد ما:
image

لقد غيرتها إلى عددي. المسافة ، تمامًا كما في رمز دائري: return fwidth(distance) * 0.5; مع المسافة التي يتم تمريرها من troikaGetFragDistValue مثل هذا: float distance = troikaGetFragDistValue(); float aaDist = troikaGetAADist(distance);
عند القيام بذلك بهذه الطريقة ، لا أحصل على الأداة غير الواضحة:
image

يمكن زيادة العامل 0.5 للحصول على حواف أكثر سلاسة. على سبيل المثال ، 0.8 :
image

اعتقدت أنك ربما لم تكن على دراية بهذه الطريقة مثلي تمامًا ، لذلك اعتقدت أنني سأشاركها. بالرغم من ذلك ، فإن "التنفيذ" الخاص بي به بعض القطع الأثرية الغريبة (انظر أدناه) ، وربما هذا هو سبب اختيارك للطريقة الأخرى. أيضًا ، لست متأكدًا تمامًا من كيفية استخدامك لمتغير aaDist في كود التظليل ، لذلك قد تكون أفضل تجهيزًا لتنفيذ ذلك. ربما هناك بعض التعليمات البرمجية التي يجب تغييرها أو إزالتها بسبب هذا التغيير ، على سبيل المثال ، يمكن أن يؤدي ذلك إلى تحسين "التنفيذ" بشكل أكبر.

image

لقد وجدت هذه الطريقة للقيام بذلك في منشور bgolus هنا: https://forum.unity.com/threads/antialiasing-circle-shader.432119/ حيث توجد بعض المعلومات الإضافية. يقول أيضًا أنه يمكنك القيام بذلك على سبيل المثال length(vec2(dFdx(distance), dFdy(distance))) بدلاً من fwidth(distance) للحصول على دقة أكبر ، على الرغم من أنني لست متأكدًا مما إذا كان هذا ضئيلًا أم لا.

ال 7 كومينتر

شكرا على اقتراحك! سأبحث في هذا بالتأكيد ، حيث لاحظت تلك الحواف الباهتة بزوايا مائلة أيضًا وأود إزالتها.

من الناحية النظرية ، أعتقد أن كلاً من التغيير في distance والتغيير في vTroikaGlyphUV * vTroikaGlyphDimensions يجب أن يكونا متكافئين نظرًا لأن كلاهما يمثل مسافة في وحدات مساحة الخط ، ولكن يجب أن يكون هناك بعض الاختلاف الدقيق هناك. تجاهله. إذا كان بإمكاني تجنب القطع الأثرية التي أظهرتها ، فسأكون سعيدًا بدمج التغيير. :)

رائعة! التغيير بسيط مثل هذا السطر الواحد (وتمرير وسيطة المسافة هذه لاستيعابها). إذا كنت لا تزال ترغب في الحصول على الشفرة الأولية ، فيمكنني إرسالها عندما أعمل غدًا.

من الناحية النظرية ، أعتقد أن كلاً من التغيير في المسافة والتغيير في vTroikaGlyphUV * vTroikaGlyphDimensions يجب أن يكونا متساويين نظرًا لأن كلاهما يمثل مسافة في وحدات مساحة الخط

لا أفهم بالضبط كيف ستكون المشتقات متشابهة. أعتقد أن distance هي مسافة SDF ، لكن الآخر هو موضع للأشعة فوق البنفسجية. لم ألقي نظرة على الكود وكيف يقارنون ، لكن يبدو أن مشتقاتهم يجب أن تكون مختلفة. بقدر ما أعرف أن fwidth يأخذ فقط الاختلاف في قيمة الإدخال المحددة التي تم تمريرها كوسيطة مع نفس قيم الإدخال المحددة في الأجزاء المجاورة ، وهو أمر ممكن لأن الأجزاء المجاورة يتم تنفيذها في نفس الوقت بالتوازي. أجريت اختبارًا في وقت سابق اليوم باستخدام gl_FragColor.rgb = vec3(fwidth(gl_FragColor.x + gl_FragColor.g + gl_FragColor.b)); لمعرفة ما إذا كان قد أدى إلى ظهور حواف مثل اكتشاف الحواف / مرشح sobel ، لمحاولة تأكيد هذه الحقيقة قليلاً ، وقد حدث ذلك.

شكرا على المناقشة ، هذه الأشياء تكسر عقلي في بعض الأحيان. ؛)

عندما قلت إنهما "متكافئان" ، كنت أعني أنهما يمثلان مسافة في نفس الوحدات ، لكنك على حق أنهما ليسا متماثلان تمامًا.

النسخ الاحتياطي ، ما نريده هنا هو معدل التغيير المحتمل بين الأجزاء. غالبًا ما يكون استخدام التغيير في المتغير distance كما تقترح دقيقًا لذلك ، ولكن في بعض الحالات سيكون غير دقيق للغاية. وذلك لأن SDF الذي يتم أخذ عينات منه هذه القيمة هو _non-uniform_ ؛ ينحني ويغير اتجاه التغيير عبر الصورة الرمزية. لذلك فإن مشتق distance بين الأجزاء المتجاورة يمكن أن ينتهي به الأمر إلى أن يكون صغيرًا جدًا ، حتى صفر ، مثل المكان الذي يتحول فيه حقل المسافة من الزيادة إلى النقصان في منتصف المسافة بين مسارات الحروف الرسومية ، أو كبير جدًا ، كما هو الحال عند عرض النص بأحجام صغيرة وشبكة الشظايا تغطي قوات سوريا الديمقراطية في مواقع غير متوقعة. أظن أن هذا يفسر على الأقل بعض القطع الأثرية التي تراها.

إذًا كيف يمكننا تحديد معدل التغيير المحتمل بدون استخدام distance ؟ حسنًا ، إن "موضع الأشعة فوق البنفسجية المتدرج" كما تسميه هو في الأساس إحداثي x / y داخل مستطيل الصورة الرمزية ، باستخدام نفس الوحدات مثل distance . يعطينا مشتق x / y معدل انتقال محتمل بين الشظايا. بشكل عام ، هذا يعطي نتيجة أفضل من استخدام distance ، لأنه يعتمد على معدل تغيير موحد عبر الصورة الرمزية ، وبالتالي لا نحصل على القطع الأثرية وهي أكثر دقة في الأحجام الصغيرة.

ولكن ، كما رأيتم ، مكان الانهيار يكون عند زوايا مائلة ؛ في تلك الحالات ، يكون معدل التغير المحتمل x / y في الوضع الرأسي مختلفًا كثيرًا عن المعدل الأفقي. وهكذا ننتهي باستخدام قيمة واحدة لمعدل التغيير المحتمل تكون كبيرة جدًا في اتجاه واحد وصغيرة جدًا في الاتجاه الآخر ، مما يعطي خطوطًا ضبابية و / أو متقطعة اعتمادًا على اتجاه التغيير الفعلي لقوات الدفاع الذاتي عند هذا الجزء.

حسنًا ، هناك بالتأكيد مجال للتحسين في الحالة المائلة ، ولكن مجرد استخدام مشتق distance لا يكفي بحد ذاته. أنا منفتح على الأفكار لتحسين هذا بالطبع. قد يكون أحد الاحتمالات محاولة اكتشاف السيناريو (حجم نص كبير بزاوية مائلة ، بالقرب من المسار) واستخدام المشتق distance فقط في هذه الحالة الواحدة.

نعم ، هذه الأشياء محيرة للتفكير فيها ، هاها. أستطيع أن أرى مجال المسافة أقل سلاسة ، نعم.

قد تكون هذه البكسلات الجذابة بسبب الأجزاء الموجودة بها بعض قيم المسافة الغريبة.

إنها ليست متقطعة بشكل لا يصدق من بعيد ، ولكن يمكنك بالتأكيد رؤية الأشعة فوق البنفسجية تتحسن. ربما يعمل الاستيفاء بين متغير المسافة والأشعة فوق البنفسجية التي تعتمد على مسافة الكاميرا بشكل جيد ؛ مثل اختيار المزيد من fwidth (المسافة) عند الإغلاق ، والمزيد من fwidth (uv) عندما تكون بعيدة.

للمقارنة (لم تلتقط الاثنين في نفس موضع الكاميرا واتجاهها بالضبط ، لكنني أعتقد أنها تُظهر الفرق جيدًا على أي حال):
المسافة (عامل 0.8):
image
الزوار الفريدون:
image

ألاحظ أن هذا التعديل يحسن بشكل كبير نتيجة تحويلات النص المخصصة. إليك بعض النصوص المعدلة لتتبع منحنى باستخدام createDerivedMaterial ( انظر هذه التقنية ). يستخدم هذا تظليل ثلاثي نصوص ثلاثي الحالي:

image

هذه هي لقطة الشاشة نفسها ، ولكن مع تعديل asbjornlystrup إلى troikaGetAADist :

image

في اللقطة الثانية ، يمكنك رؤية "عظيم!" هش إلى حد ما.

من الروايات المتناقلة: لقد وجدت أيضًا أن تعديل الثابت إلى 0.25 (من 0.5) يجعل حافة واضحة لطيفة أيضًا:

return length(fwidth(vTroikaGlyphUV * vTroikaGlyphDimensions)) * 0.25;

شكرًا @ canadaduane ، يمكنني بالتأكيد رؤية التحسن في الأجزاء الممتدة. يمكنني أيضًا رؤية القطع الأثرية القبيحة تظهر هناك بين الحرفين L في HELLO ، والتي سنحتاج بالتأكيد إلى اكتشافها قبل اعتماد هذا التغيير.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات