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. Изображения хранятся в папке 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. Каждый Vector4 (x, y, z, w) будет определен следующим образом:
- x = Ubottom
- y = V снизу
- 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>
Выход
Приведенная выше строка кода генерирует следующий вывод -
В этой демонстрации мы использовали изображение под названием 3d.png. Изображения хранятся в папке images / локально, а также вставлены ниже для справки. Обратите внимание: 3d.png - это изображение спрайта; изображение-спрайт - это набор изображений. Мы хотели показать изображение на кубе со всеми сторонами куба вместе. Вы также можете загрузить похожие изображения спрайтов на ваш выбор и использовать их в демонстрационной ссылке.
Текстура, используемая для коробки - images/3d.png
СеткаЦилиндр
В этом разделе мы увидим, как создать MeshCylinder.
Чтобы создать MeshCylinder, вам нужно использовать класс BABYLON.MeshBuilder.CreateCylinder.
Параметры для класса следующие:
var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
height: 3,
diameter: 35,
tessellation: 52
}, scene);
Разница между CreateCylinder, использующим сетку, и 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 - Пересечение сетки и точка
Пересечение сетки в играх важно, так как вы знаете, что нужно делать, когда в игре пересекаются 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 дает истину или ложь, если он пересекается с сеткой, указанной в переданном ему параметре.
Например,
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 - Столкновение при выборе сетки
Выбор столкновения фактически дает вам координаты, и вы можете разместить свою сетку в этом месте. Объект выбирается мышью, и вы можете просто разместить там, где вы щелкаете мышью. Считайте, что вам нужно разместить сетку (объект) в том месте, где пользователь щелкает мышью; Итак, с помощью выбора столкновения он помогает вам с координатами в позиции места, на которое щелкнули.
Демо
<!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 - Raycast
Raycast похожи на солнечные лучи и используются для проверки столкновения и пересечения в сцене.
Синтаксис
var ray = new BABYLON.Ray(origin, direction, length);
Параметры
Рассмотрим следующие параметры для raycast -
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>
Выход
Приведенная выше строка кода генерирует следующий вывод -
Объяснение
В центре есть главный блок, который действует как 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(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, box или box5, она вернет false; в противном случае верно.
Вы можете попробовать приведенный выше пример для того же.
BabylonJS - сетка теней
Тени визуализируются в зависимости от того, как свет падает на созданную сетку. Они играют важную роль в обеспечении реалистичности изображения в трехмерном мире.
Давайте теперь узнаем, как создавать тени с помощью 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; - Called Poisson sampling
shadowGenerator.useExponentialShadowMap = true; - Exponential Shadow Map
shadowGenerator.useBlurExponentialShadowMap= true; - Blur Exponential Shadow Map
В нашей демонстрации мы использовали shadowGenerator00.useBlurExponentialShadowMap = true; Вы можете попробовать другие и посмотреть, как выглядит результат.
Здесь мы использовали изображение gr1.jpg. Изображения хранятся в папке images / локально. Вы можете скачать любое изображение на ваш выбор и использовать в демо-ссылке.
BabylonJS - Расширенные текстуры на сетках
В этом разделе мы узнаем о расширенных текстурах на сетках. Различные текстуры показаны ниже -
Текстура куба
Зеркальная и рельефная текстура
Видео Текстура
Применим к сетке сложную текстуру - зеркало, рельеф, видео и преломление.
Sr. No. | Сетка и описание |
---|---|
1 | Слой MeshHightlight
Слой Highlight используется для выделения сетки в сцене. Вы можете придать ему цвет, и цвет будет применен к границам сетки. В случае, если в игре вы хотите выделить подсветку, для этого можно использовать слой подсветки сетки. |
2 | Преобразовать сетку
Морфинг изменяет форму одного объекта на другой посредством некоторого перехода. Мы видели обновляемый параметр для фигур; в противном случае для параметра установлено значение false. Для морфинга устанавливается значение true, и сетка обновляется для изменения формы. |
3 | Действия с сеткой
Действия используются для добавления взаимодействия к сетке. События активируются, когда вы нажимаете на сетку или когда сетка пересекается или сталкивается. |
4 | Mesh AssetsManager
С помощью класса Assestsmanager вы можете загружать в сцену сетки, изображения и двоичные файлы. |
5 | Импортировать сетку
Мы научимся использовать Import Mesh. |
6 | Цели морфинга сетки
Мы уже видели морфинг линий, ленты, многоугольника и т. Д. Теперь мы увидим морфинг сферы и прямоугольника в этой демонстрации. С морфингом целей форма сферы изменяется, как показано в демонстрации ниже. |
7 | Экземпляры сетки
Если вы хотите рисовать идентичные сетки в своей сцене, используйте экземпляры. |
8 | Уровень детализации сети и экземпляры
LOD означает линию расстояния. Эта функция позволяет вам определять сетки в зависимости от расстояния до зрителя. По мере того как расстояние от зрителя до объекта увеличивается, уровень детализации сетки четко отображается с помощью LOD. |
9 | Сетка VolumemetricLightScatteringПост-процесс
Этот процесс рассеивает свет, как показано на выходе, приведенном ниже. Проверьте то же самое в браузере, и вы увидите, как свет рассеивается через сетку. |
10 | Mesh EdgesRenderer
EdgesRendering используется для рисования краев вокруг сетки, как показано в выходных данных выше. |
11 | Mesh BlendModes
Вы можете создать режим наложения, изменив альфа-режим материалов. |
12 | Сетка SolidParticles
Система SolidParticle обновляется на сетке. Все свойства, которые мы видели на сетке, можно использовать на твердой частице. |
13 | Сетка FacetData
Данные фасета занимают много памяти, и эта функция по умолчанию отключена. Чтобы включить его, нам нужно создать сетку по мере необходимости и обновить в нее данные фасетов. |