صمِّم تطبيقًا للواقع المعزّز باستخدام 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

  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 إلى المضيف المحلي: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 لتفعيل وظائف الواقع المعزّز الأساسية. يساعد ذلك في تسريع عملية الإعداد، ما يتيح للدرس التطبيقي حول الترميز التركيز على ميزات الواقع المعزّز.

صفحة 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"" متوافق.

إذا كانت الأمور على ما يرام، سيؤدي النقر على الزر إدخال الواقع المعزّز إلى محاولة إنشاء جلسة XR. في الحالات الأخرى، يتم اسم 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 هذه موضع الجهاز واتجاهه في المساحة. ويتضمّن أيضًا مصفوفة من XRView تصف كل نقطة مشاهدة يجب عرض المشهد منها لعرضها بشكل صحيح على الجهاز الحالي. على الرغم من أنّ الواقع الافتراضي المجسَّم له عرضان (إحداهما لكل عين)، لا يتم تسجيل سوى عرض واحد لأجهزة الواقع المعزّز.
    ويشيع استخدام المعلومات الواردة في 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. تفعيل التظليل على WebGLRenderer three.js بعد إنشاء العارض، اضبط القيم التالية على shadowMap:
setupThreeJs() {
  ...
  this.renderer = new THREE.WebGLRenderer(...);
  ...
  this.renderer.shadowMap.enabled = true;
  this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  ...
}

يتضمّن المثال الذي تم إنشاؤه في DemoUtils.createLitScene() كائنًا اسمه shadowMesh، وهو سطح أفقي مسطح يعرض الظلال فقط. يكون الموضع ص في البداية لهذا السطح مع 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.

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