BabylonJS - ตาข่าย

ในบทนี้เราจะเรียนรู้การสร้างรูปทรงต่างๆโดยใช้ตัวสร้างตาข่าย เราได้เรียนรู้วิธีสร้างรูปร่างในบทก่อนหน้านี้แล้ว

ความแตกต่างคือด้วย meshbuilder ช่วยให้คุณมีความยืดหยุ่นในการเพิ่มสีรูปภาพให้กับรูปร่าง

CreateBox โดยใช้ MeshBuilder

ตอนนี้ให้เราดูวิธีสร้างกล่องโดยใช้ MeshBuilder

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
            
            var texture = new BABYLON.Texture("images/cube.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            for (var i = 0; i < 6; i++) {
               faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
            }

            var options = {
               width: 1.5,
               height: 1.5,
               depth: 1.5,
               faceUV: faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

สำหรับตัวอย่างข้างต้นเราได้ใช้ภาพสไปรท์ดังที่แสดงด้านล่าง มีคอลัมน์แนวนอน 3 คอลัมน์และแนวตั้ง 2 แถว

ในการสาธิตนี้เราได้ใช้ภาพที่เรียกว่า cube.png ภาพจะถูกเก็บไว้ในภาพ / โฟลเดอร์ในเครื่องและวางไว้ด้านล่างเพื่อใช้อ้างอิง โปรดทราบว่า cube.png เป็นภาพสไปรท์ภาพสไปรท์คือชุดของภาพ เราต้องการแสดงภาพบนลูกบาศก์ดังนั้นต้องการให้ทุกด้านของลูกบาศก์รวมกัน คุณยังสามารถดาวน์โหลดภาพสไปรท์ที่คล้ายกันที่คุณเลือกและใช้ในลิงค์สาธิต

ตัวสร้าง createBox ช่วยให้คุณมีตัวเลือกสำหรับขนาด

ตัวอย่างเช่น,

var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);

การสาธิต

var hSpriteNb =  3;  // 3 sprites per raw ie colums horizontally as shown in the image

var vSpriteNb =  2;  // 2 sprite raws as shown in the image above.

var faceUV = new Array(6); // the cube has 6 sides so creating array for same.
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

var options = {
   width: 1.5,
   height: 1.5,
   depth: 1.5,
   faceUV: faceUV
};

เรียกว่าการใช้พื้นผิวกับ meshbuilder โดยใช้เมธอด createBox เราได้ใช้ภาพ cube.png ซึ่งมี 3 คอลัมน์แนวนอนและ 2 แถวในแนวตั้งลูกบาศก์หรือกล่องมี 6 ด้าน

ในการใช้พื้นผิวเรากำลังใช้พารามิเตอร์ตัวเลือกตัวอย่างเช่น

Var box = BABYLON.MeshBuilder.CreateBox ('box', options, scene);

เราได้กำหนดอาร์เรย์ที่เรียกว่า faceUV โดยมีขนาดเป็น 6 ซึ่งเป็นด้านข้างของลูกบาศก์ อาร์เรย์นี้จะมีองค์ประกอบ Vector4 เสมอ Vector4 (x, y, z, w) แต่ละตัวจะถูกกำหนดดังนี้ -

  • x = Ubottom
  • y = Vbottom
  • z = Utop
  • w = Vtop

เวกเตอร์อยู่ในช่วง [0, 1] Ubottom และ Vbottom เป็นพิกัด 2 มิติของจุดล่างซ้ายของจุดเริ่มต้นของการครอบตัดพื้นผิว Utop, Vtop คือจุดบนขวาที่การครอบตัดพื้นผิวสิ้นสุดลง

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

สมมติว่าพื้นผิวเริ่มต้นเช่นภาพที่กำหนดจะถูกนำไปใช้กับทุกใบหน้าของกล่อง หากคุณต้องการเปลี่ยนเพียง 1 ใบหน้าหรือ 1 ด้านของกล่องคุณสามารถกำหนดค่าได้โดยตรงตามที่แสดงด้านล่าง -

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

