اذهب إلى المحتوى

البحث في الموقع

المحتوى عن 'webgl'.

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المحتوى


التصنيفات

  • الإدارة والقيادة
  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • السلوك التنظيمي في المؤسسات
  • عالم الأعمال
  • التجارة والتجارة الإلكترونية
  • نصائح وإرشادات
  • مقالات ريادة أعمال عامة

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • PHP
    • Laravel
    • ووردبريس
  • جافاسكربت
    • لغة TypeScript
    • Node.js
    • React
    • Vue.js
    • Angular
    • jQuery
    • Cordova
  • HTML
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • لغة C#‎
    • ‎.NET
    • منصة Xamarin
  • لغة C++‎
  • لغة C
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • لغة Rust
  • برمجة أندرويد
  • لغة R
  • الذكاء الاصطناعي
  • صناعة الألعاب
  • سير العمل
    • Git
  • الأنظمة والأنظمة المدمجة

التصنيفات

  • تصميم تجربة المستخدم UX
  • تصميم واجهة المستخدم UI
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب GIMP
    • كريتا Krita
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • مقالات DevOps عامة
  • خوادم
    • الويب HTTP
    • البريد الإلكتروني
    • قواعد البيانات
    • DNS
    • Samba
  • الحوسبة السحابية
    • Docker
  • إدارة الإعدادات والنشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
    • ريدهات (Red Hat)
  • خواديم ويندوز
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • شبكات
    • سيسكو (Cisco)

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح
  • مبادئ علم التسويق

التصنيفات

  • مقالات عمل حر عامة
  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • العمل الحر المهني
    • العمل بالترجمة
    • العمل كمساعد افتراضي
    • العمل بكتابة المحتوى

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

  • الأقسام
    • أسئلة البرمجة
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات

التصنيفات

  • كتب ريادة الأعمال
  • كتب العمل الحر
  • كتب تسويق ومبيعات
  • كتب برمجة
  • كتب تصميم
  • كتب DevOps

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

