صمِّم تطبيقًا للواقع المعزّز باستخدام WebXR Device API.

1. قبل البدء

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

استخدام WebXR Device API التي تجمع بين وظائف الواقع المعزّز والواقع الافتراضي يمكنك التركيز على إضافات الواقع المعزّز لواجهة برمجة التطبيقات WebXR Device API لإنشاء تطبيق واقع معزّز بسيط يعمل على الويب التفاعلي.

ما هو الواقع المعزّز؟

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

أصبح الواقع المعزّز مستخدمًا على نطاق واسع في التطبيقات بعد إصدار ARCore من Google وARKit من Apple، سواء كان ذلك لفلاتر الصور الذاتية أو الألعاب المستندة إلى الواقع المعزّز.

ما ستُنشئه

في هذا الدليل التعليمي حول البرمجة، يمكنك إنشاء تطبيق ويب يضع نموذجًا في العالم الحقيقي باستخدام الواقع المعزّز. سينفّذ تطبيقك ما يلي:

  1. استخدام أدوات الاستشعار في الجهاز المستهدَف لتحديد موقعه واتجاهه في العالم وتتبُّعه
  2. عرض تصميم ثلاثي الأبعاد مركّب في أعلى شاشة عرض مباشر للكاميرا
  3. تنفيذ اختبارات الارتطام لوضع العناصر فوق مساحات العرض المكتشفة في العالم الحقيقي

المُعطيات

  • كيفية استخدام WebXR Device API
  • كيفية ضبط مشهد أساسي للواقع المعزّز
  • كيفية العثور على سطح باستخدام اختبارات الارتطام في الواقع المعزّز
  • كيفية تحميل نموذج ثلاثي الأبعاد وعرضه بشكل متزامن مع خلاصة الكاميرا في العالم الحقيقي
  • كيفية عرض الظلال استنادًا إلى التصميم الثلاثي الأبعاد

يركز هذا الدرس التطبيقي على واجهات برمجة التطبيقات لواقع الواقع المعزّز. يتم تجاهل المفاهيم ومجموعات الرموز غير ذات الصلة، ويتم توفيرها لك في رمز المستودع المقابل.

المتطلبات

انقر على تجربة على جهاز الواقع المعزّز لتجربة الخطوة الأولى من هذا الدليل التعليمي. إذا ظهرت لك صفحة تتضمّن رسالة تفيد بأنّ "متصفّحك لا يتضمّن ميزات الواقع المعزّز"، تأكَّد من أنّه تم تثبيت "خدمات Google Play للواقع المعزّز" على جهاز Android.

2. إعداد بيئة التطوير

تنزيل الرمز

  1. انقر على الرابط التالي لتنزيل كل الرموز البرمجية لهذا الدرس التطبيقي حول الترميز على محطة عملك:

  1. فكِّ ضغط ملف ZIP الذي تم تنزيله. يؤدي ذلك إلى فك ضغط مجلد جذر (ar-with-webxr-master) يحتوي على أدلة لعدة خطوات من هذا الدليل التعليمي للترميز، بالإضافة إلى جميع الموارد التي تحتاج إليها.

يحتوي المجلدان step-03 وstep-04 على الحالة النهائية المطلوبة للخطوتَين الثالثة والرابعة من هذا الدليل التعليمي حول الرموز البرمجية، بالإضافة إلى نتيجة final. وهي مخصّصة للرجوع إليها.

يمكنك تنفيذ جميع أعمال الترميز في دليل work.

تثبيت خادم الويب

  1. يمكنك استخدام خادم الويب الخاص بك. يوضّح هذا القسم بالتفصيل كيفية إعداد "خادم الويب" في Chrome إذا لم يسبق لك إعداده.
    إذا لم يكن هذا التطبيق مثبَّتًا على محطة العمل بعد، يمكنك تثبيته من "سوق Chrome الإلكتروني".

  1. بعد تثبيت تطبيق الويب الخاص بتطبيق Chrome، انتقِل إلى chrome://apps وانقر على رمز "خادم الويب":

