BabylonJS - Mesh
在本章中,我们将学习使用网格生成器创建不同的形状。我们已经在之前的章节中学习了如何创建形状。
不同之处在于,使用网格生成器可以灵活地为形状添加颜色和图像。
使用 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 的图像。图像本地存储在 images/ 文件夹中,也粘贴在下面以供参考。请注意 cube.png 是精灵图像,精灵图像是图像的集合。我们想在立方体上显示图像,所以想将立方体的所有面放在一起。您还可以下载您选择的类似精灵图像并在演示链接中使用。
createBox 构建器为您提供了尺寸选项。
例如,
var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
演示
var hSpriteNb = 3; // 每个原始图像有 3 个精灵,即水平列,如图像中所示 var vSpriteNb = 2; // 如上图所示,有 2 个精灵原始图像。 var faceUV = new Array(6); // 立方体有 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 };
这称为使用 createBox 方法将纹理应用于 meshbuilder。我们使用了图像 cube.png,该图像水平方向有 3 列,垂直方向有 2 行。立方体或盒子有 6 条边。
要应用纹理,我们使用 options 参数。例如,
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 是纹理裁剪开始位置左下角点的 2D 坐标。Utop、Vtop 是纹理裁剪结束位置右上角点。
var hSpriteNb = 3; // 每个原始图像 3 个精灵 var vSpriteNb = 2; // 2 个精灵原始图像 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 个精灵 var vSpriteNb = 2; // 2 个精灵原始数据 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 的图像。图像存储在本地 images/ 文件夹中,也粘贴在下面以供参考。请注意 3d.png 是一个精灵图像;精灵图像是图像的集合。我们想在一个立方体上显示图像,立方体的所有面都在一起。您还可以下载您选择的类似精灵图像并在演示链接中使用。
用于盒子的纹理images/3d.png −

MeshCylinder
在本节中,我们将了解如何创建 MeshCylinder。
要创建 MeshCylinder,您需要使用 BABYLON.MeshBuilder.CreateCylinder 类。
该类的参数如下 −
var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", { height: 3, diameter: 35, tessellation: 52 }, scene);
使用 mesh 和 meshbuilder 的 CreateCylinder 之间的区别是 - 您可以在 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>
输出
上述代码行生成以下输出 −

现在将在一个演示中一起使用使用网格生成器创建的多个形状。下面的演示链接中涵盖的形状在后续部分中列出。
BabylonJS – 网格相交和点
游戏中的网格相交非常重要,因为您知道游戏中两个对象相交时需要做什么。下面的演示中解释了网格相交时需要捕获的事件的相同概念。
在下面给出的演示中,我们介绍了以下两个概念 −
- 网格相交
- 点相交
<!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>
输出
上述代码生成以下输出 −

说明
使用上述代码,我们创建了一个线框为 true 的圆柱体。我们创建了 3 个球体。球体的原始颜色是绿色。
在 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 如果与传递给它的参数中给出的网格相交,则返回 true 或 false。
例如,
balloon1.intersectsMesh(cone, false); //cone 在此处指的是圆柱体网格。
如果球体与圆柱体相交,则球体的颜色变为红色;否则为绿色。
以下代码用于与点相交 −
var pointToIntersect = new BABYLON.Vector3(10, 0, 0); if (balloon3.intersectsPoint(pointToIntersect)) { balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0); }
此处,pointtoIntersect 变量是位置向量,在 x 轴上为 10。如果球体越过交点,球体的颜色将变为黑色。
BabylonJS – MeshPicking Collision
Picking Collision 实际上为您提供了坐标,您可以将网格定位在该位置。对象由鼠标拾取,您只需用鼠标单击即可放置。假设您需要将网格(对象)放置在用户单击鼠标的位置;因此,借助 Picking 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); //当指针向下事件发生时 scene.onPointerDown = function (evt, pickResult) { // 如果点击击中地面物体,我们会改变撞击位置 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>
输出