ตัวอย่าง

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var texture = new BABYLON.Texture("images/3d.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

            var options = {
               width:3,
               height:3,
               depth: 3,
               faceUV:faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

ในการสาธิตนี้เราได้ใช้ภาพที่เรียกว่า 3d.png ภาพจะถูกเก็บไว้ในภาพ / โฟลเดอร์ในเครื่องและวางไว้ด้านล่างเพื่อใช้อ้างอิง โปรดทราบว่า 3d.png เป็นภาพสไปรท์ ภาพสไปรท์คือชุดของภาพ เราต้องการแสดงภาพบนลูกบาศก์โดยให้ด้านทั้งหมดของลูกบาศก์อยู่ด้วยกัน คุณยังสามารถดาวน์โหลดภาพสไปรท์ที่คล้ายกันที่คุณเลือกและใช้ในลิงค์สาธิต

พื้นผิวที่ใช้สำหรับกล่อง - images/3d.png

MeshCylinder

ในส่วนนี้เราจะดูวิธีสร้าง MeshCylinder

ในการสร้าง MeshCylinder คุณต้องใช้คลาส BABYLON.MeshBuilder.CreateCylinder

พารามิเตอร์สำหรับคลาสมีดังนี้ -

var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
   height: 3,
   diameter: 35,
   tessellation: 52
}, scene);

ความแตกต่างระหว่าง CreateCylinder โดยใช้ mesh และ meshbuilder คือ - คุณสามารถใช้ตัวเลือกใน meshbuilder ตอนนี้เรากำลังใช้ความสูงเส้นผ่านศูนย์กลางและการเทสเซลล์เป็นตัวเลือกที่จะส่งไปยังกระบอกสูบ เราใช้วัสดุมาตรฐานพร้อมโครงลวดเป็นวัสดุสำหรับตาข่ายนี้ ตรวจสอบผลลัพธ์ในเบราว์เซอร์และดูกระบอกสูบ คุณสามารถใช้โครงสร้างที่คล้ายกันในเกมของคุณเป็นวงล้อที่หมุนในฉาก

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>Babylon.js demo - Mesh Builder</title>
      <script src = "babylon.js"></script>
      <style>
         html,body,canvas { margin: 0; padding: 0; width: 100%; height: 100%; font-size: 0; }
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 6, 1.3, 40, new BABYLON.Vector3(0, -3, 0), scene);
            
            var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);

            var mat = new BABYLON.StandardMaterial("mat", scene);
            mat.diffuseColor = new BABYLON.Color3(0.1, .5, 0);
            mat.specularColor = new BABYLON.Color3(0, 0, 0);
            mat.wireframe = true;

            var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
               height: 3,
               diameter: 35,
               tessellation: 52
            }, scene);

            meshcylinder.material = mat;
            meshcylinder.position = new BABYLON.Vector3(0, 0, 0);

            scene.activeCamera.attachControl(canvas);
            return scene;
         };
         
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

ตอนนี้รูปร่างจำนวนมากที่สร้างด้วยตัวสร้างตาข่ายจะถูกนำมาใช้ร่วมกันในการสาธิตครั้งเดียว รูปร่างที่ครอบคลุมในลิงค์สาธิตด้านล่างแสดงอยู่ในส่วนต่อไป

  • Ground

  • Cone

  • Plane

  • Disc

  • Torus

  • Polyhedron

  • IcoSphere

BabylonJS - แยกตาข่ายและจุด

Mesh Intersection ในเกมมีความสำคัญเนื่องจากคุณรู้ว่าต้องทำอะไรเมื่อวัตถุ 2 ชิ้นมาตัดกันในเกม แนวคิดเดียวกันนี้ได้อธิบายไว้ในการสาธิตด้านล่างเกี่ยวกับเหตุการณ์ที่ต้องจับเมื่อตาข่ายตัดกัน

