תחילת העבודה עם Three.js

מבוא

השתמשתי ב-Three.js עבור חלק מהניסויים שלי, והוא עוזר מאוד לבטל את הטרחה הכרוכה בשימוש בתלת-ממד בדפדפן. בעזרתה אפשר ליצור מצלמות, אובייקטים, תאורה, חומרים ועוד, ויש לכם בחירה של כלי לעיבוד, כך שתוכלו להחליט אם אתם רוצים שהסצנה תשורטט באמצעות לוח הציור של HTML 5, WebGL או SVG. ומכיוון שמדובר בקוד פתוח, אתם יכולים אפילו לקחת חלק בפרויקט. אבל עכשיו אני אתמקד במה שלמדתי בזכות השימוש בו כמנוע, ואספר לכם על כמה מהיסודות.

למרות המגניבות המדהימה של Three.js, לפעמים קשה מאוד. בדרך כלל צריך להקדיש הרבה זמן לדוגמאות, להנדסה הפוכה ו (במקרה שלי בהחלט) לחיפוש פונקציונליות ספציפית ומדי פעם לשאול שאלות דרך GitHub. אם אתה צריך עוד שאלות, דרך אגב, מר. דוב ו-AlteredQualia מועילים מאוד!

1. העקרונות הבסיסיים

אני מניח שיש לך לפחות ידע חולף בתלת-ממד, ובקיאות סבירה ב-JavaScript. אם לא תענו על השאלות האלה, אולי כדאי ללמוד קצת לפני שתנסו להתנסות בהן, כי זה עלול להיות מבלבל.

בעולם התלת-ממד שלנו יהיו חלק מהדברים הבאים, שאדריך אותך בתהליך היצירה:

  1. סצנה
  2. כלי לעיבוד
  3. מצלמה
  4. אובייקט או שניים (עם חומרים)

כמובן שתוכל לעשות כמה דברים מגניבים, ואני מקווה שתמשיכו לעשות זאת ותתחילו להתנסות בתלת ממד בדפדפן שלכם.

2. תמיכה

רק הערה קצרה על התמיכה בדפדפנים. מניסיוני, דפדפן Chrome של Google הוא הדפדפן הטוב ביותר לעבודה בכל הנוגע למאפשרים הנתמכים ולמהירות של מנוע ה-JavaScript שבבסיסו. Chrome תומך ב-Canvas, WebGL ו-SVG, והמהירות שלו גבוהה במיוחד. Firefox הוא גרסה 4 עם השקתה של גרסה 4. נראה שמנוע ה-JavaScript שלו איטי בנגיעה מזו של Chrome, אבל שוב התמיכה שלו בטכנולוגיות העיבוד נהדרת. אופרה ו-Safari בתהליך הוספה של תמיכה ב-WebGL, אבל הגרסאות הנוכחיות שלהם תומכות רק באזור העריכה. Internet Explorer (גרסה 9 ואילך) תומך בעיבוד בד ציור בלבד, ולא שמעתי דבר על התכנון של Microsoft להוסיף יכולות WebGL.

3. הכנת הסצנה

אני מניח שבחרתם דפדפן שתומך בכל טכנולוגיות העיבוד, ושאתם רוצים לעבד אותן באמצעות בד קנבס או WebGL, כי אלו האפשרויות הסטנדרטיות יותר. ב-Canvas יש תמיכה רחבה יותר מאשר WebGL, אבל חשוב לציין ש-WebGL פועל על ה-GPU של הכרטיס הגרפי, כך שהמעבד (CPU) יכול להתרכז במשימות אחרות שלא ניתן לעבד, כמו כל פעולה בפיזיקה או באינטראקציה עם המשתמש שמנסים לבצע.

חשוב לזכור שצריך להתאים את ה-JavaScript לביצועים, בלי קשר לרינדור שבחרתם. תלת-ממד אינו משימה קלה לדפדפן (וזה מדהים שאפשר לעשות זאת), לכן חשוב שתקפיד להבין היכן יש בקוד שלך צווארי בקבוק, ולהסיר אותם במידת האפשר!

במילים אחרות, ובהנחה שהורדתם וכללתם את הקובץ3.js בקובץ ה-HTML, איך אתם מגדירים סצנה? תוכל לעשות זאת כך:

// set the scene size
var WIDTH = 400,
HEIGHT = 300;

// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
                VIEW_ANGLE,
                ASPECT,
                NEAR,
                FAR );

var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;

// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

לא יותר מדי, באמת!

4. יצירת רשת

יש לנו סצנה, מצלמה ורינדור (בחרתי ל-WebGL בקוד לדוגמה שלי) אבל אין לנו מה לצייר. Three.js למעשה כולל תמיכה בטעינה של מספר סוגי קבצים סטנדרטיים שונים, וזה מעולה אם אתם יוצרים פלט של מודלים מ-Bleender, Maya, Cine4D או כל דבר אחר. כדי לפשט את הדברים (כלומר, להתחיל אחרי הכול!) אני אדבר על פרימיטיבים. פרימיטיבים הם רשתות גיאומטריות, רשתות בסיסיות יחסית כמו כדורים, מישורים, קוביות וגלילים. Three.js מאפשר ליצור בקלות את הסוגים הבאים של פרימיטיבים:

// set up the sphere vars
var radius = 50, segments = 16, rings = 16;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),

sphereMaterial);

// add the sphere to the scene
scene.add(sphere);