رمز خادم الويب

سيظهر لك مربع الحوار هذا بعد ذلك، والذي يتيح لك ضبط خادم الويب المحلي:

ضبط Chrome Web Server

  1. انقر على اختيار مجلد واختَر مجلد ar-with-webxr-master. ويتيح لك ذلك عرض عملك قيد التقدم من خلال عنوان URL المظلل في مربّع حوار خادم الويب (في قسم عناوين URL لخادم الويب).
  2. ضمن الخيارات (تتطلّب إعادة تشغيل)، ضَع علامة في مربّع الاختيار عرض index.html تلقائيًا.
  3. بدِّل خيار خادم الويب إلى إيقاف، ثم عد إلى تم البدء.إعادة تشغيل خادم الويب في Chrome
  4. تأكَّد من ظهور عنوان URL واحد على الأقل لخادم الويب: http://127.0.0.1:8887، وهو عنوان URL التلقائي لخادم الويب المحلي.

إعداد قاعدة إعادة توجيه المنفذ

يمكنك إعداد جهاز الواقع المعزّز حتى يصل إلى المنفذ نفسه على محطة العمل عند الانتقال إلى Localhost:8887 عليه.

  1. على محطة عمل المطوّر، انتقِل إلى chrome://inspect وانقر على إعادة توجيه المنفذ...: chrome://inspect
  2. استخدِم مربّع الحوار إعدادات إعادة توجيه المنفذ لإعادة توجيه المنفذ 8887 إلى localhost:8887.
  3. ضَع علامة في مربّع الاختيار تفعيل إعادة توجيه المنفذ:

ضبط إعادة توجيه المنفذ

التحقق من صحة الإعداد

اختبار الاتصال:

  1. وصِّل جهاز الواقع المعزّز بمكان عملك باستخدام كابل USB.
  2. على جهاز الواقع المعزّز في Chrome، أدخِل http://localhost:8887 في شريط العناوين. من المفترض أن يعيد توجيه جهاز الواقع المعزّز هذا الطلب إلى خادم الويب الخاص بمحطة عمل التطوير. من المفترض أن يظهر لك دليل الملفات.
  3. على جهاز الواقع المعزّز، انقر على step-03 لتحميل ملف step-03/index.html في المتصفِّح.

من المفترض أن تظهر صفحة تحتوي على الزر بدء الواقع المعزّز.

ومع ذلك، إذا ظهرت لك صفحة خطأ متصفّح غير متوافق، من المحتمل أنّ جهازك غير متوافق.

توفُّر ARCore

عدم توفّر ARCore

من المفترض أن يعمل الاتصال بخادم الويب الآن مع جهاز الواقع المعزّز.

  1. انقر على بدء الواقع المعزّز. قد يُطلب منك تثبيت ARCore.

طلب تثبيت ARCore

ستظهر لك رسالة تطلب منك منح أذونات الكاميرا في المرة الأولى التي تشغّل فيها تطبيقًا للواقع المعزّز.

Chrome يطلب أذونات الوصول إلى الكاميرا ‏← مربّع حوار الأذونات

بعد الانتهاء من ضبط الإعدادات، من المفترض أن يظهر لك مشهد مكعبات معروضة فوق خلاصة الكاميرا. يزداد فهم المشهد عندما تُحلِّل الكاميرا المزيد من التفاصيل، لذا يمكن أن يساعد التنقّل في تحسين الأداء.

3- ضبط WebXR

في هذه الخطوة، ستتعرّف على كيفية إعداد جلسة WebXR ومشهد أساسي للواقع المعزّز. يتم توفير صفحة HTML مع تنسيق CSS وJavaScript لتفعيل وظائف الواقع المعزّز الأساسية. يؤدي ذلك إلى تسريع عملية الإعداد، ما يتيح لمشروع Codelab التركيز على ميزات الواقع المعزّز.