ในการสาธิตด้านล่างเราได้กล่าวถึงสองแนวคิดต่อไปนี้ -

  • ตัดตาข่าย
  • จุดตัดกัน
<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);
            
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var matcone = new BABYLON.StandardMaterial("mat1", scene);
            matcone.alpha = 1.0;
            matcone.diffuseColor = new BABYLON.Color3(0, 0, 0);
            matcone.wireframe = true;

            var cone = BABYLON.MeshBuilder.CreateCylinder("cone", {height : 10, diameterTop: 10,diameterBottom:10, tessellation: 5}, scene);
            cone.position= new BABYLON.Vector3(12,1,0);
            cone.material = matcone;	

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            var balloon3 = BABYLON.Mesh.CreateSphere("balloon3", 5, 1.0, scene);
            
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon3.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(4, 2, 0);
            balloon2.position = new BABYLON.Vector3(5, 1, 0);
            balloon3.position = new BABYLON.Vector3(7, 0, 0);

            var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
            var a = 0.01;
            
            scene.registerBeforeRender(function () {
               if (balloon1.intersectsMesh(cone, false)) {
                  balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon2.intersectsMesh(cone, false)) {
                  balloon2.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon2.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsMesh(cone, false)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsPoint(pointToIntersect)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
               }

               a += 0.01;
               balloon1.position.x += Math.cos(a) / 10;
               balloon2.position.x += Math.cos(a) / 10;
               balloon3.position.x += Math.cos(a) / 10;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -

คำอธิบาย

ด้วยรหัสด้านบนเราสร้างทรงกระบอกที่มีโครงร่างเป็นจริง เราสร้าง 3 Sphere สีเดิมของทรงกลมเป็นสีเขียว

ใน scene.registerBeforeRender ฟังก์ชันเราจะเปลี่ยนสีของทรงกลมตามจุดตัดกับตาข่ายซึ่งเป็นทรงกระบอกตรงนี้

พิจารณารหัสต่อไปนี้ใน registerBeforeRender -

if (balloon1.intersectsMesh(cone, false)) {
   balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
} else {
   balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
}

intersectsMesh ให้จริงหรือเท็จถ้ามันตัดกับตาข่ายที่กำหนดในพารามิเตอร์ที่ส่งผ่านไป

ตัวอย่างเช่น,

balloon1.intersectsMesh(cone, false); //cone refers to the cylinder mesh here.

สีของทรงกลมเปลี่ยนเป็นสีแดงตัดกับทรงกระบอก มิฉะนั้นจะเป็นสีเขียว

รหัสต่อไปนี้ใช้สำหรับจุดที่จะตัดกัน -

var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
if (balloon3.intersectsPoint(pointToIntersect)) {
   balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
}

ที่นี่ pointtoIntersectตัวแปรคือเวกเตอร์ตำแหน่งซึ่งมีค่า 10 บนแกน x หากทรงกลมข้ามจุดตัดกันสีของทรงกลมจะเปลี่ยนเป็นสีดำ

BabylonJS - MeshPicking Collision

การชนกันแบบเลือกจะทำให้คุณได้พิกัดและคุณสามารถวางตาข่ายของคุณในตำแหน่งนั้นได้ เมาส์จะเลือกวัตถุและคุณสามารถวางตำแหน่งที่คุณคลิกด้วยเมาส์ได้พิจารณาว่าคุณต้องวางตาข่าย (วัตถุ) ในตำแหน่งที่ผู้ใช้คลิกเมาส์ ดังนั้นด้วยความช่วยเหลือของการหยิบการชนกันจะช่วยให้คุณมีพิกัดที่ตำแหน่งของสถานที่ที่คลิก

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);

            // setup environment
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 10, 20), scene);
            var freeCamera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -30), scene);

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon2.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
            balloon2.material.emissiveColor = new BABYLON.Color3(0, 0, 1);

            //Wall
            var wall = BABYLON.Mesh.CreatePlane("wall", 30.0, scene);
            wall.material = new BABYLON.StandardMaterial("wallMat", scene);
            wall.material.emissiveColor = new BABYLON.Color3(0.5, 1, 0.5);

            //When pointer down event is raised

            scene.onPointerDown = function (evt, pickResult) {
               // if the click hits the ground object, we change the impact position
               if (pickResult.hit) {
                  var dateValue = new Date();
                  var secondNumber = dateValue.getSeconds();
                  if (secondNumber % 2 == 0) {
                  balloon1.position.x = pickResult.pickedPoint.x;
                  balloon1.position.y = pickResult.pickedPoint.y;
                  } else {
                     balloon2.position.x = pickResult.pickedPoint.x;
                     balloon2.position.y = pickResult.pickedPoint.y;
                  }
               }
            };
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