说明
在上面的例子中,我们使用了一个平面和两个球体。要生成此输出,请使用以下代码 −
scene.onPointerDown = function (evt, pickResult) { // 如果点击击中地面物体,我们会改变撞击位置 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 为 true。我们考虑奇数/偶数秒,并更改球体的位置以拾取结果 z 和 y 坐标,如上所示。一旦位置改变,球体就会放置在您单击和放置鼠标的位置。您可以尝试上述演示。
BabylonJS – 射线投射
射线投射就像太阳光线,用于检查场景中的碰撞和相交。
语法
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);
然后,为了得到方向,我们从原点(盒子位置)中减去它 −
长度 −射线的长度。
演示
<!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; }
在浏览器中尝试上述示例以查看输出。
带谓词函数的射线投射
现在让我们看看带谓词函数的射线投射如何工作以及使用 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; //射线显示方向 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、box 或 box5,它将返回 false;否则,返回 true。
您可以尝试上述示例。
BabylonJS – 网格阴影
阴影是根据光线照射到创建的网格上的方式渲染的。它们在使输出在 3D 世界中看起来逼真方面发挥着重要作用。
现在让我们学习如何使用 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>
输出
上述代码行生成以下输出 −

说明
要创建阴影,您需要创建阴影生成器。请考虑以下示例。
var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);
要定义需要阴影的网格,您需要将其添加到上述生成器中。
shadowGenerator00.getShadowMap().renderList.push(box);
现在,我们已经创建了一个地面和其上的一个盒子。我们希望盒子的阴影落在地面上。为此,我们需要确保地面被标记为接收阴影,如下所示 −
ground01.receiveShadows = true;
有一些可用于阴影的过滤器,如下所示 −
shadowGenerator.usePoissonSampling = true; - 称为泊松采样 shadowGenerator.useExponentialShadowMap = true; - 指数阴影图 shadowGenerator.useBlurExponentialShadowMap= true; - 模糊指数阴影图
在我们的演示中,我们使用了 shadowGenerator00.useBlurExponentialShadowMap = true;您可以尝试其他方法,看看输出结果如何。
在这里,我们使用了名为 gr1.jpg 的图像。图像存储在本地的 images/ 文件夹中。您可以下载您选择的任何图像并在演示链接中使用。
BabylonJS – 网格上的高级纹理
在本节中,我们将了解网格上的高级纹理。不同的纹理如下所示 −
让我们将一些复杂的纹理应用于网格 - 镜像、凹凸、视频和折射。
Sr.No. | 网格 &描述 |
---|---|
1 | 网格高亮层
高亮层用于高亮场景中的网格。您可以为其赋予颜色,并将颜色应用于网格的边框。如果您在游戏中想要高亮,可以使用网格高亮层来实现这一点。 |
2 | 网格变形
变形通过某种过渡方式将一个对象的形状更改为另一个对象的形状。我们已经看到了形状的可更新参数;否则,该参数设置为 false。对于变形,将其设置为 true,并更新网格以更改形状。 |
3 | 网格操作
操作用于向网格添加交互。单击网格时,或网格相交或碰撞时,会激活事件。 |
4 | 网格 AssetsManager
使用assestsmanager 类,您可以在场景中加载网格、图像和二进制文件。 |
5 | 导入网格
我们将学习使用导入网格。 |
6 | 网格变形目标
我们已经看到了线条、丝带、多边形等的变形。现在,我们将在此演示中看到球体和盒子的变形。使用变形目标,球体的形状会发生变化,如下面的演示所示。 |
7 | 网格实例
如果您想要在场景中绘制相同的网格,并利用实例。 |
8 | 网格 LOD 和实例
LOD 代表距离线。此功能允许您根据查看者的距离指定网格。随着查看者与物体之间的距离增加,网格的细节级别将通过 LOD 清晰显示。 |
9 | 网格 VolumemetricLightScatteringPost-process
此过程会散射光线,如下面的输出所示。在浏览器中测试相同内容,您将看到光线如何散射穿过网格。 |
10 | 网格边缘渲染器
EdgesRendering 用于在网格周围绘制边缘,如上面的输出所示。 |
11 | 网格混合模式
您可以通过修改材质的 alphamode 来创建混合模式。 |
12 | 网格固体粒子
固体粒子系统在网格上更新。我们在网格上看到的所有属性都可以在固体粒子上使用。 |
13 | 网格刻面数据
刻面数据占用大量内存,默认情况下不启用此功能。要启用它,我们需要根据需要创建一个网格并向其更新刻面数据。 |