صفحة HTML

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

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

يجب أن يظهر ملف index.html، المتوفِّر في الدليل work، على النحو التالي. هذه مجموعة فرعية من المحتوى الفعلي، ولا تنسخ هذا الرمز إلى ملفك.

<!-- Don't copy this code into your file! -->
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Building an augmented reality application with the WebXR Device API</title>
    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>

    <!-- three.js -->
    <script src="https://unpkg.com/three@0.123.0/build/three.js"></script>
    <script src="https://unpkg.com/three@0.123.0/examples/js/loaders/GLTFLoader.js"></script>

    <script src="../shared/utils.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
  <!-- Information about AR removed for brevity. -->

  <!-- Starting an immersive WebXR session requires user interaction. Start the WebXR experience with a simple button. -->
  <a onclick="activateXR()" class="mdc-button mdc-button--raised mdc-button--accent">
    Start augmented reality
  </a>

</body>
</html>

افتح رمز JavaScript الخاص بالمفتاح.

نقطة بداية تطبيقك هي app.js. يوفّر هذا الملف بعض النماذج لإعداد تجربة الواقع المعزّز.

يتضمن دليل العمل أيضًا رمز التطبيق (app.js).

التحقّق من توفّر WebXR والواقع المعزّز

قبل أن يتمكّن المستخدم من استخدام الواقع المعزّز، تأكَّد من توفُّر navigator.xr وميزات XR اللازمة. يمثّل العنصر navigator.xr نقطة دخول واجهة برمجة التطبيقات WebXR Device API، وبالتالي يجب أن يظهر إذا كان الجهاز متوافقًا. تأكَّد أيضًا من أنّ وضع جلسة ""immersive-ar"" متوافق.

إذا كان كل شيء على ما يرام، سيؤدي النقر على الزر دخول الواقع المعزّز إلى محاولة إنشاء جلسة واقع ممتزج. بخلاف ذلك، يتمّ استدعاء onNoXRDevice() (في shared/utils.js) الذي يعرض رسالة تشير إلى عدم توفّر ميزة الواقع المعزّز.

هذا الرمز متوفّر حاليًا في app.js، لذا ليس عليك إجراء أي تغيير.

(async function() {
  if (navigator.xr && await navigator.xr.isSessionSupported("immersive-ar")) {
    document.getElementById("enter-ar").addEventListener("click", activateXR)
  } else {
    onNoXRDevice();
  }
})();

طلب XRSession

عند النقر على بدء الواقع المعزّز، يتصل الرمز بـ activateXR(). يؤدي هذا الإجراء إلى بدء تجربة الواقع المعزّز.

  1. ابحث عن الدالة activateXR() في app.js. تم حذف بعض الرموز:
activateXR = async () => {
  // Initialize a WebXR session using "immersive-ar".
  this.xrSession = /* TODO */;

  // Omitted for brevity
}

يمكن الوصول إلى WebXR من خلال XRSystem.requestSession(). يمكنك استخدام وضع immersive-ar للسماح بعرض المحتوى المعروض في بيئة حقيقية.

  1. إعداد this.xrSession باستخدام الوضع "immersive-ar":
activateXR = async () => {
  // Initialize a WebXR session using "immersive-ar".
  this.xrSession = await navigator.xr.requestSession("immersive-ar");

  // ...
}

إعداد XRReferenceSpace

يصف XRReferenceSpace نظام الإحداثيات المستخدَم للأجسام في العالم الافتراضي. الوضع 'local' هو الأنسب لتجربة الواقع المعزّز، مع مساحة مرجعية لها مصدر بالقرب من المشاهد وتتبُّعها الثابت.

يمكنك إعداد this.localReferenceSpace في onSessionStarted() باستخدام الرمز التالي:

this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");

تحديد حلقة صورة متحركة

  1. استخدِم requestAnimationFrame في XRSession لبدء حلقة عرض، مثل window.requestAnimationFrame.