คำอธิบาย

ในตัวอย่างข้างต้นเราได้ใช้เครื่องบินและ 2 ทรงกลม ในการสร้างผลลัพธ์นี้ให้ใช้รหัสต่อไปนี้ -

scene.onPointerDown = function (evt, pickResult) {
   // if the click hits the ground object, we change the impact position
   if (pickResult.hit) {
      var dateValue = new Date();
      var secondNumber = dateValue.getSeconds();
      if (secondNumber % 2 == 0) {
      balloon1.position.x = pickResult.pickedPoint.x;
      balloon1.position.y = pickResult.pickedPoint.y;
      } else {
         balloon2.position.x = pickResult.pickedPoint.x;
         balloon2.position.y = pickResult.pickedPoint.y;
      }
   }
};

เหตุการณ์ scene.onPointerDown ให้ค่าพิกัด -x, y และ z ซึ่งในตัวอย่างของเราคือ pickResult.

จะให้ pickResult.hit เป็นจริงถ้าคุณคลิกบนกราวด์เมช เราพิจารณาวินาทีคี่ / คู่และเปลี่ยนตำแหน่งของทรงกลมเพื่อเลือกผลลัพธ์ z และ y พิกัดดังที่แสดงด้านบน เมื่อเปลี่ยนตำแหน่งแล้วทรงกลมจะถูกวางไว้ในตำแหน่งที่คุณคลิกและวางเมาส์ คุณสามารถลองใช้การสาธิตข้างต้นได้เช่นเดียวกัน

BabylonJS - Raycasts

เรย์คาสต์เปรียบเสมือนรังสีของดวงอาทิตย์และใช้เพื่อตรวจสอบการชนกันและทางแยกในฉาก

ไวยากรณ์

var ray = new BABYLON.Ray(origin, direction, length);

พารามิเตอร์

พิจารณาพารามิเตอร์ต่อไปนี้สำหรับเรย์คาสต์ -

  • Origin - สถานที่ที่จะเริ่มฉายรังสี

  • Direction - ทิศทางไปยังรังสีคำนวณได้ดังนี้ -

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

จากนั้นเพื่อให้ได้ทิศทางเราลบออกจากจุดเริ่มต้นตำแหน่งกล่อง -

  • Length - ความยาวของรังสี

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
           
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;

               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray);

               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

คำอธิบาย

มีกล่องหลักอยู่ตรงกลางซึ่งทำหน้าที่เป็นเรย์คาสต์ ขณะที่ชี้ไปที่กล่องใด ๆ ขนาดของกล่องจะเพิ่มขึ้น แนวคิดนี้พิสูจน์ได้ว่ามีประโยชน์ในขณะเล่นเกมเพื่อให้ทราบว่ามีวัตถุอื่นใดเข้ามาสัมผัสและสามารถดำเนินการที่จำเป็นได้

การเพิ่ม box.isPickable = false;เพื่อไม่ให้พิจารณากล่องหลักที่อยู่ตรงกลาง หากคุณไม่ต้องการให้วัตถุใด ๆ รวมอยู่ในรังสีสัมผัสให้เพิ่มbox.isPickable = false; ไปเลย

