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