فهم three-mesh-bvh: كيف يتعامل Three.js مع النماذج ثلاثية الأبعاد الضخمة بسرعة أكبر

عند العمل مع الأبعاد الثلاثية على الويب تظهر مشكلة بسرعة: كيف نتفاعل مع نماذج ثلاثية الأبعاد معقدة دون أن ينهار الأداء؟

قد يحتوي عارض منتج بسيط على آلاف المثلثات، بينما قد يحتوي نموذج CAD أو توأم رقمي أو بيئة لعبة أو مشهد معماري على ملايين.

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

ما هي BVH؟

BVH اختصار لـ Bounding Volume Hierarchy: بنية تسريع مكانية تنظّم الهندسة في شجرة من الصناديق المحيطة. بدل فحص المثلثات واحدًا تلو الآخر، تبني BVH تسلسلًا هرميًا:

               Model
                 |
       ---------------------
       |                   |
     Area A              Area B
       |                   |
   ---------           ---------
   |       |           |       |
Triangle Triangle  Triangle Triangle

يمكن للنظام الآن تجاهل أجزاء كبيرة من النموذج بسرعة وفحص المنطقة المهمة فقط.

فكّر في البحث عن كتاب في مكتبة. دون تنظيم تفحص كل الكتب. ومع التنظيم — القسم ← الرف ← الكتاب — تصل أسرع بكثير.

ما هي three-mesh-bvh؟

three-mesh-bvh هي تنفيذ لـ BVH مصمم خصيصًا لشبكات Three.js، وتحسّن:

  • الـ Raycasting
  • كشف التصادم
  • الاستعلامات المكانية
  • حساب أقرب نقطة
  • اختبارات تقاطع الهندسة

يصفها المشروع نفسه بأنها: «تنفيذ لـ BVH لتسريع الـ Raycasting وتمكين الاستعلامات المكانية على شبكات three.js».

لماذا يكون الـ Raycasting العادي بطيئًا؟

raycaster.intersectObject(mesh) مفيد جدًا، لكن الشبكة مكوّنة من مثلثات. في نموذج معقد من 500,000 مثلث يفحص الشعاع المثلث 1 ثم 2 ثم 3… حتى المثلث رقم 500,000.

هذا مقبول للكائنات الصغيرة، لكنه مكلف لنماذج BIM وملفات CAD والتوائم الرقمية والبيئات الكبيرة. تغيّر BVH استراتيجية البحث.

مثال بسيط في Three.js

دون BVH:

const raycaster = new THREE.Raycaster();
const hits = raycaster.intersectObject(mesh);

مع three-mesh-bvh:

import { MeshBVH, acceleratedRaycast } from "three-mesh-bvh";

geometry.boundsTree = new MeshBVH(geometry);
THREE.Mesh.prototype.raycast = acceleratedRaycast;

const raycaster = new THREE.Raycaster();
raycaster.firstHitOnly = true;

const hits = raycaster.intersectObject(mesh);

الآن لا يبحث الشعاع في الهندسة كلها — بل يستخدم شجرة BVH ليجد الإجابة أسرع بكثير.

تشبيه من الواقع

عندما تبحث في خرائط Google عن «مطاعم بالقرب مني»، لا تفحص كل مطاعم العالم، بل تستخدم فهارس مكانية: العالم ← الدولة ← المدينة ← الحي ← المطعم. تفعل BVH شيئًا مشابهًا مع الهندسة ثلاثية الأبعاد، وتجيب عن أسئلة مثل:

  • أي جزء من النموذج تحت الفأرة؟
  • أين أصاب الشعاع؟
  • ما أقرب سطح؟
  • هل يتصادم هذا الكائن مع كائن آخر؟

استخدامات شائعة في Three.js

1. عارضات النماذج الكبيرة

عارضات العمارة وتطبيقات BIM وعارضات CAD والتوائم الرقمية تحتوي غالبًا على مئات الآلاف أو الملايين من المثلثات. تحافظ BVH على سلاسة التفاعل.

2. Raycasting متقدم

تحديد الكائنات، وتأثيرات التمرير، والرسم على الأسطح، وأدوات القياس — أي العثور على المثلث الدقيق تحت الفأرة.

3. كشف التصادم

تحتاج الألعاب والمحاكاة إلى سؤال «هل تلمس الشخصية البيئة؟». بدل فحص كل مضلع، تضيّق BVH نطاق البحث بسرعة.

4. الفيزياء والمحاكاة

يمكن لـ BVH تسريع الاستعلامات الهندسية المستخدمة في محركات الفيزياء ومعالجة الهندسة والحسابات المكانية.

5. Path Tracing والعرض المتقدم

BVH مفهوم أساسي في تتبع الأشعة. تستخدم أنظمة العرض الحديثة بنى التسريع لأن إطلاق الأشعة على كل مثلث مستحيل على نطاق واسع.

إمكانات أخرى

لا تقتصر المكتبة على الـ Raycasting: هناك استعلامات أقرب نقطة، وتقاطع الكرة، وتقاطع الصندوق، وتقاطع الهندسة، وShape Casting.

const result = geometry.boundsTree.closestPointToPoint(point, target);

ويجيب هذا عن: «ما النقطة على هذه الشبكة الأقرب إلى موضعي؟»

المزايا

  • الأداء: تحسّن كبير للشبكات المعقدة. يمكن لمشهد بطيء مع الـ Raycasting العادي أن يصبح تفاعليًا.
  • يعمل مع سير عملك الحالي: يتكامل مع Mesh وBufferGeometry وRaycaster دون الحاجة إلى تغيير أداة العرض.
  • يتيح تفاعلات متقدمة: الرسم ثلاثي الأبعاد، وقياسات CAD، وأدوات تحرير الشبكات، وأنظمة التصادم.

القيود

  • ذاكرة إضافية: تنشئ BVH بنى بيانات إضافية. أداء أعلى يعني ذاكرة أكثر.
  • وقت البناء: يستغرق إنشاء الشجرة وقتًا، ما يضيف كلفة عند البدء للنماذج الضخمة.
  • الهندسة المتغيرة أصعب: تعمل BVH بأفضل شكل مع الهندسة الثابتة. إذا تغيّرت الرؤوس في كل إطار تصبح BVH قديمة وتحتاج إلى إعادة بناء أو Refit.

متى تستخدم three-mesh-bvh؟

عندما يحتوي تطبيقك على نماذج ثلاثية الأبعاد كبيرة، أو Raycasting معقد، أو عارضات CAD/BIM، أو هندسة تفاعلية، أو استعلامات فيزياء وتصادم، أو تجارب WebGL متقدمة. لمكعب دوّار بسيط على الأرجح لا حاجة لها؛ ولنموذج من مليون مثلث فهي شبه ضرورية.

الخلاصة

جعل Three.js الأبعاد الثلاثية على الويب متاحة، لكن الأداء هو التحدي التالي. تُظهر three-mesh-bvh مبدأً مهمًا في رسومات الحاسوب:

أسرع عملية حسابية غالبًا هي العملية التي تتجنب القيام بها.

بدل السؤال «كيف نعالج مثلثات أكثر؟»، تسأل BVH «كيف نتجنب النظر إلى المثلثات غير المهمة؟» — وهذه الفكرة من أسس التطبيقات ثلاثية الأبعاد التفاعلية الحديثة.

مصادر: مثال Raycasting مع BVH في three.js · three-mesh-bvh على npm