รหัสต่อไปนี้จะเพิ่มมาตราส่วนของกล่องที่เรย์เลือก

scene.registerBeforeRender(function () {
   var origin = box.position;	
   var forward = new BABYLON.Vector3(0,0,1);		
   forward = vecToLocal(forward, box);

   var direction = forward.subtract(origin);
   direction = BABYLON.Vector3.Normalize(direction);

   var length = 100;

   var ray = new BABYLON.Ray(origin, direction, length);

   var hit = scene.pickWithRay(ray);

   if (hit.pickedMesh) {
      hit.pickedMesh.scaling.y  += 0.01;
   }
});

var ray = new BABYLON.Ray(origin, direction, length); สร้างรังสีและใช้ตำแหน่งกล่องหลักเป็นจุดเริ่มต้น

ทิศทางไปยังรังสีคำนวณได้ดังนี้ -

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

จากนั้นเพื่อให้ได้ทิศทางเราลบออกจากจุดเริ่มต้นตำแหน่งกล่อง ฟังก์ชั่นvecToLocal ได้รับการออกแบบมาเพื่อเปลี่ยนตำแหน่งจากมุมมองแบบตาข่ายโดยการคูณเวกเตอร์ด้วยเมทริกซ์ตาข่าย

เราได้รับจุดตีจากรังสีโดยใช้ var hit = scene.pickWithRay(ray);

ให้ตำแหน่งที่รังสีตรงกับตาข่าย

การปรับมาตราส่วนจะถูกนำไปใช้กับตาข่ายซึ่งถูกเลือกโดยดำเนินการตามบรรทัดของโค้ดต่อไปนี้ -

if (hit.pickedMesh) {
   hit.pickedMesh.scaling.y  += 0.01;
}

ลองใช้ตัวอย่างข้างต้นในเบราว์เซอร์เพื่อดูผลลัพธ์

Raycast พร้อมฟังก์ชันเพรดิเคต

ตอนนี้ให้เราดูว่า raycast พร้อมฟังก์ชันเพรดิเคตทำงานอย่างไรและทิศทางที่แสดงด้วย rayhelper

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            //ray showing the direction
            var ray = new BABYLON.Ray();
            var rayHelper = new BABYLON.RayHelper(ray);

            var localMeshDirection = new BABYLON.Vector3(0, 0, -1);
            var localMeshOrigin = new BABYLON.Vector3(0, 0, -.4);
            var length = 10;

            rayHelper.attachToMesh(box, localMeshDirection, localMeshOrigin, length);
            rayHelper.show(scene);

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;
               function predicate(mesh) {
                  if (mesh == box2 || mesh == box || mesh == box5) {
                     return false;
                  }
                  return true;
               }
               
               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray, predicate);
               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

คำอธิบาย

Raycast พร้อมฟังก์ชันเพรดิเคตช่วยในการเลือกตาข่ายที่เราต้องการ หากเราไม่ต้องการให้มีการเลือกตาข่ายเราสามารถเพิกเฉยได้

function predicate(mesh) {
   if (mesh == box2 || mesh == box || mesh == box5) {
      return false;
   }
   return true;
}

ฟังก์ชั่นข้างต้นให้ตาข่ายซึ่งถูกเลือกโดยเรย์ ถ้าตาข่ายที่เลือกคือ box2 กล่องหรือ box5 มันจะส่งกลับเท็จ มิฉะนั้นจริง

คุณสามารถลองใช้ตัวอย่างข้างต้นได้เช่นเดียวกัน

BabylonJS - ตาข่ายเงา

เงาจะแสดงผลตามวิธีที่แสงตกกระทบบนตาข่ายที่สร้างขึ้น พวกเขามีบทบาทสำคัญในการทำให้ผลลัพธ์ดูสมจริงในโลก 3 มิติ

ตอนนี้ให้เราเรียนรู้วิธีสร้างเงาโดยใช้ babylonjs

ไวยากรณ์

var shadowGenerator00 = new BABYLON.ShadowGenerator(shadowsize, light);

