Учебники

BabylonJS — Mesh

В этой главе мы научимся создавать различные фигуры, используя построитель сеток. Мы уже научились создавать фигуры в одной из наших предыдущих глав.

Разница в том, что с помощью 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>

Выход

Выше строка кода генерирует следующий вывод —

MeshBuilder CubeBox

Для приведенного выше примера мы использовали изображение спрайта, как показано ниже. Он имеет 3 колонки по горизонтали и 2 ряда по вертикали.

куб

В этой демонстрации мы использовали изображение с именем cube.png. Изображения хранятся в папке images / локально, а также вставляются ниже для справки. Пожалуйста, обратите внимание, что 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
};

Это называется применением текстур к построителю сетки с использованием метода createBox. Мы использовали изображение cube.png, которое имеет 3 столбца по горизонтали и 2 строки по вертикали. Куб или блок имеют 6 сторон.

Чтобы применить текстуры, мы используем параметр options. Например,

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

Мы определили массив с именем faceUV размером 6, который является сторонами куба. Этот массив всегда будет содержать элементы Vector4. Каждый вектор 4 (x, y, z, w) будет определен следующим образом:

  • х = снизу
  • y = Vbottom
  • z = Utop
  • w = Vtop

Векторы находятся в диапазоне [0, 1]. Ubottom и Vbottom — это двухмерные координаты нижней левой точки, где начинается обрезка текстуры. 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>

Выход

Выше строка кода генерирует следующий вывод —

Textturepahse4

В этой демонстрации мы использовали изображение с именем 3d.png. Изображения хранятся в папке images / локально, а также вставляются ниже для справки. Пожалуйста, обратите внимание, что 3d.png является спрайт-изображением; Спрайт-изображение — это коллекция изображений. Мы хотели показать изображение на кубе со всеми сторонами куба вместе. Вы также можете скачать похожие изображения спрайтов по вашему выбору и использовать в демонстрационной ссылке.

Текстура, используемая для коробки — images / 3d.png

3d

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>

Выход

Выше строка кода генерирует следующий вывод —

Meshcylinder

Несколько фигур, созданных с помощью построителя сетки, теперь будут использоваться вместе в одной демонстрации. Формы, описанные в демонстрационной ссылке ниже, перечислены в последующих разделах.

земля

шишка

Самолет

диск

торус

многогранник

IcoSphere

BabylonJS — пересечение сетки и точка

Пересечение сетки в играх важно, поскольку вы знаете, что нужно делать, когда в игре пересекаются 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 сферы. Оригинальный цвет сферы — зеленый.

В функции 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 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 — это вектор положения, который на оси X равен 10. Если сфера пересекает точку пересечения, цвет сферы изменяется на черный.

BabylonJS — Столкновение MeshPicking

Выбор столкновения фактически дает вам координаты, и вы можете расположить вашу сетку в этом месте. Объект выбирается мышью, и вы можете просто разместить его там, где вы щелкаете мышью. Обдумайте, что вам нужно разместить сетку (объект) в месте, где пользователь щелкает мышью; Таким образом, с помощью выбора столкновения это поможет вам с координатами в месте, где вы щелкнули.

демонстрация

<!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 как true, если вы нажмете на наземную сетку. Мы рассматриваем нечетные / четные секунды и меняем положение сферы, чтобы выбрать координаты z и y результата, как показано выше. После изменения положения сфера помещается туда, куда вы щелкаете и позиционируете мышь. Вы можете попробовать приведенную выше демонстрацию для того же самого.

BabylonJS — Raycasts

Лучевые трансляции похожи на солнечные лучи и используются для проверки столкновения и пересечения в сцене.

Синтаксис

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);

Затем, чтобы получить направление, мы вычитаем его из начала координат, положение коробки —

  • Длина — длина луча.

Длина — длина луча.

демонстрация

<!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>

Выход

Выше строка кода генерирует следующий вывод —

Raycast

объяснение