הכול טוב, אבל מה לגבי החומר של כדור הארץ? בקוד השתמשנו במשתנה sphereMaterial, אבל עדיין לא הגדרנו אותו. קודם כל, צריך לדבר על חומרים יותר לעומק.

5. חומרים

ללא ספק, זהו אחד מהחלקים השימושיים ביותר של Three.js. יש בו כמה חומרים נפוצים (ומועילים מאוד) שאפשר להשתמש בהם ברשתות:

  1. 'בסיסי' – כלומר, הוא מופיע כ 'לא מואר'
  2. למברט
  3. פונג

יש עוד, אבל שוב כדי לשמור על פשטות, אני אאפשר לך לגלות אותן בעצמך. במיוחד במקרה של WebGL, חומרים אלה יכולים להציל חיים. למה? כי ב-WebGL צריך לכתוב תוכנות הצללה לכל מה שעובר רינדור. צימרים הם נושא עצום בפני עצמם, אבל בקצרה הם נכתבים ב-GLSL (שפת OpenGL Shader), שאומרים ל-GPU איך משהו אמור להיראות. כלומר, צריך לחקות את החישובים המתמטיים של תאורה, השתקפות וכן הלאה. זה יכול להיות מסובך מאוד מהר. הודות ל-Three.js, אתם לא צריכים לעשות זאת אם אתם לא רוצים לעשות זאת, כי זה מפשט את זה עבורכם. עם זאת, אם רוצים לכתוב תוכנות הצללה, אפשר לעשות גם את זה עם MeshShaderMaterial, כך שזו הגדרה גמישה.

עם זאת, בינתיים נחיל חומר למברט על הכדור:

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});

כדאי גם לציין שיש מאפיינים אחרים שאפשר לציין כשיוצרים חומר נוסף מלבד הצבע, כמו החלקה או מפות סביבה. כדאי לבדוק בדף ה-Wiki את המאפיינים השונים שאפשר להגדיר לחומרים, ולמעשה, על כל אובייקט שהמנוע מספק לכם. כמו כן, לאחרונה השקנו את threejs.org, המציעות תצוגה אטרקטיבית יותר של ה-API.

6. להדליק אורות!

אם תעבדו את הסצנה עכשיו, תראו עיגול אדום. למרות שאנחנו משתמשים בחומר למברט, אין אור בסביבה, ולכן כברירת מחדל, Three.js יחזור לאור סביבתי מלא, שזהה לצבע אחיד. נתקן את זה באמצעות נקודת אור פשוטה:

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);

7. עיבוד

עכשיו למעשה יש לנו הכול מוגדר לעיבוד, למרבה הפלא. אבל בעצם אנחנו צריכים לעשות את זה:

// draw!
renderer.render(scene, camera);

אבל סביר להניח שתרצו לעבד יותר מפעם אחת, כך שאם אתם מתכוונים ליצור לולאה, כדאי לכם להשתמש ב-requestAnimationFrame. זו דרך מאוד חכמה לטפל באנימציה בדפדפן. הכלי עדיין לא נתמך באופן מלא, ולכן אני ממליץ לך מאוד לקרוא את Paul Ireland's shim.

8. מאפייני אובייקט נפוצים

אם תעיינו בקוד של Three.js, תראו הרבה אובייקטים ש'יורשים' מ-Object3D. זהו אובייקט בסיס שמכיל כמה מאפיינים שימושיים מאוד, כמו פרטי ה-position, rotation ו-scale. באופן ספציפי, כדור הארץ הוא רשת רשת שיורשת מ-Object3D, שאליו היא מוסיפה מאפיינים משלה: geometry ו-materials. למה אנחנו מציינים את זה? סביר להניח שלא תרצו להשתמש בכדור במסך שלא עושה דבר, וכדאי לבדוק את המאפיינים האלה, כי הם מאפשרים לכם לבצע מניפולציה על הפרטים הבסיסיים של הרשתות והחומרים בזמן אמת.

// sphere geometry
sphere.geometry

// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array

// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same

9. סודות קטנים

רציתי רק להסביר בקצרה את התהליך של Three.js, שאם משנים, לדוגמה את הקודקוד של רשת, תראו ששום דבר לא משתנה. למה? כי Three.js (עד כמה שאני יכול) שומר את הנתונים של הרשת במטמון, בתור אופטימיזציה. מה שצריך לעשות בפועל הוא לסמן ל-Three.js שמשהו השתנה כדי שיוכל לחשב מחדש את מה שצריך. תוכלו לעשות זאת בדרכים הבאות:

// changes to the vertices
sphere.geometry.__dirtyVertices = true;

// changes to the normals
sphere.geometry.__dirtyNormals = true;

שוב יש עוד, אבל שני הסוגים האלה שמצאתי הם השימושיים ביותר. כמובן שחשוב לסמן רק את הדברים שהשתנו, כדי למנוע חישובים מיותרים.

סיכום

אני מקווה שהמבוא הקצר הזה ל-Three.js הועיל לכם. אין משהו כמו ללכלך את הידיים ולנסות משהו, ואני לא יכולה להמליץ על זה מספיק. כיף מאוד לרוץ בתלת-ממד בדפדפן ושימוש במנוע כמו Three.js חוסך לכם הרבה כאבי ראש ומאפשר לכם ליצור דברים מגניבים במיוחד. כדי לעזור לכם קצת, הגדרתי את קוד המקור במאמר שיעור ה-Lab הזה, כך שתוכלו להיעזר בו. אם נהניתם, אשמח לדעת דרך Twitter, תמיד אפשר להגיד לי שלום!