کار با WebGL از طریق three.js

گردآوری و تالیف : ارسطو عباسی
تاریخ انتشار : 08 فروردین 1397
دسته بندی ها : جاوا اسکریپت

WebGL امکانی است که در اکثر مرورگرهای وب پشتیبانی می‌شود و شما را قادر می‌سازد که از طریق جاوااسکریپت با المان‌های سه‌بعدی کار کنید. این کار موجب می‌شود که در اپلیکیشن‌ها و بازی‌های مبتنی بر مرورگر امکانات بسیار زیادی را دریافت کنند. 

WebGL به صورت پیشفرض دارای امکانات کمی است و بعید به نظر می‌رسد که در چنین حالتی شما از آن استفاده کنید. بنابراین بسیاری از موتورهای بازی‌سازی و کتاب‌خانه‌های مختلف به وجود آمده‌اند که کارایی این مورد را بالاتر برده‌اند و استفاده‌پذیری آن را بیشتر ساخته‌اند.

در این مطلب قصد دارم به شما شیوه ساخت یک وبسایت یا اپلیکیشن را با استفاده از WebGL و three.js که یک کتابخانه متن باز است و مفهوم اولیه WebGL را برای‌مان پیاده‌سازی می‌کند، را آموزش دهم. 

1. three.js را دریافت کنید

در ابتدای کار نیاز است که آخرین نسخه از three.js را دریافت کرده و در پوشه پروژه‌تان قرار دهید. بعد از آن مانند دیگر کتابخانه‌ها فایل جاوااسکریپتی را به پروژه‌تان اضافه کنید. حال یک فایل دیگر جاوااسکریپت نیز برای ساختن پروژه‌مان را تهیه کنید. -کدهای جاوااسکریپت را به صورت مستقیم در فایل HTML نمی‌گذاریم-.

 

Getting started with three.js

2. صحنه را آماده کنید

برای شروع به کار با WebGL ما به سه چیز نیاز داریم: یک صحنه، یک دوربین و یک رندر. منظور از صحنه جایی است که از طریق three.js ما اشیاء و المان‌های‌مان را قرار می‌دهیم. دوربین منظور از نقطه‌ای است که ما صحنه را مشاهده می‌کنیم. در نهایت رندر نیز با تلفیق این دو، براساس کارهایی که انجام می‌دهیم کلیت ماجرا را برای ما فراخوانی می‌کند. بعد از اینکه ما اولین مراحل را پیاده‌سازی کردیم، یک رندر را به صفحه اضافه می‌کنیم.

var width = window.innerWidth;
var height = window.innerHeight;
var viewAngle = 45;
var nearClipping = 0.1;
var farClipping = 9999;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( viewAngle, width / height, nearClipping, farClipping );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );

3. یک حلقه درست کنید

بعد از این‌کار برای اینکه واقعا صحنه را رندر کنیم، نیاز است که یک حلقه ایجاد کنیم. ما این‌کار را از طریق تابع renderer.render() انجام می‌دهیم، اما هدف اصلی ما این است که به صورت بازگشتی از تابع requestAnimationFrame() استفاده کنیم، این تابع وقتی یک فریم آماده بود، مرورگر را قادر می‌سازد که فریم‌های بعدی را درخواست کند. استفاده از requestAnimationFrame() باعث می‌شود که انیمیشنی بهتر و نرم‌تر نسبت به ساختن یک حالت زمان‌بندی است.

function animate() {
  requestAnimationFrame( animate );
  renderer.render( scene, camera );
}
animate();

4. ساخت اشیاء پایه

حال ما آماده هستیم که یک‌سری شئ به صحنه‌مان اضافه کنیم. ما می‌توانیم این کار را با ساختن شئ‌های Mesh و اضافه کردن آن‌ها به صحنه انجام دهیم. یک شئ Mesh تشکیل شده از یک شکل هندسی -برای قالب‌بندی کلی- و یک رنگ یا پترن -برای نمایش قالب‌بندی- است. ما برای ساخت شئ‌مان از سه شکل هندسی استفاده می‌کنیم و بعد از آن رنگ های مورد نظرمان را به آن‌ها می‌دهیم.

var cubeGeometry = new THREE.BoxGeometry( 1, 1, 1 );
var cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xff0000 } );
var cube = new THREE.Mesh( cubeGeometry, cubeMaterial );
var coneGeometry = new THREE.ConeGeometry( 0.5, 1, 4 );
var coneMaterial = new THREE.MeshLambertMaterial( {color: 0x00ff00} );
var cone = new THREE.Mesh( coneGeometry, coneMaterial );
var sphereGeometry = new THREE.SphereGeometry( 0.5, 8, 8 );
var sphereMaterial = new THREE.MeshLambertMaterial( { color: 0x0000ff } );
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );

5. یک موقعیت تعیین کنید

به صورت پیشفرض اشیا‌ء ما در قسمت پیشفرض صحنه (x=0 , y=0, z=0) قرار دارد، درست به همین شکل دوربین ما نیز نمایش داده می‌شود. بنابراین ما نیاز داریم که موقعیت اولیه درستی را به آن‌ها بدهیم. بعد از آن باید مش‌های‌مان را به صحنه اضافه کنیم که در این صورت به حالت خودکار با استفاده از حلقه animation() همه چیز رندر می‌شود.

cube.position.x = -2
cube.position.z = -5;
cone.position.z = -5;
sphere.position.z = -5;
sphere.position.x = 2;
cube.position.z = -5;
scene.add(cube);
scene.add(cone);
scene.add(sphere);

6. یک منبع نور اضافه کنید