في كل إطار، يتم استدعاء onXRFrame باستخدام طابع زمني وXRFrame.

  1. أكمِل تنفيذ onXRFrame. عند رسم إطار، أضِف الطلب التالي إلى قائمة الانتظار من خلال إضافة ما يلي:
// Queue up the next draw request.
this.xrSession.requestAnimationFrame(this.onXRFrame);
  1. أضِف رمزًا لإعداد بيئة الرسومات. إضافة إلى أسفل onXRFrame:
// Bind the graphics framebuffer to the baseLayer's framebuffer.
const framebuffer = this.xrSession.renderState.baseLayer.framebuffer;
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
this.renderer.setFramebuffer(framebuffer);
  1. لتحديد وضع المشاهد، استخدِم XRFrame.getViewerPose(). يصف XRViewerPose هذا موضع الجهاز واتجاهه في الفضاء. ويتضمّن أيضًا صفيفًا من XRViews، التي تصف كلّ نقطة نظر يجب أن يتم عرض المشهد منها لعرضه بشكل صحيح على الجهاز الحالي. على الرغم من أنّ الواقع الافتراضي المجسَّم له مشاهدتان (واحدة لكل عين)، لا يمكن لأجهزة الواقع المعزّز أن تحصل إلا على عرض واحد.
    يتم استخدام المعلومات الواردة في pose.views بشكل شائع لضبط مصفوفة العرض ومصفوفة الإسقاط للكاميرا الافتراضية. يؤثر هذا على كيفية تخطيط المشهد ثلاثي الأبعاد. عندما يتم إعداد الكاميرا، يمكن عرض المشهد.
  2. أضِف ما يلي إلى أسفل onXRFrame:
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(this.localReferenceSpace);
if (pose) {
  // In mobile AR, we only have one view.
  const view = pose.views[0];

  const viewport = this.xrSession.renderState.baseLayer.getViewport(view);
  this.renderer.setSize(viewport.width, viewport.height);

  // Use the view's transform matrix and projection matrix to configure the THREE.camera.
  this.camera.matrix.fromArray(view.transform.matrix);
  this.camera.projectionMatrix.fromArray(view.projectionMatrix);
  this.camera.updateMatrixWorld(true);

  // Render the scene with THREE.WebGLRenderer.
  this.renderer.render(this.scene, this.camera);
}

اختبار الميزة

شغِّل التطبيق، ثم انتقِل إلى work/index.html على جهاز التطوير. من المفترض أن تظهر لك خلاصة الكاميرا مع مكعبات تطفو في الفضاء ويتغير منظورها أثناء تحريك جهازك. يزداد رصد نشاطك دقة كلما تحركت أكثر، لذا استكشِف الإعدادات التي تناسبك أنت وجهازك.

إذا كنت تواجه مشاكل في تشغيل التطبيق، اطّلِع على قسمَي المقدّمة وإعداد بيئة التطوير.

4. إضافة شبكة استهداف

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

فهم اختبار النتيجة

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

تتيح لك WebXR Device API معرفة ما إذا كان هذا الشعاع قد تقاطع مع أي أجسام في العالم الحقيقي، وذلك استنادًا إلى إمكانات الواقع المعزّز الأساسية وفهم العالم.

شرح اختبار مؤشر الماوس

طلب XRSession مع ميزات إضافية

لإجراء اختبارات النتائج، يجب توفّر ميزات إضافية عند طلب XRSession.

  1. في app.js، حدِّد موقع navigator.xr.requestSession.
  2. أضِف السمتَين "hit-test" و"dom-overlay" كسمات requiredFeature على النحو التالي:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["hit-test", "dom-overlay"]
});
  1. اضبط تراكب DOM. ضَع العنصر document.body فوق عرض كاميرا الواقع المعزّز على النحو التالي:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["hit-test", "dom-overlay"],
  domOverlay: { root: document.body }
});

إضافة طلب يتضمن الحركة

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