تم العثور على 3 نتائج

  1. بعد تعلّم المعلومات الرئيسية عن الفضاء ثلاثي الأبعاد والإضاءة، تعجّلنا في نهاية الدرس السابق لكي نحصل على صورة ثلاثية الأبعاد، إلا أنني سأعود قليلًا إلى الوراء وأشرح كائنات threeJS بالتفصيل قبل إعادة عرض الناتج مجددًا. التفاصيل أنشأنا في نهاية الدرس السابق جسمًا كرويًا نمثّل به لكوكب المريخ: let marsGeo = new THREE.SphereGeometry (500, 32, 32); تدعم مكتبة threeJS أشكالا هندسية مختلفة، من بينها الشكل الكروي الذي يُتحصَّل عليه بالدالة SphereGeometry. نمرّر للدالة في المعطى الأول قيمة نصف قطر الكرة (500)، عدد القطع الأفقية المكونة للكرة (32) وعدد القطع العموديّة (32). يُنشَأ كل جسمٍ افتراضيًا في نقطة المبدأ (‎0, 0, 0)، لذا لا حاجة إلى نقل الجسم. ماذا يحدث لو قلّلنا عدد القطع إلى 4 في كل اتجاه من الكرة؟ الصورة الآتية تعرض أثر اختلاف عدد القطع (من اليسار إلى اليمين: 4 ثم 8 ثم 16 ثم 32 قطعة أفقيًا وشاقوليًا لكل جسم). يمكنك أن تلاحظ أنَّ حافة الجسم تصبح «خشنةً» كلما قلّ عدد القطع؛ ويبدو الجزء الأمامي من الجسم كرويًا بسبب الأضواء والمُظلِّلات (shaders، سأتحدث عن المُظلِّلات بعد قليل). كقاعدة عامة: كلما ازدادت عدد القطع الموجودة في أحد الأجسام كان «أنعم»؛ لكن زيادة عدد القطع له سلبياته، فالعدد الكبير من القطع يؤدي إلى زيادة وقت المعالجة اللازم لإظهار المشهد إضافةً إلى زيادة حجم الذاكرة اللازمة لعرضه. عليك الموازنة بين الأمرين وذلك بتحديد دقة التفاصيل التي تحتاج لها في الجسم؛ فلو كانت الكرة بعيدةً جدًا أو صغيرةً جدًا، فلن تحتاج إلى قطعٍ كثيرة لكي تجعلها تبدو كرويةً، لكن إذا أردتَ إنشاء مشهدٍ يصوِّر الكوكب عن قرب، فعليك زيادة عدد القطع لتضمن أنَّ حواف الكرة ستبقى ناعمةً حتى لو اقتربنا كثيرًا من الكوكب. تركيب «المواد» طبّقنا في آخر مثال مادة Phong ‏(Phong material) إلى الكرة: marsMaterial = new THREE.MeshPhongMaterial( { color: 0xff6600 } ), Phong هي خوارزمية تظليل (Shader algorithm) كتبها أحد باحثي رسوميات الحاسوب الفيتناميين. الغرض من المُظلِّل هو تعريف كيفية تفاعل الضوء مع السطح ثلاثي الأبعاد: وكانت خوارزمية Phong سريعةً وكفاءتها عالية، ومثاليةً لعرض السطوح الناعمة. يجب أن تُدمَج المادة مع كائن ثلاثي الأبعاد في threeJS لإنشاء mesh: marsMesh = new THREE.Mesh(marsGeo, marsMaterial); الناتج المعروض في المثال السابق بسيطٌ جدًا ولا يناسب غرضنا، فنحن نريد إنشاء كوكب، وليس كرةً برتقاليةً لامعة. ولإنشاء هذا الشعور، فعلينا تضمين المزيد من المواد ووضعها على الكرة، وذلك عبر Texture Loader: let loader = new THREE.TextureLoader(); هنالك الكثير من الجوانب التي تتعلق بالمواد المُشكِّلة للجسم، وأبرزها – في حالة كوكب المريخ – هو اللون، لكن سطح كوكب المريخ متنوع جدًا ولا يمكن تمثيله بلونٍ واحد. فالحل هو أخذ إحدى الخرائط التي أنشأتها المكوكات الفضائية واستعمالها على الكرة. استعملتُ في هذا المثال صورًا من Celestia ثم ضبطُها لتكوِّن خريطةً المواد لسطح الكوكب: marsMaterial.map = loader.load(imgLoc+"mars-map.jpg"); ربما تتذكر من أوّل درس في هذه السلسلة أننا عرّفنا المتغير imgLoc الذي يحتوي على مسار تخزين الصور. قياس الخريطة المستعملة مع WebGL على النقيض من عدد القطع التي تُشكِّل الجسم، من المستحسن استخدام خرائط ذات دقة عالية، لأنها تعطي شعورًا بدقة تفاصيل الجسم؛ لكن ذلك يؤدي إلى نفس المشاكل: استخدام ذاكرة أكثر، وتقليل الأداء. أجرتَ WebGL موازنة بين ما سبق عبر وضع شرطين للخرائط المستعملة: يجب أن يكون عرض وارتفاع الخريطة من قوى العدد 2: أي 1 أو 2 أو 4 أو 8 أو 16 أو 32 أو 64 أو 128 أو 256 أو 512 أو 1024 أو 2048 أو 4096 أو 8192 بكسل طولًا أو عرضًا (يمكن أن تختلف الأرقام. فمن الممكن أن تكون الخريطة بعرض 1024 وبارتفاع 512). هنالك حدٌّ أقصى لما تستطيع متصفحات الهاتف استعماله لخرائط الأجسام، وهذا الحد يرتفع مع مرور الوقت (نظام iOS 10 يدعم خريطةً بأبعاد 4096×4096، ويمكنك تجربة مختلف الأجهزة والأنظمة في webglreport.com). سأعيد تحجيم الخريطة التي سأستعملها إلى 4096‎×2048 بكسل: ‎من المهم أن تكون الخريطة سلسة الحواف (seamless): أي عندما توضع على كرة، فلن تكون حدودها واضحةً. العرض لإنتاج أيّ مشهد فعلينا «عرضه» (render)، وذلك باستخدام شفرة ذات خمسة أسطر، على النحو التالي: let renderer = new THREE.WebGLRenderer({antialiasing : true}); marsloc.appendChild(renderer.domElement); function render(){ renderer.setSize(window.innerWidth, window.innerHeight); renderer.clear(); renderer.render(scene, camera); } استعملنا الخيار antialiasing لتنعيم شكل كوكب المريخ عند تعريف المتغير renderer (الذي يملك خياراتٍ كثيرة أخرى). المتغير marsLoc هو العنصر الذي سيحتوي على مشهد WebGL والذي أنشأناه في الجزء الأول، حيث أضفنا renderer إليه. أما داخل الدالة render فكانت أبعاد المشهد مساويةً لأبعاد نافذة المتصفح؛ ثم مسحنا كل ما كان موجودًا في لوح الرسم، ثم عرضنا المشهد باستخدام الكاميرا التي عرَّفناها سابقًا. ستلاحظ الآن أنَّ النتيجة تبدو مسطحةً ولامعةً، وثابتةً في الفضاء، وغير متجاوبة؛ وسنتخذ التدابير اللازمة في الدرس القادم من هذه السلسلة لحلّ تلك المشاكل. ترجمة –وبتصرّف– للمقال A WebGL Tour of the Solar System: Mars, Part ThreeلصاحبهDudley Storey
  2. شرحنا في أوّل جزء من هذه السلسلة أساسيات استخدام إطار عمل threeJS، بما في ذلك ضبط إعدادات الكاميرا ودمج مشهد WebGL مع محتويات صفحة الوِب. أما في هذا الدرس فسنُموضع الكاميرا في الفضاء ثلاثي الأبعاد ونجعلها تُشير إلى كائن ونُضيف إضاءةً إلى المشهد. ولكن قبل فعل أيّ مما سبق، علينا أن نفهم طبيعة الفضاء ثلاثي الأبعاد. ملاحظة: هذا الدرس يكمل من حيث انتهى الدرس السابق، لذا عليك أن تفهمه وتحصل على شِفرته قبل الاستمرار بقراءة هذا الدرس. التنقل في الفضاء ثلاثي الأبعاد أتوقع أنَّك تعرف محاور الإحداثيات من دراستك الثانوية: يُرسَم المحور x أفقيًا، والمحور y شاقوليًا (عموديّا). وبضبط الوحدات التي تُمثلها تلك المحاور، فسنتمكن من تحديد مكان أيّ عنصرٍ في الجزء الموجب من الفضاء ثنائي الأبعاد. أما إذا أردنا تضمين الأماكن السالبة فعلينا تمديد المحاور إلى اليسار وإلى الأسفل: نقطة تقاطع المحورين هي النقطة ‎0, 0 وتسمى «المبدأ» (Origin). أما لتحديد المواقع في فضاء ثلاثي الأبعاد، فعلينا إضافة محور ثالث عمودي على المحورين السابقين ويتجه بعيدًا عن المشاهد. نستطيع تخيّل المحور z أيضًا بإمالة المنظور قليلًا كما في الرسم التوضيحي الآتي: لاحظ أنَّ الجزء السالب من المحور z يتجه مبتعدًا عنّا، أما الجزء الموجب فهو أقرب. يمكن الآن تحديد مكان أيّة نقطة في الفضاء بتقاطع ثلاثة قيم x وy وz. ملاحظة: لاحظ عدم أهمية ما الذي تمثِّله تلك الأرقام، فقد تكون بوحدة المليمتر أو القدم أو السنوات الضوئية! المهم هو كيف تتفاعل تلك الأرقام مع بعضها: فالقيمة 2x هي ضعف المسافة x. تتواجد الكاميرات التي أنشأناها في الدرس السابق في مبدأ الإحداثيات افتراضيًا، لكننا نريد وضعها بعيدًا عن المنتصف: camera.position.set(1380, 0, 0); المتغير scene يحتوي على الكائنات التي سنُنشِئها، والذي يُمكن تهيئته بالسطر الآتي: scene = new THREE.Scene(); يوضع المشهد تلقائيًا في مبدأ الإحداثيات (‎0, 0, 0) وسنضع فيه أيضًا العنصر الرئيسي الذي سنُنشِئه (كوكب المريخ). لذا نريد أن نوجِّه الكاميرا إلى تلك النقطة: camera.lookAt(scene.position); ملاحظة: يمكن وضع الكاميرا – في هذا المثال– على المحور z أيضًا لكن يجب أن تبعد بنفس القيمة (1380)، ويمكن أيضًا وضعها في الجزء السالب من المحور x أوz؛ وذلك لأنَّ الكاميرا ستكون موجهةً نحو المبدأ دومًا. لنشغِّل الأضواء المشهد الذي أنشأناه هو فضاءٌ مظلمٌ لا متناهٍ، مما يعني أنَّ أي كائن سيوضع فيه سيكون غيرَ مرئي، لعدم وجود مصدر للضوء. لنضف واحدًا: light = new THREE.PointLight(0xFFFFFF, 2, 5000); light.position.set(2000, 2000, 1500); scene.add(light); ملاحظة: لاحظ أنَّك لن ترى شيئًا في هذه المرحلة، ليس لأنَّ مصدر الضوء يكون مخفيًّا افتراضيًا، وإنما لأننا لم نعرض المشهد بعد. تتوافر ستة أنواع من الأضواء في إطار عمل threeJS: ضوء نقطي (PointLight): وهو الضوء الذي يكون له موضعٌ معيّن، ويُشعّ الضوء في كل الاتجاهات بقدر متساوٍ، مما يجعل هذا النوع من الإضاءة مثاليًا لمحاكاة الضوء الآتي من النجوم أو المصابيح. ضوء ذو اتجاه (DirectionalLight): وهو الضوء الذي له اتجاهٌ معيّن، لكنه ليس حزمةً ضوئيةً (Beam، على النقيض من «بقعة الضوء» Spotlight أدناه)، وهو مفيدٌ لمحاكاة طريقة رؤية أشعة الشمس من سطح الأرض. بقعة ضوء (SpotLight): الضوء الذي يُشير إلى اتجاهٍ معيّن يشبه حزمةً ضوئيةً واسعةً مَثَلُهُ كَمَثَلِ الأضواء المسرحية. الضوء الآتي من منطقة مضيئة مستطيلة (RectAreaLight) وهو مفيدٌ لمحاكاة الضوء المار عبر النافذة أو من لوحٍ من الفلورسنت. الإضاءة المحيطية (AmbientLight): هذا ضوءٌ عامٌ كالذي تراه آتيًا من جميع الاتجاهات. تخيل ليلةً غيرَ مقمرةٍ فيها ضوء محيطي. للإضاءة المحيطية القدرة على إضفاء لونٍ معيّن على المشهد: فكلما كان الضوء المحيطي فاتحًا كلما ظهر المشهد بلونٍ باهت. الإضاءة نصف الكروية (HemisphereLight): يدعى هذا النوع من الإضاءة في برامج التصميم ثلاثي الأبعاد بالمصطلح «Skylight». وهي تحاكي الضوء القادم من الأعلى (السماء) إلى الأسفل (أيّ نوع من الانعكاس أو الضوء من الأرض). يمكنك تخيّل هذا النوع من الإضاءة كما لو أنَّ الإضاءة المحيطية مقسومة إلى نصفين. سأشرح أنواع الإضاءة السابقة تفصيليًا في مقالاتٍ قادمة، لكن علينا أن نركِّز الآن على الضوء النقطي والذي يأخذ ثلاثة وسائط: اللون (عبر قيمة بالنظام الست عشري، يسبقها ‎0x)، والشدة (Intensity)، والنقطة التي سيبدأ الضوء بالانتشار منها. وكذلك الأمر فيما يتعلق بالظلال، فجميع الأضواء تلقي بظلالٍ في الواقع، أما في الرسومات ثلاثية الأبعاد فقد يُسبِّب ذلك مشاكل، لذا يكون إلقاء الظلال الناتجة من الضوء اختياريًا. ربما تُفضِّل التجربة مع شدة الضوء لترى تأثيرها، حيث ستجد أنَّ الشدة العالية للضوء ستجعل الألوان قويةً جدًا، مثل استخدام ضوء فلاش قوي جدًا بالقرب من الجسم الذي تصوِّره بكاميرتك العادية. نموذج أولي بسيط يؤسفني أن نخوض في كل المعلومات السابقة دون أن تتاح لنا فرصةٌ لرؤية أيّة أشكال في صفحتنا، لذا أنشأتُ نسخةً مبسطةً من الناتج وعرضتها لك. الشيفرة الآتية تضم جميع التعليمات البرمجية التي كتبناها منذ بداية هذه السلسلة وحتى هذه المرحلة (دون الشفرة المسؤولة عن تضمين إطار threeJS): let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000), light = new THREE.PointLight(0xFFFFFF, 2, 5000), scene = new THREE.Scene(); light.position.set(2000, 2000, 1500); camera.position.set(1500, 0, 0); camera.lookAt(scene.position); scene.add(light); let marsGeo = new THREE.SphereGeometry (500, 32, 32), marsMaterial = new THREE.MeshPhongMaterial( { color: 0xff6600 } ), marsMesh = new THREE.Mesh(marsGeo, marsMaterial); scene.add(marsMesh); let renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight) marsloc.appendChild(renderer.domElement); renderer.render(scene, camera); بوضع الشيفرة السابقة في صفحة الويب التي أنشأناها في الدرس السابق، فسترى النتيجة الآتية؛ لكن ما يزال علينا إضافة الكثير من الأمور إليها، وشرحها بالتفصيل، وهذا ما سنفعله في الدرس القادم. ترجمة –وبتصرّف– للمقال A WebGL Tour of the Solar System: Mars, Part Two لصاحبه Dudley Storey.
  3. كانت هنالك الكثير من المحاولات الباكرة لابتكار تقنية لإنشاء رسوميات ثلاثية الأبعاد 3D تفاعلية في صفحات الوِب، بما فيها VRML وFlash، لكن لم يظهر معيارٌ متكاملٌ حتى عام 2013 ألا وهو WebGL المبني على OpenGL ES 2.0، لذا أصبح بإمكاننا تضمين رسوميات 3D تفاعلية في صفحات الوِب دون الحاجة إلى أيّة إضافات أو ملحقات للمتصفح. ما هي تقنية WebGL؟ تسمح تقنية WebGL بكتابة رسوميات 3D في صفحات الويب باستخدام JavaScript عبر العنصر <canvas>، لكن تقنية WebGL لا تُنشِئ «عناصر» على الصفحة، إذ تتعامل مباشرةً مع البكسلات؛ وبالتالي نقول عن تقنية WebGL أنّها تقنيةٌ منخفضة المستوى: حيث توفِّر تحكمًا دقيقًا بالفضاء ثلاثي الأبعاد. وعلى النقيض من أغلبية تطبيقات 3D، لا تتضمن WebGL «مشاهد» (Scenes) أو «كائنات» (Objects) أو «نماذج» (Models). وهذا ما يجعلها تقنيةً قويةً جدًا، لكن في الوقت نفسه تُصعِّب عملية التعلم بالنسبة للمطورين، ولا يمكن إخراج النتائج بواسطتها بسرعة. صحيحٌ أنَّ من الممكن تقنيّا كتابة شِفرات WebGL عبر JavaScript مباشرة، لكن أغلبية المطورين يستعملون إطار عمل Framework، وأشهر إطار عمل لتقنية WebGL هو threeJS، لكن هنالك خياراتٌ أخرى عداه. الحاجة إلى إطار عمل أنصح دومًا بالابتعاد عن أطر العمل: فأنا أعتقد أنَّ المطورين سيتعلمون أمورًا تفيدهم في المستقبل إذا تمكنوا من فهم الأساسيات التي تُبنَى عليها تقنيةٌ ما، بدلًا من سَلك «طرق مختصرة». لكنّ الرسم ثلاثي الأبعاد موضوعٌ معقدٌ جدًا، ومحاولة بناء خبرة عملية باستخدام WebGL إضافةً إلى تعلم تقنيات الوِب الأخرى أمرٌ صعبٌ للكثيرين، وتعلّم أساسيات WebGL يعني إضاعة الكثير من الوقت في التعلم دون القدرة على إنشاء أيّة رسومات ولو كانت بسيطةً. لهذا السبب، سنستعمل في شرحنا لهذه التقنية إطار threeJS، ولا أفترض عند كتابتي لهذه السلسلة أنَّ القارئ على دراية بمبادئ الرسم ثلاثي الأبعاد، لكن يجب أن يكون ذا درايةٍ جيدة بتقنيات HTML وCSS وJavaScript. سنستخدم في هذه السلسلة آخر إصدار متوافر من إطار threeJS. ما الذي يجعل هذه السلسلة مختلفةً عن غيرها أغلبية الدروس التعليمية التي تتحدث عن threeJS والمتوافرة على الوِب هي دروسٌ ليست بالمستوى المطلوب، حيث لا تعمل الأمثلة الحية لعدم تحديث الشفرة منذ فترةٍ طويلةٍ (تأتي التحديثات والتحسينات على إطار عمل threeJS بين الحين والآخر)، وهنالك خطواتٌ كاملةٌ غيرُ مشروحةٍ. لذا سأبذل جهدي لتفادي ذلك في هذه السلسلة، حيث سأضع المعلومات بتسلسلٍ منطقيٍ شارحا باستفاضة، مستعملًا أمثلةً عمليةً مسليةً ألا وهي نمذجة الكواكب الموجودة في نظامنا الشمسي كرسومات 3D. بناء كوكب المريخ باستخدام WebGL بعد أن تعرفنا على WebGL وتحدثنا أننا سنستعمل إطار العمل threeJS للاستفادة من إمكانية WebGL لإنشاء رسوميات 3D في صفحات الويب التي نُنشِئها، فسنكمل تعلمنا في بقية هذا الدرس (وفي الدروس القادمة) بإنشاء نموذج لكوكب المريخ؛ وسنستهل الأمر بتعلم كيفية وضع كاميرا ثلاثية الأبعاد، والتحكم بتفاعل محتوى WebGL مع بقية صفحة HTML الموجود داخلها. ملاحظة: سنشرح كل خطوة بالتفصيل أثناء بنائنا للنموذج، لذا لن يكون لدينا مشهدٌ جاهزٌ في نهاية هذا الدرس، وإنما سنفعل ذلك في المقالات اللاحقة المبنية على هذه المقالة (والمستقلة عنها)، أما لو كنتَ متحمسًا لرؤية الناتج النهائي، فاطلع على هذه التجربة الحية. تهيئة الصفحة على الرغم من إمكانية استخدام عناصر WebGL بمفردها في الصفحة، إلا أنها تُصنَّف كتقنية وِب معيارية، مما يعني أنَّها تندمج اندماجًا كاملًا مع محتوى HTML، ولعدم امتلاك العنصر <canvas> ميزات تتعلق بقابلية الوصول وتحسين أرشفة محركات البحث للصفحة، فمن المنطقي أن نُنشِئ محتوى WebGL ضمن صفحة وِب فيها معلوماتٌ تشرح محتواه، وذلك بوضع النص ضمن شيفرات HTML، ثم إضافة محتوى WebGL عند الحاجة. وسنؤسِّس لصفحتنا –التي تتحدث عن المريخ– باستعمال الشيفرة الآتية: <div id="marsloc"></div> <article id="marsinfo"> <h1>Mars</h1> <div> <p>Home to both the Solar System’s highest mountain… </div> </article> سيوضع محتوى WebGL ضمن العنصر marsloc، وسيوضَع النص الموجود في عنصر <div> فوق جميع محتويات الصفحة. هذه هي شِفرة Sass التي تتحكم بمظهر الصفحة: body { background: black; margin: 0; min-height: 100vh; color: #fff; } #marsloc { cursor: grab; } #marsinfo { position: absolute; top: 0; width: 100%; padding: 2rem; } #marsinfo h1 { font-size: 8vw; margin-top: 0; font-weight: 100; line-height: 1; position: absolute; } #marsinfo div { width: 40%; position: absolute; background-color: rgba(0,0,0,0.3); right: 0; padding: 1.3rem; line-height: 1.6; font-size: 1.2rem; pointer-events: none; @media all and (max-width: 540px) { width: 100%; left: 0; top: 40vw; } } تغيير شكل مؤشر الفأرة في العنصر ‎#marsloc سيُدلُّ على محتوى WebGL، أما العنصر div الموجود في ‎#marsloc فله الخاصية pointer-events: none لذا لن يتأثر النص الموجود أعلى محتوى WebGL بالتعديلات التي نجريها على الكوكب. إنشاء الكوكب بعد كتابة شفرات HTML و CSS، فلنحمِّل آخر إصدار من threeJS من CDN في أسفل الصفحة: <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"> </script> ملاحظة: علينا أن نضمن وجود إطار عمل threeJS قبل كتابة أيّة شفرات تتعلق به. سيبدأ السكربت بضبط مجموعة من المتغيرات والثوابت التي سنستعملها في شيفرتنا: var container, controls, camera, renderer, scene, light, marsMesh, clock = new THREE.Clock(); const imgLoc = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/"; سنستخدم المتغير clock للمساعدة في الحركة الافتراضية لكوكب المريخ، أما imgLoc فهو ثابتٌ يُشير إلى موقع جميع الصور التي سنستعملها وعرّفناه في البداية كي لا نُكرِّر المسار لاحقًا. مجال الرؤية أوّل عنصر سنُنشِئه هو الكاميرا، وهذا أمرٌ ضروريٌ لنتمكن من «رؤية» المشهد الذي سنُنشِئه. يوجد نوعان من الكاميرات في إطار threeJS: المنظور (perspectiveCamera): الخطوط المتوازية الموجودة في المشهد ستتقارب من بعضها إذا امتدت لمسافة طويلة (تخيل نفسك واقفًا على سكةٍ حديديةٍ وتنظر إلى أبعد جزء ينتهي إليه بصرك)؛ وستبدو الأجسام البعيدة من الكاميرا صغيرةً. وهذه مشابه لآلية عمل بصرنا، وسيبدو المشهد من هذا النوع من الكاميرات واقعيًا. الإسقاط العمودي (OrthographicCamera): الخطوط المتوازية ستبقى متوازية بغض النظر عن مدى امتدادها؛ ولنفس السبب، لن تبدو الأجسام أصغر كلما ابتعدت عن الكاميرات. نستفيد من هذا النوع من الكاميرات عند رسم عناصر الواجهة الرسومية أو لبعض المناظير المعمارية. إذا كنّا سنستخدم كاميرا ذات منظور (perspectiveCamera) فعلينا أن نُعرِّف مجال الرؤية (يُشار إليه عادةً بالاختصار FOV، الذي يرمز إلى Field of view). يُحدِّد مجال الرؤية مدى اتساع «رؤية» الكاميرا. فمجال الرؤية الضيق (الذي يشبه الغِماء Blinker الذي يضعونه على أعين الخيول التي تجر العربات، كيلا تجزع الأحصنة مما حولها) يؤدي إلى «تركيز» الكاميرا ugn جزءٍ مُحدّد من المشهد، مما يؤدي إلى عدم إظهار بعض العناصر لأنها ستقع خارج مجال الرؤية. أما مجال الرؤية العريض فيؤدي إلى إظهار المزيد من الأجسام، لكنه يُسبِّب في جعلها تبدو أصغر وأبعد. علينا أيضًا ضبط نسبة العرض إلى الارتفاع Aspect ratio: أي ما هو عرض المشهد نسبةً إلى ارتفاعه. من المرجّح أنَّك قد سمعتَ بنسبة العرض إلى الارتفاع في الأفلام، فالأفلام ذات المشاهد «العريضة» تجنح لأن تكون أفلام «ملحمية»، أما الأفلام التي نسبة العرض إلى الارتفاع قليلة (تكاد أن تصبح مربعةً) فستشعر أنها أفلامٌ قديمة. نريد غالب الأوقات أن تتشابه نسبة العرض إلى الارتفاع في المشهد مع نسبة العرض إلى الارتفاع التابعة لنافذة المتصفح للزائر. آخر قيمتين علينا ضبطهما للكاميرا هما قيمتا لوحي القص Clipping plane البعيد والقريب. مبدئيا، تستطيع الكاميرات ثلاثية الأبعاد أن «ترى» إلى مسافة لا متناهية (على النقيض من المشاهد الواقعية)، أي لا توجد محدوديات في العدسات المستعملة في الكاميرات ثلاثية الأبعاد ولا توجد جزئيات في طبقات الجو تعرقل رؤيتها. يُشار إلى ذلك في الألعاب بالمصطلح «مسافة الرؤية» (أو مسافة الرسم، Draw distance)، وهذا هو أحد أسباب استخدام الضباب في الألعاب ثلاثية الأبعاد القديمة: فكلما قلَّ عدد العناصر التي يجب تحميلها كانت اللعبة أسرع. وفي حالتنا، نريد أن يكون لوح القص القريب Near clipping plane قريبًا جدًا إلى «عدسة» الكاميرا، ولوح القص البعيد Far clipping plane على مسافةٍ معقولة، وبالتالي ستحتوى العناصر التي نريد عرضها بين هذين اللوحين. الشفرة التي سنستعملها لفعل ذلك هي: camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); أصبحتَ لدينا الآن كاميرا ثلاثية الأبعاد، لكنها موجودة في فضاء أسود لا متناهي، ولا تُشير إلى أيّ شيءٍ بعد؛ لكننا سنشرح في الدرس القادم طبيعة الفضاء ثلاثي الأبعاد، وكيفية إضاءته، وطريقة إضافة العناصر إلى المشهد. ترجمة –وبتصرّف– للمقال Introduction to WebGL وللمقال A WebGL Tour of the Solar System: Mars, Part One لصاحبهما Dudley Storey.
×
×
  • أضف...