В центре есть главный ящик, который действует как лучевой канал. Как только он укажет на любой из ящиков, размер ящика увеличится. Эта концепция оказывается полезной при игре в игры, чтобы узнать, какой другой объект вступает в контакт, и могут быть предприняты необходимые действия.

Добавление 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 (происхождение, направление, длина); создает луч, и он принимает положение основного ящика в качестве источника.

Направление на луч рассчитывается следующим образом —

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

объяснение

Raycast с функцией предиката помогает выбрать, какую сетку мы хотим. Если мы не хотим, чтобы меш выбирался, мы можем игнорировать то же самое.

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

Вышеупомянутая функция дает меш, который выбран лучом. Если выбран меш — box2, box или box5, он вернет false; в противном случае, правда.

Вы можете попробовать приведенный выше пример для того же.

BabylonJS — Mesh Shadows

Тени отображаются в зависимости от того, как свет падает на созданную сетку. Они играют важную роль в том, чтобы результат выглядел реалистично в трехмерном мире.

Давайте теперь узнаем, как создавать тени, используя babylonjs.

Синтаксис

var shadowGenerator00 = new BABYLON.ShadowGenerator(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; - Called Poisson sampling 
shadowGenerator.useExponentialShadowMap = true; - Exponential Shadow Map
shadowGenerator.useBlurExponentialShadowMap= true;  - Blur Exponential Shadow Map

В нашей демонстрации мы использовали shadowGenerator00.useBlurExponentialShadowMap = true; Вы можете попробовать другие и посмотреть, как выглядит результат.

Здесь мы использовали изображение с именем gr1.jpg. Изображения хранятся в папке images / локально. Вы можете скачать любое изображение по вашему выбору и использовать в демонстрационной ссылке.

BabylonJS — передовые текстуры на сетках

В этом разделе мы узнаем о расширенных текстурах на сетках. Различные текстуры показаны ниже —

Куб текстуры

Зеркальная и выпуклая текстура

Видео текстуры

Давайте применим несколько сложных текстур к сетке — зеркало, выпуклость, видео и рефракцию.

Слой подсветки используется для выделения сетки в сцене. Вы можете дать ему цвет, и цвет будет применен к границам сетки. В случае, если в игре вы хотите подсветить, слой сетки подсветки может быть использован для того же.

Морфинг изменяет форму объекта другим путем перехода. Мы видели обновляемый параметр для фигур; в противном случае параметр имеет значение false. Для морфинга он имеет значение true, а сетка обновляется для изменения формы.

Действия используются для добавления взаимодействия в сетку. События активируются, когда вы нажимаете на сетку, или когда сетка пересекается или сталкивается.

С помощью класса assestsmanager вы можете загружать сетки, изображения и двоичные файлы в сцену.

Используя Import Mesh мы узнаем.

Мы уже видели морфинг линий, ленты, многоугольника и т. Д. Теперь мы увидим морфинг сферы и прямоугольника в этой демонстрации. С изменяющимися целями форма сферы изменяется, что видно из демонстрации ниже.

Если вы хотите рисовать одинаковые сетки в вашей сцене, используйте экземпляры.

LOD обозначает линию расстояния. Эта функция позволяет указывать сетки в зависимости от расстояния до зрителя. По мере увеличения расстояния от зрителя до объекта уровень детализации сетки четко отображается с использованием LOD.

Этот процесс рассеивает свет, как показано в выходных данных, приведенных ниже. Проверьте то же самое в браузере, и вы увидите, как свет рассеивается через сетку.

EdgesRendering используется для рисования egdes вокруг сетки, как показано в выходных данных выше.

Вы можете создать режим наложения, изменив альфа-режим материалов.

Система SolidParticle обновляется на сетке. Все свойства, которые мы видели на сетке, могут быть использованы для твердых частиц.

Данные фасетов занимают много памяти, и эта функция по умолчанию не включена. Чтобы включить его, нам нужно создать меш по мере необходимости и обновить в нем данные фасетов.