استخدِم الرمز "dom-overlay" من الخطوة السابقة لعرض طلب لإجراء حركة فوق بث الكاميرا.

أضِف <div> إلى index.html باستخدام المعرّف stabilization. يعرض هذا <div> صورة متحركة للمستخدمين تمثّل حالة التثبيت وتطالبهم بالتحرك باستخدام أجهزتهم لتحسين عملية SLAM. يظهر هذا الاسم عندما يكون المستخدم في وضع "الواقع المعزّز" ويتم إخفاؤه عندما تعثر الشبكة على سطح معيّن، وتتحكّم هذه الفئة من فئات <body>.

  <div id="stabilization"></div>

</body>
</html>

إضافة شبكة تصويب

استخدِم شبكة تصويب للإشارة إلى الموقع الجغرافي الذي يشير إليه عرض الجهاز.

  1. في app.js، استبدِل طلب DemoUtils.createCubeScene() في setupThreeJs() بطلب Three.Scene() فارغ.
setupThreeJs() {
  // ...

  // this.scene = DemoUtils.createCubeScene();
  this.scene = DemoUtils.createLitScene();
}
  1. املأ المشهد الجديد بجسم يمثّل نقطة الاصطدام. تتعامل فئة Reticle المقدَّمة مع تحميل نموذج الشبيكة في shared/utils.js.
  2. إضافة Reticle إلى المشهد في setupThreeJs():
setupThreeJs() {
  // ...

  // this.scene = DemoUtils.createCubeScene();
  this.scene = DemoUtils.createLitScene();
  this.reticle = new Reticle();
  this.scene.add(this.reticle);
}

لإجراء اختبار مطابقة، استخدِم XRReferenceSpace جديدًا. تشير هذه المساحة المرجعية إلى نظام إحداثي جديد من منظور المشاهد لإنشاء شعاع تتماشى مع اتجاه العرض. يُستخدم نظام الإحداثيات هذا في XRSession.requestHitTestSource()، الذي يمكنه احتساب اختبارات النتائج.

  1. أضِف ما يلي إلى onSessionStarted() في app.js:
async onSessionStarted() {
  // ...

  // Setup an XRReferenceSpace using the "local" coordinate system.
  this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");

  // Add these lines:
  // Create another XRReferenceSpace that has the viewer as the origin.
  this.viewerSpace = await this.xrSession.requestReferenceSpace("viewer");
  // Perform hit testing using the viewer as origin.
  this.hitTestSource = await this.xrSession.requestHitTestSource({ space: this.viewerSpace });

  // ...
}
  1. باستخدام هذا hitTestSource، يمكنك إجراء اختبار تصادم في كل إطار:
    • إذا لم تظهر أي نتائج لاختبار الاصطدام، يعني ذلك أنّه لم يتوفّر لتطبيق ARCore وقت كافٍ لفهم البيئة. في هذه الحالة، اطلب من المستخدم تحريك الجهاز باستخدام رمز التثبيت <div>.
    • إذا كانت هناك نتائج، حرِّك الشبكة إلى هذا الموقع.
  2. عدِّل onXRFrame لنقل شبكة الاستهداف:
onXRFrame = (time, frame) => {
  // ... some code omitted ...
  this.camera.updateMatrixWorld(true);

  // Add the following:
  const hitTestResults = frame.getHitTestResults(this.hitTestSource);

  if (!this.stabilized && hitTestResults.length > 0) {
    this.stabilized = true;
    document.body.classList.add("stabilized");
  }
  if (hitTestResults.length > 0) {
    const hitPose = hitTestResults[0].getPose(this.localReferenceSpace);

    // update the reticle position
    this.reticle.visible = true;
    this.reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
    this.reticle.updateMatrixWorld(true);
  }
  // More code omitted.
}

إضافة سلوك عند النقر على الشاشة