اگر به پروژه‌تان نگاهی بیاندازید متوجه می‌شوید که همه چیز به نظر کمی تخت می‌آید. به آن‌ها هیچ نوری داده نشده، بنابراین شکل یک شکل دوبعدی را به خود گرفته است. برای اینکار نیاز داریم که از حالت MeshBasicMaterial به یک متریال دیگر که نوردهی را پشتیبانی می‌کند سوئیچ کنیم، ما از MeshLambertMaterial استفاده می‌کنیم. در کنار اشیاء باید کمی به صحنه‌مان نیز نوردهی را اضافه کنیم.

var light = new THREE.PointLight(0xFFFFFF);
light.position.x = 0;
light.position.y = 10;
light.position.z = 0;
scene.add(light);

7. منبع را تکان دهید

بعد از این کار باید وجود شی‌هایی که به صورت سه‌بعدی در صحنه قرار گرفته‌اند را مشخص کنید. چیزی که ما هنوز انجام نداده‌ایم استفاده کامل از تابع animation است. بیاید کمی با من منبع نوری‌مان کار کنیم و آن را جابجا کنیم.

var lightAngle = 0;
function animate() {
  lightAngle += 5;
  if (lightAngle > 360) { lightAngle = 0;};
  light.position.x = 5 * Math.cos(lightAngle * Math.PI / 180);
  light.position.z = 5 * Math.sin(lightAngle * Math.PI / 180);
  requestAnimationFrame( animate );
  renderer.render( scene, camera ); }

8. بافت‌ها را اضافه کنید

در این تمرین، مطمئنا قصد نداریم که اشیاء‌مان را به صورت رنگ‌های تخت مشاهده کنیم. اضافه کردن بافت‌ها و الگوهای دیگری به شئ‌ها به نظر جالب‌تر می‌آید. ما می‌توانیم برای این‌کار از THREE.TextureLoader() استفاده کنیم. ما می‌توانیم از طریق این تابع، بافت‌مان را از طریق یک فایل اضافه کنیم. بنابراین می‌شود به صورت زیر عمل کرد:

var textureLoader = new THREE.TextureLoader();
textureLoader.load("./grass_texture.jpg", texture => {
  var coneGeometry = new THREE.ConeGeometry( 0.5, 1, 4 );
  var coneMaterial = new THREE.MeshLambertMaterial( { map: texture } );
  var cone = new THREE.Mesh( coneGeometry, coneMaterial);
  cone.position.z = -5;
  scene.add(cone);
  },
);

9. آن را طبیعی کنید

مواردی که ساختیم بهتر شدند اما هنوز کاملا طبیعی نیستند. الگوهای ما بیشتر تخت به نظر می‌رسند و هنوز نسبت به منبع نوری خوب جواب نمی‌دهند. برای این کار می‌توانیم از تکنیک نقشه‌کشی استفاده کنیم، این تکنیک به ما این قابلیت را می‌دهد که بتوانیم الگوهای‌مان را روی یک شئ دیگر که معمولا سطح صافی‌ست پیاده‌سازی کنیم. در این مرحله حالت مش را به صورت MeshPhongMaterial تغییر می‌دهیم. 

var textureLoader = new THREE.TextureLoader();
textureLoader.load("./bump_map.jpg", texture => {
  var sphereGeometry = new THREE.SphereGeometry( 0.5, 8, 8 );
  var sphereMaterial = new THREE.MeshPhongMaterial( { color: 0x0000ff, bumpMap: texture, bumpScale: 1.0 } );
  var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
  sphere.position.z = -5;
  sphere.position.x = 2;
  scene.add(sphere);
  },
);

10. اضافه کردن کنترل‌ها

به عنوان یک نقطه پایانی، می‌توانید به کاربر قابلیت کنترل روی صحنه را بدهید. برای چنین کاری ما نیاز داریم که کتابخانه دیگری را نیز به پروژه‌مان اضافه کنیم. این کتابخانه نیز متعلق به three.js است. برای اضافه کردن آن باید OrbitControls.js را بیابید. این کتابخانه چندین حالت کنترلی را به ما می‌دهد که می‌شود از آن‌ها در پروژه‌مان بهره ببریم.

 

11. اعمال کردن روی دوربین

حال تنها کاری که نیاز است انجام دهیم این است که از شئ THREE.OrbitControls استفاده کنیم و آن را روی دوربین‌مان اعمال کنیم. این کتابخانه همه کارها را برای شما انجام می‌دهد و نیازی نیست که نگران حرکت ماوس و چیزهای دیگر شوید. 

camera.position.z = 10;
var controls = new THREE.OrbitControls( camera );

منبع

مقالات پیشنهادی

10 نکته برای داشتن تجربه کاربری بهتر در موبایل

لایه ها، فرم ها، فونت ها و موارد دیگر، چیزهایی هستند که در هنگام طراحی وبسایت باید آنها را در نظر بگیرید. جدای از آن شما باید در رابطه با اینکه این ال...

5 سوال ساده برای وقتی که به دنبال بازخورد کاربر هستید

شما نمی توانید اولین برداشت را از نو بسازید درسته؟ البته که درسته و این یکی از دلایلی است که باید وقت و تلاش زیادی صرف طراحی یک وب سایت کنید . شما می...

۴ اشتباه تجربه کاربری که تقریبا هر طراحی مرتکب می شود

به عنوان یک طراح، احتمالا همیشه، بارها و بارها انتظار دارید که بتوانید غیر ممکن را ممکن سازید. همیشه انتظار دارید که یک کار پیچیده را دریافت کنید و آن...

حس اتوماتیک سازی کارهای front-end با gulp

سلام خدمت همه ای کاربرهای راکت ، این یک مقاله اختصاصی از وبسایت راکت هست امیدوارم مورد استفاده اتون قرار بگیره و بیشتر با زبان محاوره ای سعی به نوشتن...