Troika: مخطط النص

تم إنشاؤها على ٢٠ أغسطس ٢٠٢٠  ·  39تعليقات  ·  مصدر: protectwise/troika

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

شكرا!

التعليق الأكثر فائدة

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

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

ال 39 كومينتر

أشعر تقريبًا أنه ربما يتم تحقيق ما أحتاجه بواسطة علامة debugSDF ، إذا كان بإمكاني فقط تلوينها.
image
يعطيني عرض sdf أساسًا مخططًا قد يعمل على الأرجح إذا كان بإمكاني تلوينه وضبط الحجم وربما جعله أكثر هشاشة.

لا ينبغي أن يكون هذا صعبًا للغاية. لقد بدأت اللعب باستخدام textOutline كميزة منذ فترة ولكني لم أكملها مطلقًا.

من الناحية النظرية ، يمكن توسيع حواف الصورة الرمزية ببساطة عن طريق تغيير القيمة في حقل المسافة الموقعة الذي يتوافق مع الحافة. هذا هو 0.5 في كود التظليل الحالي ، ولكن يمكن جعله قابلاً للتكوين بتمريره كزي موحد.

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

لقد بدأت اللعب باستخدام textOutline كميزة منذ فترة ولكني لم أكملها مطلقًا.

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

عدت إلى هذا قليلاً وأدركت بسرعة لماذا لم أنتهي منه في الأصل. بينما يمكن استخدام SDF للتوضيح ، إلا أن هناك بعض المحاذير:

  • الحد الأقصى للعرض المحتمل للمخطط التفصيلي مقيد بمدى حقل المسافة نفسه (حوالي 8 تكسيل في نسيج 64 × 64 SDF).
  • لا يتوافق ذلك مع حجم مرئي ثابت عبر جميع الصور الرمزية ، حيث يتم تحجيم نسيج SDF وفقًا لحدود كل حرف رسومي.

لذا فإن الحروف الرسومية الأكبر مثل "W" يمكن أن تحصل على مخطط سميك لائق ، ولكن الصغيرة مثل الفترات يمكن أن تحصل فقط على مخطط رفيع للغاية. ويحتاج كل حرف رسومي إلى استخدام نقطة قطع مختلفة لقوات الدفاع الذاتي لجعل الخطوط العريضة متسقة بصريًا.

لا أعتقد أن هذا لا يمكن التغلب عليه حتى الآن ، لكنه ليس بهذه البساطة التي كنت أعتقدها في البداية.

lojjic ، أحب هذه المكتبة 🥇 ، لكن مخطط النص هو مطلب لمشروعنا ...

عدت إلى هذا قليلاً وأدركت بسرعة لماذا لم أنتهي منه في الأصل. بينما يمكن استخدام SDF للتوضيح ، إلا أن هناك بعض المحاذير:

  • الحد الأقصى للعرض المحتمل للمخطط التفصيلي مقيد بمدى حقل المسافة نفسه (حوالي 8 تكسيل في نسيج 64 × 64 SDF).
  • لا يتوافق ذلك مع حجم مرئي ثابت عبر جميع الصور الرمزية ، حيث يتم تحجيم نسيج SDF وفقًا لحدود كل حرف رسومي.

لذا فإن الحروف الرسومية الأكبر مثل "W" يمكن أن تحصل على مخطط سميك لائق ، ولكن الصغيرة مثل الفترات يمكن أن تحصل فقط على مخطط رفيع للغاية. ويحتاج كل حرف رسومي إلى استخدام نقطة قطع مختلفة لقوات الدفاع الذاتي لجعل الخطوط العريضة متسقة بصريًا.

لا أعتقد أن هذا لا يمكن التغلب عليه حتى الآن ، لكنه ليس بهذه البساطة التي كنت أعتقدها في البداية.

لدي فضول ، هل يمكننا إجراء نوع من المعالجة اللاحقة باستخدام التظليل لتحقيق مخطط تفصيلي و / أو تأثيرات الظل؟ شكرا مقدما!
هذا هو التأثير الذي أحاول تحقيقه:
Screen Shot 2020-08-31 at 4 32 03 PM

تحرير: هذا من mapbox gl ، أعتقد أنهم يستخدمون SDF أيضًا https://blog.mapbox.com/drawing-text-with-signed-distance-fields-in-mapbox-gl-b0933af6f817 ، ربما يمكننا تشريح الكود الخاص بهم لمعرفة ما فعلوه. https://github.com/mapbox/mapbox-gl-js

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

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