يمكن أن يُرسِل XRSession أحداثًا استنادًا إلى تفاعل المستخدِم من خلال الحدث select الذي يمثّل الإجراء الأساسي. في WebXR على الأجهزة الجوّالة، يكون الإجراء الأساسي هو النقر على الشاشة.

  1. إضافة أداة معالجة أحداث select في أسفل onSessionStarted:
this.xrSession.addEventListener("select", this.onSelect);

في هذا المثال، يؤدي النقر على الشاشة إلى وضع زهرة عباد الشمس في شبكة الاستهداف.

  1. أنشئ عملية تنفيذ لـ onSelect في فئة App:
onSelect = () => {
  if (window.sunflower) {
    const clone = window.sunflower.clone();
    clone.position.copy(this.reticle.position);
    this.scene.add(clone);
  }
}

اختبار التطبيق

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

  1. عند تشغيل تطبيقك، من المفترض أن يظهر لك إطار شبكي يتتبّع سطح الأرض. إذا لم يظهر لك أي محتوى، حاوِل التنقّل في الغرفة ببطء باستخدام هاتفك.
  2. بمجرد رؤية الشبكة، انقر عليها. يجب وضع زهرة عباد الشمس فوقها. قد تحتاج إلى التحرك قليلاً حتى تتمكّن منصة الواقع المعزَّز الأساسية من رصد الأسطح في العالم الحقيقي بشكل أفضل. تؤدي الإضاءة المنخفضة والأسطح التي لا تحتوي على ميزات إلى تقليل جودة فهم المشهد، وزيادة احتمال عدم العثور على أي نتائج. إذا واجهت أي مشاكل، اطّلِع على رمز step-04/app.js للاطّلاع على مثال عملي لهذه الخطوة.

5- إضافة ظلال

يتضمن إنشاء مشهد واقعي عناصر مثل الإضاءة المناسبة والظلال على الأجسام الرقمية التي تضيف واقعية وشعورًا بالانغماس في المشهد.

تعالج three.js الإضاءة والظلال. يمكنك تحديد المصابيح التي يجب أن تلقي ظلالًا والمواد التي يجب أن تتلقّى هذه الظلال وتُظهِرها، والشبكات التي يمكنها رمي الظلال. يحتوي مشهد هذا التطبيق على ضوء يلقي ظلًا وسطح مستوٍ لعرض الظلال فقط.

  1. فعِّل الظلال في three.js WebGLRenderer. بعد إنشاء العارض، اضبط القيم التالية على shadowMap:
setupThreeJs() {
  ...
  this.renderer = new THREE.WebGLRenderer(...);
  ...
  this.renderer.shadowMap.enabled = true;
  this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  ...
}

يتضمّن مثال المشهد الذي تم إنشاؤه في DemoUtils.createLitScene() عنصرًا يُسمى shadowMesh، وهو سطح مستوٍ أفقي لا يعرض سوى الظلال. يكون موضع Y لهذه المساحة في البداية 10,000 وحدة. بعد وضع زهرة عباد الشمس، حرِّك الرمز shadowMesh ليكون بالارتفاع نفسه الذي تبلغه سطح الأرض في الواقع، بحيث يظهر ظلّ الزهرة فوق سطح الأرض في الواقع.

  1. في onSelect، بعد إضافة clone إلى المشهد، أضِف رمزًا لإعادة وضع مستوى الظل:
onSelect = () => {
  if (window.sunflower) {
    const clone = window.sunflower.clone();
    clone.position.copy(this.reticle.position);
    this.scene.add(clone);

    const shadowMesh = this.scene.children.find(c => c.name === "shadowMesh");
    shadowMesh.position.y = clone.position.y;
  }
}

اختبار الميزة

عند وضع زهرة عباد الشمس، من المفترض أن يظهر ظلّها. إذا واجهت أي مشاكل، اطّلِع على رمز final/app.js للاطّلاع على مثال عملي لهذه الخطوة.

6- مراجع إضافية

تهانينا! لقد وصلت إلى نهاية هذا الدليل التعليمي حول الواقع المعزّز باستخدام WebXR.

مزيد من المعلومات