אז בשביל ליצור אפקט של מטבע מסתובב צריך לקחת בחשבון שיש למטבע שני צדדים וצריך לשים ציורים שונים על כל אחד מהצדדים. מכוון ש threejs ואוביקט הצילינדר בפרט , לא ממש מאפשר זאת, כלומר אפשר לעשות הכל עם webgl אבל אנחנו בקורס תכנות חינמי, בסיסי ומקוצר אז נעשה כמה טריקים על מנת ליצר אפקט זה ולא נבנה מטבע של ממש כי זה דורש כבר התעסקות עם shaders. אז כרגיל, השיעורים הקודמים לרשותכם:
להלן רצף השיעורים בקורס תכנות משחקים – webgl
- קורס תכנות משחקים – webgl – שיעור ראשון – הקמת הפרויקט
- קורס תכנות משחקים – webgl – שיעור שני- הסצנה והמצלמה
- קורס תכנות משחקים – webgl – שיעור שלישי- ציור של אובייקט המטבע
- קורס תכנות משחקים – webgl – שיעור רביעי- תנועה של האובייקט הגרפי במרחב
שימוש בתאורה AmbientLight , PointLight ושימוש ב TextureLoader
נתחיל עם החלק היותר משעשע וזה לשים תאורה על האובייקטים בקאנווס. Threejs מציע פתרונות נהדרים לשימוש בתאורה , אם לומר את האמת לא יצא לי לעשות הרבה שימוש בתאורה אז אשתף משהו בסיסי ביותר וגם בשביל הפרקטיקה שלנו ושל הקורס הזה בחרתי להשתמש בכמה סוגי תאורה רק בשביל המשחק ולא באמת חייב לשים את כל התאורות שבחרתי לשים אם זה לא נראה מספיק יפה בעינייכם. אז בואו נכיר את החברים החדשים:
- AmbientLight – אפשרות זו מייצר תאורה באופן כללי על כל האובייקטים בסצנה באופן שווה.
- PointLight – אור הנפלט מנקודה ספציפית לכל כיוון שתבחרו. מקבל :צבע, חוזק , טווח , עמעום
וגם נגדיר את הטקסטרה של המטבע והצבע שלו וככה נסיים את העבודה על נראות המטבע שלנו, אז צבע כבר ראינו איך עושים בשיעורים הקודמים ובשביל טקסטורה נתשמש ב TextureLoader שמאפשר לנו לטעון תמונה ו Three יודע להלביש את האובייקט בהתאמה . כמו כן יש פעמים שתדרש תמונה בפרופורציות מסויימות על מנת שהטקסטורה תשב היטב, במקרה שלנו בחרתי תמונה ריבועית בלי צבע רגע בלי מרווחים בכלל.
ועכשיו נמשיך אל תוך הקוד ונמשיך בהסברים:
import React, { Component } from 'react'; import * as THREE from 'three'; import side1 from './side1.png'; import side2 from './side2.png'; class Coin extends Component { constructor(props) { super(props); this.state = { textureSide1: new THREE.TextureLoader().load(side1), textureSide2: new THREE.TextureLoader().load(side2) }; this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); this.scene = new THREE.Scene(); this.renderer = null; this.cylinder = null; this.canvasRef = React.createRef(); } initialObj() { this.camera.position.z = 200; this.renderer = new THREE.WebGLRenderer({ canvas: this.canvasRef.current, }); this.renderer.setPixelRatio(window.devicePixelRatio); this.renderer.setSize(window.innerWidth, window.innerHeight); } componentDidMount() { this.initialObj(); this.addLights(); this.createShape(); this.animate(); } createShape() { const geometry = new THREE.CylinderGeometry(10, 10, 1, 100); const material = new THREE.MeshStandardMaterial({ map: this.state.textureSide1, color: 0xFFD700, metalness: 0.3, roughness: 0.3 }) this.cylinder = new THREE.Mesh(geometry, material); this.cylinder.rotation.x = Math.PI / 2; this.cylinder.rotation.y = Math.PI / 2; this.scene.add(this.cylinder); } addLights() { this.scene.add(new THREE.AmbientLight(0xffffff)) // Left point light const pointLightLeft = new THREE.PointLight(0xff4422, 1) pointLightLeft.position.set(-20,-10,10) this.scene.add(pointLightLeft) // Right point light const pointLightRight = new THREE.PointLight(0x44ff88, 1) pointLightRight.position.set(20,10,10) this.scene.add(pointLightRight) // Top point light const pointLightTop = new THREE.PointLight(0xdd3311, 1) pointLightTop.position.set(0,3,2) this.scene.add(pointLightTop); } animate() { const spininngCoin = setInterval(() => { this.cylinder.rotation.z += 0.01; this.renderer.render(this.scene, this.camera); }); } render() { return ( <canvas ref={this.canvasRef} className="canvasClass"></canvas> ) } } export default Coin;
איזה יופי של קוד מתחיל להיות לנו פה, ועוד לא הגענו לחלק האומנתי 🙂 .
הוספנו לא מעט דברים , אפשר לראות ששינתי מעט את המטודה של createShape קודם כל שיניתי את basicMaterial ל MeshStandardMaterial שמאפשר לנו יותר מאפייני עיצוב וככה אפשר לשים גם תמונה וגם לשחק עם השילוב בין התמונה לצבעים ולקבל טקסטורה שתיתן תחושה יותר קרובה ללוק של מטבע מוזהב. וכמובן הוספה של התיאורה עם מטודה חדשה שמוסיפה 4 סגנונות תאורה בצבעים ומיקומים שונים, תוכלו גם לשחק עם הערכים על מנת להבין מה כל ערך עושה , כל העניין של להבין את האפשרויות זה דרך ניסויים ומשחק עם הערכים השונים.
לאחר מכן נקרא למטודה החדשה ב componentDidMount. והנה לנו מטבע נחמד עם טקסטורה. שימו לב שכבר ייבאנו 2 תמונות לשני הצדדים ושמרנו אותם ב state . כמו כן כרגע נעשה שימוש רק בצד אחד ובהמשך ניישם את השימוש בשני הצדדים.

סיכום שיעור חמישי webgl | תכנות משחקים
קיבלנו כבר צורה למשחק שלנו ואנחנו קרובים לסיומו , יש לנו עוד מעט לוגיקה לבצע שזהו חלק מעניין ודורש קצת מתמטיקה בסיסית. ולאחר מכן קצת עבודה של UI ואנחנו מסיימים. ולסיכום השיעור הזה, מציע לכם לקרוא וללמוד את כל האפשרויות שמגישים לנו three בעניין של עיצוב וצביעה ככה תוכלו לייצר אובייקטים יפים שישדרגו כל אתר או אפליקציה שתעשו. אם תגיעו לעולמות של shaders שזה עולם שלם של צביעה של קודקודים אז הרחקתם לכת כי לדעתי זה משהו מתקדם מאוד ולא נגע בו כלל בקורס הזה. אולי בקורס אחר שיהיה מבוסס shades.
בהצלחה! ❤🐊