تُفضل العروض المعيارية أكثر بكثير من عروض القياس. سيتصرف مثل css بهذه الطريقة أيضًا.
يتم تكوين أي text-shadow يتم تطبيقه عبر css بشكل مستقل عن font-size .
إذا كان الحل الذي اقترحته lojjic يعمل بنفس الطريقة ، فسيكون ذلك 🎉 🎉 🎉

شكرا لاستجابتك السريعةlojjic!

الهدف هو إضافة التباين ، ويبدو اقتراحك رائعًا. هل تقصد أن المخطط سيكون ثابتًا؟ أي لا توجد طريقة للسيطرة عليها (كما وصف stephencorwin ، باستخدام نهج text-shadow-ish).

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

شكرا مقدما!

أعتقد أن اقتراحك يعني أن المخطط سيكون أرق بشكل مرئي على أجهزة DPI الأعلى ، أليس كذلك؟

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

الجانب السلبي الكبير الآخر هو (أعتقد) أن زيادة سماكة الهالة سيكون لها تأثير على الأداء بسبب طلب المزيد من قراءات النسيج. أنا بحاجة لمواصلة البحث عن هذا بالرغم من ذلك.

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

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

شكرا لمساهمة @ FunMiles. (كولورادو تمثل! 😄)

أعتقد أنك ربما تكون على حق في الخطوط العريضة المكونة من 1 أو 2 شظية بسمك. ما يقلقني هو أنه مع زيادة السماكة ، يؤدي ذلك إلى انفجار عدد قراءات النسيج (سمك 4 = 56 قراءة؟) بالإضافة إلى احتمال أن تكون هذه القراءات أكثر تكلفة. لكنني فقط أتوقع بناءً على قراءة بعض الأشياء ، لست خبيرًا في وحدات معالجة الرسومات بأي حال من الأحوال. ربما سأضطر فقط إلى تجربته.

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

تقرأ الآن مسافة قياسية للبكسل بـ texture2D(uTroikaSDFTexture, vTroikaSDFTextureUV).r; . إذا كنت أفهم ما كتبته من قبل ، فهناك مشكلة تتعلق بالمساحة حول الصور الرمزية. هل يمكنك التوضيح بمزيد من التفاصيل؟
بالعودة إلى مثالك عن "W" و "،" هل امتداد vTroikaSDFTextureUV في النسيج مناسب تمامًا حول الصورة الرمزية ، أم أن هناك مساحة إضافية؟ هل يعرف تظليل الأجزاء حدود الأشعة فوق البنفسجية للصورة الرمزية الحالية؟ إذا حدث ذلك ، فبالنسبة للجزء الذي يقع في الخارج ، يمكنك عرض الأشعة فوق البنفسجية الحالية على الحدود والانتقال لقراءة البيانات الموجودة بالداخل مباشرةً.

أعتقد أنه من الممكن معرفة ما هو مطلوب بحد أقصى 5 قراءات texel أو باستخدام المشتقات (أرى أنك تتحقق مما إذا كانت متوفرة).

بالعودة إلى مثالك عن "W" و "،" هل امتداد vTroikaSDFTextureUV في النسيج مناسب تمامًا حول الصورة الرمزية ، أم أن هناك مساحة إضافية؟

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

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

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

سأكون ممتنًا إذا كنت تعرف طريقة للحصول على مخططات أكثر سمكًا بقراءات أقل من texel! لقد كنت أفهمها على النحو التالي: بالنسبة لجزء ليس داخل مسار الصورة الرمزية ، قم بإجراء بحث شعاعي لمعرفة ما إذا كانت هناك أجزاء داخل r =سوف تقع داخل مسار الصورة الرمزية. قد تكون هذه مجرد طريقة خاطئة للتفكير في الأمر.

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