พารามิเตอร์

พิจารณาพารามิเตอร์ต่อไปนี้ที่เกี่ยวข้องกับเงาตาข่าย -

  • Shadowsize - ขนาดของเงา

  • Light - แสงที่ใช้ในฉาก

การสาธิต

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);	
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            // light1
            var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -2, -1), scene);
            light.position = new BABYLON.Vector3(20, 40, 20);

            var ground01 = BABYLON.Mesh.CreateGround("Spotlight Hard Shadows", 24, 60, 1, scene, false);
            var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
            groundMaterial.diffuseTexture = new BABYLON.Texture("images/gr1.jpg", scene);
            groundMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
            groundMaterial.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);

            ground01.material = groundMaterial;
            ground01.receiveShadows = true;
            ground01.position.x = -5;

            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position.x = -5;
            box.position.y = 5;
            var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);
            shadowGenerator00.getShadowMap().renderList.push(box);
            //shadowGenerator00.usePoissonSampling = true;
            //shadowGenerator00.useExponentialShadowMap = true;
            shadowGenerator00.useBlurExponentialShadowMap = true;
            shadowGenerator00.bias = 0.01;
            scene.registerBeforeRender(function() {
               box.rotation.x += 0.01;
               box.rotation.x += 0.01;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

เอาต์พุต

บรรทัดโค้ดด้านบนสร้างผลลัพธ์ต่อไปนี้ -

คำอธิบาย

ในการสร้างเงาคุณต้องสร้าง Shadowgenerator พิจารณาตัวอย่างที่แสดงด้านล่าง

var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);

ในการกำหนดตาข่ายที่ต้องการเงาคุณต้องเพิ่มสิ่งเดียวกันกับตัวสร้างด้านบน

shadowGenerator00.getShadowMap().renderList.push(box);

ตอนนี้เราได้สร้างกราวด์และกล่องไว้ด้านบนแล้ว เราต้องการให้เงาของกล่องตกลงที่พื้น ในการทำเช่นนั้นเราต้องตรวจสอบให้แน่ใจว่าพื้นดินถูกทำเครื่องหมายเพื่อรับเงาซึ่งทำได้ดังนี้ -

ground01.receiveShadows = true;

มีฟิลเตอร์สำหรับเงาซึ่งมีดังต่อไปนี้ -

shadowGenerator.usePoissonSampling = true; - Called Poisson sampling 
shadowGenerator.useExponentialShadowMap = true; - Exponential Shadow Map
shadowGenerator.useBlurExponentialShadowMap= true;  - Blur Exponential Shadow Map

ในการสาธิตของเราเราได้ใช้ shadowGenerator00.useBlurExponentialShadowMap = true; คุณสามารถลองใช้ตัวอื่น ๆ และดูว่าผลลัพธ์มีลักษณะอย่างไร

ที่นี่เราใช้ภาพที่เรียกว่า gr1.jpg ภาพจะถูกจัดเก็บในภาพ / โฟลเดอร์ในเครื่อง คุณสามารถดาวน์โหลดรูปภาพที่คุณต้องการและใช้ในลิงค์สาธิต

BabylonJS - พื้นผิวขั้นสูงบนตาข่าย

ในส่วนนี้เราจะเรียนรู้เกี่ยวกับพื้นผิวขั้นสูงบนตาข่าย พื้นผิวที่แตกต่างกันแสดงไว้ด้านล่าง -

  • เนื้อลูกบาศก์

  • กระจกและพื้นผิว Bump

  • พื้นผิววิดีโอ

ให้เราใช้พื้นผิวที่ซับซ้อนบางอย่างกับตาข่ายเช่นกระจกกันกระแทกวิดีโอและการหักเหของแสง

ซีเนียร์ ตาข่ายและคำอธิบาย
1 เลเยอร์ MeshHightlight

เลเยอร์ไฮไลต์ใช้เพื่อเน้นตาข่ายในฉาก คุณสามารถให้สีกับมันและสีจะถูกนำไปใช้กับขอบของตาข่าย ในกรณีที่คุณต้องการไฮไลท์ในเกมคุณสามารถใช้เลเยอร์ไฮไลท์ตาข่ายได้เช่นเดียวกัน

2 เปลี่ยนเป็นตาข่าย

การเปลี่ยนรูปร่างจะเปลี่ยนรูปร่างของวัตถุไปเป็นอีกรูปแบบหนึ่งโดยการเปลี่ยนแปลงบางอย่าง เราได้เห็นพารามิเตอร์ที่สามารถอัพเดตได้สำหรับรูปร่าง พารามิเตอร์ถูกตั้งค่าเป็นเท็จมิฉะนั้น สำหรับการปรับเปลี่ยนจะถูกตั้งค่าเป็นจริงและตาข่ายจะถูกอัปเดตเพื่อเปลี่ยนรูปร่าง

3 การดำเนินการกับ Mesh

การดำเนินการใช้เพื่อเพิ่มปฏิสัมพันธ์ให้กับตาข่าย เหตุการณ์จะเปิดใช้งานเมื่อคุณคลิกที่ตาข่ายหรือเมื่อตาข่ายตัดกันหรือชนกัน

4 ตาข่าย AssetsManager

ด้วยคลาส assestsmanager คุณสามารถโหลดตาข่ายรูปภาพและไฟล์ไบนารีในฉากได้

5 นำเข้าตาข่าย

การใช้ Import Mesh เราจะได้เรียนรู้

6 เป้าหมายตาข่าย Morph

เราได้เห็นการเปลี่ยนแปลงของเส้นริบบิ้นรูปหลายเหลี่ยมและอื่น ๆ แล้วตอนนี้เราจะเห็นการแปรเปลี่ยนของทรงกลมและกล่องในการสาธิตนี้ด้วยเป้าหมาย morph รูปร่างของทรงกลมจะเปลี่ยนไปซึ่งเห็นได้จากการสาธิตด้านล่าง

7 อินสแตนซ์ตาข่าย

หากคุณต้องการวาดตาข่ายที่เหมือนกันในฉากของคุณให้ใช้อินสแตนซ์

8 ตาข่าย LOD และอินสแตนซ์

LOD หมายถึงเส้นของระยะทาง คุณสมบัตินี้ช่วยให้คุณระบุตาข่ายตามระยะห่างของตัวแสดง เมื่อระยะห่างจากตัวแสดงถึงวัตถุเพิ่มขึ้นระดับของรายละเอียดของตาข่ายจะแสดงอย่างชัดเจนโดยใช้ LOD

9 ตาข่าย VolumemetricLightScatteringPost-process

กระบวนการนี้กระจายแสงดังที่แสดงในเอาต์พุตที่ระบุด้านล่าง ทดสอบสิ่งเดียวกันในเบราว์เซอร์แล้วคุณจะเห็นว่าแสงกระจายผ่านตาข่ายอย่างไร

10 ขอบตาข่าย

EdgesRendering ใช้เพื่อวาด egdes รอบ ๆ ตาข่ายดังที่แสดงในเอาต์พุตด้านบน

11 ตาข่าย BlendModes

คุณสามารถสร้างโหมดผสมผสานได้โดยการปรับเปลี่ยนอัลฟาโมดของวัสดุ

12 ตาข่าย SolidParticles

ระบบ SolidParticle ได้รับการอัปเดตบนตาข่าย คุณสมบัติทั้งหมดที่เราเห็นบนตาข่ายสามารถใช้กับส่วนที่เป็นของแข็งได้

13 ตาข่าย FacetData

ข้อมูล Facet ใช้หน่วยความจำมากและคุณลักษณะนี้ไม่ได้เปิดใช้งานโดยค่าเริ่มต้น ในการเปิดใช้งานเราจำเป็นต้องสร้างตาข่ายตามต้องการและอัปเดตข้อมูลด้านเป็น