ما أفهمه هو أن قيم vTroikaGlyphUV لها قيم مثبتة بين 0 و 1 عندما تكون داخل الصورة الرمزية. ما قصدته عندما تحدثت عن الإسقاط هو أنه إذا كان vTroikaGlyphUV خارج هذه الحدود ، يمكنك استرداد مسافة النقطة "المسقطة" على حدود الصورة الرمزية. أي ، إذا كانت uv = (1.05 ، 0.7) ، فإن النقطة المتوقعة هي (1.0 ، 0.7). باستخدام القيم الموجودة في (1.0 ، 0.7 + إبسيلون) و (1.0 ، 0.7-إبسيلون) ، يمكنك استرداد التدرج اللوني للمسافة واستخدام ذلك ، لحساب المسافة التقريبية عند (1.05 ، 0.7).
عندما قمت بعملي الخاص من أجل هذا ، أتذكر أنني قرأت مقالًا عن شخص يقوم بعمل SDF مع تدرج في النسيج أيضًا. يتجنب هذا الأسلوب الاضطرار إلى قراءة ثلاث نسخ ، ولكنه يجعل النسيج مكونًا من 3 مكونات ويضيف تعقيدًا لبناء النسيج.

هل هذا يجيب علي سؤالك؟

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

ملاحظة: ربما أساء فهم "مساحة إضافية حول حدود المسار الحقيقي لكل حرف رسومي". هل تقول أن X ، على سبيل المثال ، مغلف في مستطيل وأن هناك أربعة مثلثات ليس لها قيم صحيحة؟

FunMiles I _think_ ربما أرى إلى أين أنت ذاهب. سأحتاج إلى بعض الوقت للتفكير مليًا في الأمر ، ولكن لدي موعد نهائي آخر أحتاج إلى التركيز عليه في الوقت الحالي.

ملاحظة: القليل من المرح ملاحظة الرياضيات:
فقط في حالة ما إذا تساءل شخص ما كيف يمكن الحصول على التدرج اللوني من نقطتين أو ثلاث نقاط متوائمة ، على المرء أن يتذكر أن تدرج المسافة له قاعدة ثابتة (اعتمادًا على المقياس المختار). ويشير التدرج بالتأكيد نحو الخارج لمربع الصورة الرمزية. على سبيل المثال ، إذا كانت جميع النقاط الثلاث للمثال (1.0 ، 0.7) ، (1.0 ، 0.7 + إبسيلون) و (1.0 ، 0.7-إبسيلون) على نفس المسافة ، فإن التدرج هو (مقياس ، 0).

على الرغم من أنه غير مؤدٍ بالتأكيد ، إلا أنه من الممكن استخدام التعويضات. أنا أستخدم react-three-fiber ، والذي يستفيد من نص الترويكا مع حزمة drei ، لكنني أعتقد أنني سأشاركه في حال كان الآخرون يبحثون عن حل مؤقت حتى تدعم المكتبة السكتة الدماغية بشكل أصلي:

import React from 'react';
import {Text} from 'drei';

const StrokedText: React.FC<
  {
    strokeWidth?: number;
    strokeColor?: string;
    strokeResolution?: number;
    bold?: boolean;
  } & any
> = ({
  strokeWidth = 1,
  strokeColor: color = '#000000',
  strokeResolution = 100,
  position,
  bold,
  ...props
}) => {
  const font = bold ? FONTS.BOLD : undefined;
  const sharedProps = {
    ...props,
    font,
    color,
    sdfGlyphSize: 12,
    debugSDF: true,
  };

  let zOffset = 0;
  const offset = () => (zOffset += 0.001);

  return (
    <group name="Stroked Text" position={position}>
      {Array(strokeWidth)
        .fill({})
        .map((_, i) => {
          const s= i / strokeResolution;
          return (
            <React.Fragment key={i}>
              {/* <Text {...sharedProps} position={[-s, 0, offset()]} />*/}
              {/* <Text {...sharedProps} position={[s, 0, offset()]} />*/}
              <Text {...sharedProps} position={[0, -s, offset()]} />
              <Text {...sharedProps} position={[0, s, offset()]} />
              <Text {...sharedProps} position={[-s, -s, offset()]} />
              <Text {...sharedProps} position={[s, s, offset()]} />
              {/* <Text {...sharedProps} position={[-s, s, offset()]} /> */}
              {/* <Text {...sharedProps} position={[s, -s, offset()]} /> */}
            </React.Fragment>
          );
        })}
      <Text name="Text" {...props} position={[0, 0, strokeWidth ? offset() : 0]} />
    </group>
  );
};

export default StrokedText;

ثم في مكان آخر ، يمكنني تسميته بـ <StrokedText /> بدلاً من <Text /> عادةً:

<StrokedText
  color="#ffffff"
  fontSize={fontSize}
  clipRect={[-0.5, -0.15, 0.5, 0.15]}
  textAlign="center"
  position={[0, 0, 0.01]}
>
  {text}
</StrokedText>

image

FunMiles لقد أتيحت لي أخيرًا بعض الوقت لتحليل اقتراحاتك. أعتقد أن هذا سيكون منطقيًا بافتراض أن مجمل مستطيل SDF الخاص بالحرف الرسومي يحتوي على قيم مسافة مفيدة (> 0.0). هذا ليس هو الحال حاليا. أعتقد أنك كنت تدرك ذلك في متابعتك حول "x" ، حيث تنخفض SDF إلى الصفر داخل حدود الرباعية ، لذلك هناك مناطق مهمة لا يوجد فيها تدرج مسافة مفيد يمكن استقراء منه:

image

ربما يمكنني النظر في تغيير مولد SDF لضمان تدرج غير صفري عبر الرباعية بالكامل ...؟ التفكير بصوت عالٍ ، يمكن أن يكون له دلالات على دقة المسافة ، ويمكن أن يقدم القطع الأثرية بين الشخصيات داخل نسيج الأطلس ... 🤔

ربما يمكنني النظر في تغيير مولد SDF لضمان تدرج غير صفري عبر الرباعية بأكملها

لقد جربت ذلك ، ونعم ، فهو يسمح باستقراء مجال المسافة خارج الحدود الرباعية ، ولكن كما كنت أخشى أنه يقلل من جودة الصورة الرمزية نفسها بشكل كبير. هذا أمر متوقع مع تدرج 8 بت فقط ؛ يؤدي نشرها على مسافة أكبر إلى دقة أقل في كل texel. :(

ربما يمكنني إنشاء SDF منفصل للخطوط العريضة فقط - مجال واسع الانتشار ولكن أقل دقة - مشفر في قناة نسيج ثانية. سوف يضاعف حجم النسيج ولكن لا ينبغي أن يكون أبطأ بكثير. 🤔

مشفرة في قناة نسيج ثانية.

lojjic يبدو ذلك معقولًا للغاية ويحاكي الحل البديل الآن. بالإضافة إلى ذلك ، يمكن أن يكون قابلاً للاشتراك ، لذلك لا توجد نتيجة مثالية إذا لم يطلب المستخدم الخطوط العريضة.

lojjic من شأن نهج التقيد الذي اقترحه stephencorwin التأكد من عدم دفع أي شخص أكثر مما هو مستعد للدفع.

العودة إلى الجانب التقني. لنأخذ صورة X في إجابتك. هل أفهم بشكل صحيح أنه بالنسبة لجميع الحروف الرسومية ، تبلغ 64 × 64 بكسل؟ مع 8 بتات ، إذا كان عليك ترميز مساحة المسافة بالكامل ، فهذا يعني أن لديك دقة 2 بتات جزئية. أعتقد أنك تذكر أن هذه الدقة ليست كافية.

ربما تكون هناك خدعة لاستخدامها لاكتساب الدقة بتكلفة قليلة جدًا. بدلاً من عمل شبكة 64x64 من 8 بت ، قم بضغط بيانات 2x2 كتل في بيانات 32 بت. تتمثل إحدى السمات الواضحة للمسافة الموقعة بين وحدتي بكسل في أنها دائمًا في نطاق [-1،1] يمينًا ويسارًا ، ولأعلى ولأسفل و [-sqrt (2)، sqrt (2)] قطريًا. لذا تخيل أنك تستخدم 12 بتًا لـ SD لمركز الكتلة 2x2 ، سيكون لديك 5 بت لكل مركز من وحدات البكسل لترميز الفرق بين مركزها ومركز 2x2. تمثل هذه البتات الخمسة على الأكثر مربعًا (2) / 2 مسافة. بشكل فعال لديك دقة 5.5 بت.
تقوم النقطة المركزية 12 بت بتشفير 6 بتات على الأقل من الدقة على مسافة 64 كحد أقصى. من الناحية الفنية ، إذا كان الصندوق يحتوي على نقطة واحدة فقط في الزاوية ، فستحتاج 12 بت إلى أن تكون قادرة على تشفير ما يصل إلى sqrt (2) * 64 ، ولكن لا أعتقد أن هذا ممكن في الواقع لأن الصندوق من المفترض أن يتمحور بشكل معقول حول كل حرف رسومي. في الواقع ، كلما ابتعدت عن أي حافة رمزية وكلما قلت المعلومات التي يتعين على الدلتا تشفيرها ، (عندما تكون بعيدًا عن حافة الصورة الرمزية ، يصبح حقل التدرج متماثلًا تقريبًا في الجوار) لذا من منظور نظرية المعلومات ، يكون كذلك ممكن لتحسين الترميز
للحصول على مزيد من المعلومات الفعلية .... لكنني لن أبدأ بمثل هذا التحسين الإضافي.

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

إذا كنت بحاجة إلى مساعدة ، يمكنني تنفيذ تشفير / فك تشفير كل هذا.

ملاحظة: لدي ذكرى رؤية مناقشة في أحد ملفات README.md حول SDF أكثر تطوراً. هل حلمت به؟ 😛 هل يمكن لأي شخص أن يوجهني إليه مرة أخرى لمعرفة ما إذا كان هذا النظام الآخر يمكنه المساعدة هنا؟

FunMiles فكرة ضغط ذكية جدا. سأضع ذلك في الاعتبار إذا فشلت الخيارات الأخرى. إن فقدان الاستيفاء الخطي بواسطة الأجهزة هو مقايضة لا أفضل القيام بها. 😉

لقد خطر لي أن مشكلتي في عدم وجود وحدات بت كافية تتفاقم باستخدام 0.5 كمسافة "صفر" ، لذا فإن نصف قيم ألفا فقط متاحة لتشفير المسافة _ خارج_ الصورة الرمزية. يمكنني تغيير ذلك لاستخدام المزيد من القيم للمسافات الخارجية وأقل للمسافات الداخلية ، واكتساب بعض الدقة على الأطراف.

يكرر. "SDF أكثر تعقيدًا" ، قد تعني "MSDF" حيث يتم استخدام قنوات ملونة متعددة؟

FunMiles فكرة ضغط ذكية جدا. سأضع ذلك في الاعتبار إذا فشلت الخيارات الأخرى. إن فقدان الاستيفاء الخطي بواسطة الأجهزة هو مقايضة لا أفضل القيام بها. 😉

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

سيكسبك ذلك بت واحد على الأكثر من الدقة. لا يعطس في ولكن لا تزال مهمة.

يكرر. "SDF أكثر تعقيدًا" ، قد تعني "MSDF" حيث يتم استخدام قنوات ملونة متعددة؟
هذا ما قصدته. لقد وجدت مشروع GitHub حوله في C ++. هل كان لديك شيء لاستخدامه أو هل شعرت بالارتباك ، وخلطت أشياء مختلفة بحثت عنها قبل أسبوعين؟

بالمناسبة ، لا أعتقد أن منظمة أطباء بلا حدود ستساعد.
هل يمكنني أن أسأل ما إذا كان يمكن أن يكون لديك ملف .md صغير يشرح كيفية إنشاء SDF في JavaScript؟ مع ذلك ، أعتقد أنه يمكنني إنشاء رمز لتنفيذ فكرة الضغط الخاصة بي.

تم بناء SDF هنا: https://github.com/protectwise/troika/blob/master/packages/troika-three-text/src/worker/SDFGenerator.js#L134 - ليس كثيرًا لشرح ذلك ، في الغالب تعيين texels إلى وحدات الخط وكتابة المسافات المقاسة في قيم texel. سيتعين علينا إضافة بعض قياسات المسافة الإضافية هناك لنقطة المنتصف لكل كتلة 2 × 2.

محاولة لف عقلي بالكامل حول هذا ... يبدو تكرار الاستيفاء ثنائي الخطوط في GLSL بسيطًا / رخيصًا بدرجة كافية ، بمجرد أن يكون لديك أقرب 4 قيم. للحصول على هذه القيم عندما يتم ترميزها باستخدام نظام الضغط الخاص بك ، أعتقد أنها ستشمل:

  • إذا كانت بالضبط في وسط texel: إما 2 أو 3 عينات نسيج
  • إذا كان بين 4 texels من كتلة 2x2: 4 عينات نسيج
  • إذا كان بين كتلتين متجاورتين: ~ 9 عينات نسيج ~ إما 7 أو 8 عينات نسيج
  • إذا كان بين أربع كتل متجاورة: ~ 11 عينة نسيج ~ 13 عينة نسيج

هل أنا أتذمر بشكل صحيح؟

أوه ، انتظر ، كنت لا أزال أفكر في نسيج أحادي القناة. باستخدام أربع قنوات rgba ، تكون كل كتلة بيانات قراءة واحدة فقط. حتى 4 عينات نسيج على الأكثر.

لقد بدأت في قراءة SDFGenerator.js. سوف أنظر إليها أكثر.

لا أعتقد أنك بحاجة إلى أكثر من قراءة texel واحد لكل جزء ، إلا إذا كنت ترغب في تحسين مزج ألفا لحالات الزاوية حيث قد تكون في نقطة محاطة بحواف الصورة الرمزية من جميع الجوانب. تحتاج فقط إلى أقرب مركز للكتلة 2 × 2 حيث يوجد مركز الجزء.
ومع ذلك ، أدرك أنه قد تكون هناك صعوبة لم أتوقعها ... WebGL 1.0 محدود للغاية فيما يقدمه والذي سيكون مفيدًا هنا: لا يوجد عدد صحيح بدون إشارة من النوع uint ولا حتى الأعداد الصحيحة 32 بت! 🤯 وليس هناك عملية أحاديّة ... لذا فإن الضغط الذي أقترحه يكون أكثر صعوبة في الكتابة باستخدام أعداد صحيحة 16 بت.

كل هذه متوفرة في WebGL 2.0 لكنني أفترض أننا نريد استهداف WebGL 1.0 هنا؟

كل هذه متوفرة في WebGL 2.0 لكنني أفترض أننا نريد استهداف WebGL 1.0 هنا؟

أعتقد أنه قد يكون من المعقول قصر مخطط النص على webgl 2 واكتشاف ما إذا كان المستخدم لديه توافق المتصفح هذا. على الرغم من أنني أستطيع أن أفهم أنه من المحتمل القيام بإصدار webgl 2 الأمثل مع احتياطي webgl 1. Imo يمكننا أن نبدأ بـ webgl 2 ونترك ذلك ممتعًا مع المجتمع قبل محاولة دعم كليهما على الفور.

أعتقد أن لدي طريقة بديلة للتغلب على مشكلة الدقة ، لذلك لا تقلق FunMiles بشأن القتال مع عناصر الضغط في الوقت الحالي.

مرحبا lojjic ، فقط تحقق في هذا. أي تقدم أو أشياء يمكننا المساعدة فيها؟

ملاحظة جانبية: يقترب Safari أخيرًا لدعم WebGL2 ، لذلك قد يكون من الممكن عدم دعم WebGL1 لهذه الميزة.

تنفيذ WebGL2 الخاص بنا في حالة جيدة بما يكفي بحيث يجب علينا تمكينه افتراضيًا للاختبار على نطاق أوسع.
https://trac.webkit.org/changeset/267027/webkit

لدي جهاز iPhone 6 لن يكون عليه WebGL 2.0

ومن المثير للاهتمام ، أن WebGL 1.0 يحدد متطلبات أسوأ مما كنت أعتقد. الأعداد الصحيحة غير موجودة بالفعل:

4.1.3 عدد صحيح
يتم دعم الأعداد الصحيحة بشكل أساسي كوسيلة مساعدة في البرمجة. على مستوى الأجهزة ، سوف تساعد الأعداد الصحيحة الحقيقية
التنفيذ الفعال للحلقات ومؤشرات الصفيف ، والإشارة إلى وحدات النسيج. ومع ذلك ، لا يوجد
شرط أن الأعداد الصحيحة في اللغة تتناسب مع نوع عدد صحيح في الأجهزة. لا يتوقع ذلك
الأجهزة الأساسية لديها دعم كامل لمجموعة واسعة من عمليات عدد صحيح. تظليل OpenGL ES
قد يؤدي تطبيق اللغة إلى تحويل الأعداد الصحيحة إلى أعداد عائمة للعمل عليها. وبالتالي ، لا يوجد محمول
سلوك الالتفاف.

ومع ذلك لم أفقد الأمل. لا بد لي من إعادة التفكير قليلاً ...
في غضون ذلك ، lojjic ، هل تمانع في إخبارنا ما هو النهج البديل الذي فكرت فيه؟

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

لقد أثبتت ذلك باستخدام مقياس خطي من مستويين ومقياس أسي. كلاهما لديه إيجابيات وسلبيات.

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

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

لست متأكدًا مما تقصده بـ "خارج الزوايا". هل تقصد المستويات الربعية المتجذرة في كل زاوية ، حيث يكون أقرب إسقاط هو الزاوية نفسها؟ أعتقد أنه يمكنك استخدام القاعدة على الحافة على كل من الحافة الرأسية والأفقية وعمل متوسط ​​مرجح بناءً على المسافة إلى كل منهما.

ملاحظة: خطرت لي فكرة تقليل الدقة بعيدًا في وقت سابق اليوم بعد قراءة هراء عدد صحيح لـ WebGL ... ما زلت آمل أن يتم تنفيذ تقنية الضغط في WebGL 1.0 للحصول على 11 بت من الدقة بثمن بخس وقليل المزيد من البتات مع المزيد من الاختبارات. على سبيل المثال ، باستخدام rgba ، يمكن أن يحتوي a على 8 بت من المتوسط ​​، ثم لكل من rgb ، سيتم توقيعهم وستمثل العلامة 1 بت لكل من الدقة المتوسط ​​، ثم أخيرًا الباقي ، والذي سيكون في النطاق 0-127 ، سيتم طرح القيمة 64 لتمثيل 7 بتات لـ 3 من القيم الأربع المطلوبة. ستكون القيمة الفعلية لهذا المركز (تتراوح من 0 إلى 2 ^ 11-1) + dist_i. سيتم استرداد القيمة الرابعة بإجراء مطروح منها مجموعها ، حيث يجب أن يكون المجموع هو المتوسط. سيحصل المرء على 11 بتة فقط ، لكن هذا ربما يكون كافياً. للحصول على المزيد من البتات ، سيتطلب الأمر اختبار ما إذا كانت القيمة أو r ، g ، و b أصغر من -64 ، موجب أو سلبي ، أكبر من 64. سيكون ذلك أساسًا أعط 14 بتًا للمركز و 6 بتات فقط للاختلافات. ربما حل وسط جيد؟ سأحتاج إلى اختبار أن الضمانات المتساهلة للغاية التي يضعها WebGL 1.0 على الدقة لن تتداخل مع هذا التفكير ...

نعم ، هذا ما قصدته ، المناطق التي يقع فيها كل من U و V خارج 0-1. شكرًا ، سأعطي ذلك فرصة.

lojjic كسؤال جانبي ، في منشور سابق ، بدا أنك قلق بشأن وجود قيمتين للنسيج لكل نسخة من SDF بسبب الذاكرة. على الرغم من أنني أفضل تقليل الذاكرة ، فإن 256 حرفًا رمزيًا على شبكة 64 × 64 تستهلك فقط 1/4 ميجابايت من ذاكرة النسيج. أعلم أن بعض اللغات قد تتطلب العديد من الحروف الرسومية ، لكن بي بي سي تقول إنه لقراءة الصحيفة ، هناك حاجة فقط إلى 2000/3000 حرف. لذا فإن 4000 حرف ستجعل 4 ميغا بايت مع بايت واحد لكل texel SDF. يستحق القلق؟

FunMiles Fair point ، ولم أكن قلقًا جدًا بشأن ذلك.

بقي بعض الأعمال المعلقة ، ولكن b19cd3aff4b0876253d76b3fc66b7e2a1f16a7e5 يعمل على إصلاح هذه المشكلة. بالنسبة لأولئك الذين يستخدمون الألياف ثلاثية التفاعل ، فقد تم إصدار هذا في drei v2.2.0
https://github.com/pmndrs/drei/pull/156

أعلم أن هذا مغلق ولكن أود أن أقول شكرًا على العمل. حصلت عليه للعمل في تطبيقي. استغرق الأمر بعض الشيء في معرفة أن الخصائص لن تقبل مجرد رقم لحجم المخطط التفصيلي. لكن النتيجة هي فقط ما احتاجه.
Screen Shot 2020-11-09 at 7 44 52 PM

تضمين التغريدة يجب أن تكون قادرًا على استخدام قيمة رقمية لـ outlineWidth ، لذلك إذا لم يكن ذلك مناسبًا لك لسبب ما ، فأعلمني بذلك.

وشكرا لك على مساهمتك على طول الطريق. ما زلت غير قادر على الحصول على استقراء سلس للمسافة خارج الحدود الرباعية باستخدام نوع التقنية التي ذكرتها ، لذا فإن المخطط السميك يحتوي حاليًا على أجزاء متكتلة في الزوايا على وجه الخصوص ، لكنه جيد بما يكفي لمعظم الحالات (حتى ~ 10٪ حجم الخط). أنا بالتأكيد منفتح لمحاولة تحسين ذلك.

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