文章目录

  • framework
  • Camera
    • UniversalCamera——通用相机
    • ArcRotateCamera——弧形旋转相机
    • FollowCamera——跟随相机
    • 其他相机
  • Light
    • PointLight——点光
    • DirectionalLight——平行光
    • SpotLight——聚光灯
    • HemisphericLight——半球光
    • 灯光属性
  • BABYLON.MeshBuilder
    • CreateSphere——球
    • CreateBox——盒子
    • CreateCylinder——圆柱/棱柱
    • CreatePlane——平面
    • CreateGround——地面
    • CreateGroundFromHeightMap——高度地图
    • CreateLine——线
    • CreateLathe——车床
    • ExtrudeShape——挤压形状
  • position & rotation & scaling
    • position——定位
    • rotation——旋转
    • scaling——缩放
  • Material
    • 材质颜色属性
    • 材质纹理属性
    • backFaceCulling——背面剔除
    • wireFrame——线框
  • GUI
    • AdvancedDynamicTexture
  • Animation——动画
    • 标准动画
    • 排序动画
    • 分组动画
    • 组合动画(连续动画)
    • 动画人物
  • Audio——声音
  • 行为
    • 相机行为(弹跳等)
    • 网格行为(拖动物体等)
  • 其他
    • **导入场景或模型**
    • 声音
    • faceUV
    • 组合网格
    • 复制网格
    • 造车!
    • 天空盒
    • Animate !
    • 避免碰撞
    • SpriteManager——精灵管理
    • ParticleSystem——粒子系统
    • onPointerObservable——点击
    • ShadowGenerator——阴影
    • VR
    • 重力

进度:https://doc.babylonjs.com/start/chap6/particlespray

framework

一个球

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>Babylon Template</title><style>html, body {overflow: hidden;width: 100%;height: 100%;margin: 0;padding: 0;}#renderCanvas {width: 100%;height: 100%;touch-action: none;}</style><script src="https://cdn.babylonjs.com/babylon.js"></script><script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script><!-- 允许您将模型导入场景。 --><script src="https://code.jquery.com/pep/0.4.3/pep.js"></script><!-- 允许您使用触摸屏。 --></head><body><canvas id="renderCanvas" touch-action="none"></canvas> <!-- touch-action="none" for best results from PEP --><script>const canvas = document.getElementById("renderCanvas");const engine = new BABYLON.Engine(canvas, true);const createScene = () => {const  scene = new BABYLON.Scene(engine);const camera = new BABYLON.ArcRotateCamera("Camera", -3 * Math.PI / 4, Math.PI / 3, 50, BABYLON.Vector3.Zero(), scene);camera.attachControl(canvas, true);const  light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(0, -1, 1), scene);light.position = new BABYLON.Vector3(0, 15, -30);var ground = BABYLON.Mesh.CreateGround("ground", 100, 100, 1, scene, false);ground.receiveShadows = true;var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene); return scene;};const scene = createScene();engine.runRenderLoop(function () {scene.render();});window.addEventListener("resize", function () {engine.resize();});</script></body>
</html>

Camera

将相机连接到画布:

camera.attachControl(canvas, true);//第二个参数可选,默认false,阻止画布上的默认事件,true即允许

使相机不显示低于地面的物体:

camera.upperBetaLimit = Math.PI / 2.2;// β上限

UniversalCamera——通用相机

默认的行为是:

1.keyboard键盘-左和右箭头移动相机左右,上下箭头移动它向前和向后;

2.mouse鼠标——用相机旋转相机的原点;

3.touch向左或向右滑动,左右移动相机,上下滑动,向前和向后移动;

4.gamepad手柄-对应于设备。

构建一个通用相机

// 参数:名称、位置、场景
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);// 把相机对准一个特定的位置。在这个例子中是场景的原点
camera.setTarget(BABYLON.Vector3.Zero());// 把相机固定在画布上
camera.attachControl(canvas, true);

ArcRotateCamera——弧形旋转相机

  • 相机总是指向一个给定的目标位置,并可以在目标周围旋转,目标是旋转的中心。
  • 它可以用光标、鼠标和触摸事件来控制
  • 它相对于目标(地球)的位置可以由三个参数设定,alpha(弧度)经度(横切面)的旋转,beta(弧度)的纬度(纵切面)的旋转和半径(目标位置的距离)。
  • 由于技术原因,将beta值设置为0或PI会导致问题,在这种情况下,beta偏移0.1弧度(大约0.6度)。
  • alpha和beta都是顺时针方向增长的
  • 相机的位置也可以由一个矢量来设定,这个矢量将会超过alpha、beta和半径的任何现值。这比计算所需的角度要容易得多。
  • 无论是使用键盘、鼠标还是触摸式滑动,都可以改变alpha值和向下方向的变化。

构建一个弧旋转相机:

//参数:alpha、beta、半径、目标位置、场景
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);//定位摄像机覆盖alpha,beta,半径
camera.setPosition(new BABYLON.Vector3(0, 0, 20));//把相机连接到画布上
camera.attachControl(canvas, true);

通过使用CTRL+MouseLeftClick,也可以使用ArcRotateCamera来进行Panning移镜头操作。你可以指定使用MouseRightClick来替代,通过在attachControl调用中设置useCtrlForPanning:

camera.attachControl(canvas, noPreventDefault, useCtrlForPanning);

如果需要的话,你也可以通过设置来完全禁用panning :

scene.activeCamera.panningSensibility = 0;

如果将弧形旋转相机的parent设为人物,则可实现跟随人物运动:

camera.parent = dude;

FollowCamera——跟随相机

两种跟随相机:

  • followCamera:自由版本
  • arcFollowCamera:弧度旋转版本

给它一个网格作为目标并跟随其移动

当它被创建时,跟随相机的初始位置设置,然后目标位置设置为三个参数:

  1. 距离目标的距离-摄像机半径camera.radius;
  2. 目标上方的高度
  3. 在x y平面上的角度

相机移动到目标位置的速度是通过它的加速度(camera.cameraAcceleration)达到最大速度(camera.maxCameraSpeed)。

构建一个跟随相机:

// 参数:名称、位置、场景
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);//半径:相机距离目标距离
camera.radius = 30;// 相机高于目标中心(原点)的目标高度
camera.heightOffset = 10;// 目标在x y平面上绕目标(中心)的目标旋转角度
camera.rotationOffset = 0;//从当前位置到目标位置移动相机的加速度
camera.cameraAcceleration = 0.005//停止的加速度
camera.maxCameraSpeed = 10//把相机连接到画布上
camera.attachControl(canvas, true);// 相机锁定目标 = 人物
camera.lockedTarget = dude;

其他相机

浮雕相机

该AnaglyphUniversalCamera和AnaglyphArcRotateCamera延长使用使用通用和弧形旋转相机用红色和青色的3D眼镜。他们使用后处理过滤技术。

构造立体浮雕通用相机

// //参数:名称,位置,眼睛位置,场景
var camera = new BABYLON.AnaglyphUniversalCamera("af_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);

构造立体浮雕旋转相机:

//参数:名称,alpha,beta,半径,目标,eyeSpace,场景
var camera = new BABYLON.AnaglyphArcRotateCamera("aar_cam", -Math.PI / 2, Math.PI / 4, 20, BABYLON.Vector3.Zero(), 0.033, scene);

eyeSpace参数设置左眼视图和右眼视图之间的偏移量。戴好3D眼镜后,您可能需要尝试使用此float值。

您可以通过访问Wikipedia页面全面了解浮雕知识,对其进行详细介绍。

设备定位相机

所述DeviceOrientationCamera是专门设计来给设备取向事件作出反应,例如被倾斜一个现代移动设备向前,后,左,或右。

构造设备定位相机:

//参数:名称,位置,场景
var camera = new BABYLON.DeviceOrientationCamera("DevOr_camera", new BABYLON.Vector3(0, 0, 0), scene);
//将相机对准特定位置
camera.setTarget(new BABYLON.Vector3(0, 0, -10));
//设置摄像机对移动和旋转的敏感度
camera.angularSensibility = 10;
camera.moveSensibility = 10;
//将相机连接到画布
camera.attachControl(canvas, true);

虚拟操纵杆相机

该VirtualJoysticksCamera专门向虚拟摇杆事件做出反应。虚拟操纵杆是屏幕上的2D图形,用于控制相机或其他场景项目。

**注意:**这台相机需要第三方文件hand.js。

完整样本:

document.addEventListener("DOMContentLoaded", startGame, false);
function startGame() {if (BABYLON.Engine.isSupported()) {var canvas = document.getElementById("renderCanvas");var engine = new BABYLON.Engine(canvas, true);BABYLON.SceneLoader.Load("Espilit/", "Espilit.babylon", engine, function (newScene) {var VJC = new BABYLON.VirtualJoysticksCamera("VJC", newScene.activeCamera.position, newScene);VJC.rotation = newScene.activeCamera.rotation;VJC.checkCollisions = newScene.activeCamera.checkCollisions;VJC.applyGravity = newScene.activeCamera.applyGravity;//等待纹理和着色器准备就绪newScene.executeWhenReady(function () {newScene.activeCamera = VJC;//将相机连接到画布输入newScene.activeCamera.attachControl(canvas);//加载场景后,只需注册一个渲染循环即可渲染它engine.runRenderLoop(function () {newScene.render();}),}),}, function (progress) {//要做:向用户提供进度反馈。}),}
}

如果您切换回另一台摄像机,请不要忘记先打电话dispose()。在VirtualJoysticks创建的3D WebGL的顶部的2D画布画布绘制青色和黄色圆圈的操纵杆。如果您忘记打电话dispose(),2D画布将保留并继续处理触摸事件。

VR设备定向相机

VRDeviceOrientationFreeCamera,VRDeviceOrientationArcRotateCamera,和VRDeviceOrientationGamepadCamera是从一个VR设备延伸上方的摄像机手柄装置定向相机一个较新的集合。

FlyCamera

FlyCamera模仿3D空间中的自由运动,认为是“空间中的幽灵”。它具有逐步校正侧倾的选项,以及模拟倾斜转弯的选项。

其默认值为:

  1. 键盘-A和D键可左右移动摄像机。在W与S键向前和向后移动。在E与Q键和上下移动。
  2. 鼠标-以摄像机为原点,绕俯仰和偏航(X,Y)轴旋转摄像机。按住right mouse button旋转,以照相机为原点,使照相机绕Roll(Z)轴旋转。

构造飞行相机:

//参数:名称,位置,场景
var camera = new BABYLON.FlyCamera("FlyCamera", new BABYLON.Vector3(0, 5, -10), scene);
//像飞机一样旋转,具有更快的侧倾校正和倾斜转弯。
//默认值为100。数字越大,校正速度越慢。
camera.rollCorrect = 10;
//默认为false。
camera.bankedTurn = true;
//弧度默认为90度,以弧度表示倾斜角度。
camera.bankedTurnLimit = Math.PI / 2;
//多少偏航(转弯)会影响滚动(倾斜转弯)。
//小于1会减少滚动,大于1会增加滚动。
camera.bankedTurnMultiplier = 1;
//这会将相机附加到画布上
camera.attachControl(canvas, true);

详情请见:https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction

Light

所有的网格都允许光通过它们,除非阴影生成被激活。允许的默认灯光数是4,但这可以增加。

PointLight——点光

// 参数:名字, 位置, 场景
var light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(1, 10, 1), scene);

DirectionalLight——平行光

// 参数:名字,位置,场景
var light = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, 0), scene);

SpotLight——聚光灯

聚光灯是由一个位置、一个方向、一个角度和一个指数来定义的。这些值定义了一个从位置开始的光锥,向方向发射。

在弧度中,角度定义了聚光灯的锥形光束的大小(照明区域),指数定义了光的衰减速度和距离(范围)。

// 参数:名字,位置,方向,角度,指数,场景
var light = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);

HemisphericLight——半球光

也就是周围环境光

// 参数:名字, 方向,场景
var light = new BABYLON.HemisphericLight("HemiLight", new BABYLON.Vector3(0, 1, 0), scene);

灯光属性

颜色。。

限制:

默认一个场景总最多有4个灯光

var material = new BABYLON.StandardMaterial("mat", scene);
material.maxsimultaneousLights = 6;

打开:

light.setEnabled(true);

关闭:

light.setEnabled(false);

强度:

light0.intensity = 0.5;
light1.intensity = 2.4;

光的范围:

适用于点光与聚光灯

light.range = 100;

Choosing Meshes to Light

当一个光被创造出来时,所有的现有网格都将被它点亮。有两种方法可以将一些网格从被点亮的地方排除出去。

一个网格可以添加到独占的网格数组中,或者添加不被排除在包含的列表中。

被排除的网格的数量可能是决定使用哪种方法的一个因素。

BABYLON.MeshBuilder

CreateSphere——球

var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene); //默认的球体spherevar mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2, diameterX: 3}, scene);
//optinon: segments(段数) diameter(直径)diameterX    diameterY diameterZ   arc(弧度)slice(切片)  updatable(可更新的) sideOrientation(边方向)

CreateBox——盒子

var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene); //默认的盒子boxvar myBox = BABYLON.MeshBuilder.CreateBox("myBox", {height: 5, width: 2, depth: 0.5}, scene);
//option: size  height  width  depth(深度) faceColors(面颜色,6种颜色的数组,每个框面一个)faceUV(面UV,6个矢量阵列,每个盒子面一个) updatable(可更新的)  sideOrientation(边方向)

CreateCylinder——圆柱/棱柱

// 参数:名字,配置{//    height?: number; 高度 默认2
//    diameterTop?: number; 上直径 默认1
//    diameterBottom?: number; 下直径 默认1
//    diameter?: number; 直径 !=0  会被上两个覆盖
//    tessellation?: number; 镶嵌(即圆柱边数量,默认24) 3为三棱柱,4为四棱柱
//    subdivisions?: number; 细分 沿着圆柱体高度设置环的数量,默认1   ?没用到过
//    arc?: number;
//    faceColors?: BABYLON.Color4[];
//    ... 7 more ...;
//    backUVs?: BABYLON.Vector4;}
const roof = BABYLON.MeshBuilder.CreateCylinder("roof", {diameter: 1.3, height: 1.2, tessellation: 3});
roof.scaling.x = 0.75;
roof.rotation.z = Math.PI / 2;
roof.position.y = 1.22;

CreatePlane——平面

var plane = BABYLON.MeshBuilder.CreatePlane("plane", {}, scene); //默认的平面planevar myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 5, height: 2}, scene);
//option:    size   width   height   updatable(可更新的)   sideOrientation(边方向)  //      frontUVs(前UV,只有当边方向设置为 sideOrientation:BABYLON.Mesh.DOUBLESIDE)//       backUVs(后UV,只有当边方向设置为 sideOrientation:BABYLON.Mesh.DOUBLESIDE)//       sourcePlane(源平面,源平面(数学)网格将被转换为)//       sourcePlane是一个平面网格的独特选择,它提供了一种方法来定向和定位它。

CreateGround——地面

var ground = BABYLON.MeshBuilder.CreateGround("ground", {}, scene); //默认的地面groundvar myGround = BABYLON.MeshBuilder.CreateGround("myGround", {width: 6, height: 4, subdivsions: 4}, scene);

CreateGroundFromHeightMap——高度地图

const largeGround = BABYLON.MeshBuilder.CreateGroundFromHeightMap("largeGround", "https://assets.babylonjs.com/environments/villageheightmap.png", {width:150, height:150,subdivisions: 20,// 细分:棱角分明程度,数值越大坡度越大,越棱角分明minHeight:0, maxHeight: 10}
);const largeGroundMat = new BABYLON.StandardMaterial("largeGroundMat");
largeGroundMat.diffuseTexture = new BABYLON.Texture("url to large ground texture");largeGround.material = largeGroundMat;largeGround.position.y = -0.01; // 确保两个地面不发生冲突并引起闪烁。

CreateLine——线

var myPoints = [];var point1 = new BABYLON.Vector3(0, 0, 0);
myPoints.push(point1);
var point2 = new BABYLON.Vector3(0, 1, 1);
myPoints.push(point2);
var point3 = new BABYLON.Vector3(0, 1, 0);
myPoints.push(point3);//或者var myPoints =[new BABYLON.Vector3(0, 0, 0),new BABYLON.Vector3(0, 1, 1),new BABYLON.Vector3(0, 1, 0)
];//然后,这些点的数组必须传递给点选项//创建线linesvar lines = BABYLON.MeshBuilder.CreateLines("lines", {points: myPoints}, scene);//您可以创建虚线CreateDashedLines,并将破折号dashNb的数量作为一个选项。

CreateLathe——车床

在x,y正半轴的象限中绘制半个图像轮廓,然后沿着y轴旋转所形成的图形

const fountainProfile = [new BABYLON.Vector3(0, 0, 0),new BABYLON.Vector3(10, 0, 0),new BABYLON.Vector3(10, 4, 0),new BABYLON.Vector3(8, 4, 0),new BABYLON.Vector3(8, 1, 0),new BABYLON.Vector3(1, 2, 0),new BABYLON.Vector3(1, 15, 0),new BABYLON.Vector3(3, 17, 0)
];// sideOrientain属性将网格设置为双面,因为内部可见,而且顶部和中空部分是倾斜的
const fountain = BABYLON.MeshBuilder.CreateLathe("fountain", {shape: fountainProfile, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);

ExtrudeShape——挤压形状

创建一个挤压形状网格。

挤压是一个参数形状。

它没有预定义的形状。

它的最终形状将取决于输入参数。

//shape to extrude
const lampShape = [];
for(let i = 0; i < 20; i++) {lampShape.push(new BABYLON.Vector3(Math.cos(i * Math.PI / 10), Math.sin(i * Math.PI / 10), 0));
}
lampShape.push(lampShape[0]); //close shape//extrusion path
const lampPath = [];
lampPath.push(new BABYLON.Vector3(0, 0, 0));
lampPath.push(new BABYLON.Vector3(0, 10, 0));
for(let i = 0; i < 20; i++) {lampPath.push(new BABYLON.Vector3(1 + Math.cos(Math.PI - i * Math.PI / 40), 10 + Math.sin(Math.PI - i * Math.PI / 40), 0));
}
lampPath.push(new BABYLON.Vector3(3, 11, 0));const yellowMat = new BABYLON.StandardMaterial("yellowMat");
yellowMat.emissiveColor = BABYLON.Color3.Yellow();//extrude lamp
const lamp = BABYLON.MeshBuilder.ExtrudeShape("lamp", {cap: BABYLON.Mesh.CAP_END, shape: lampShape, path: lampPath, scale: 0.5});

ExtrudeShape中options的参数:

  • shape:是一个必须的连续Vector3数组。该阵列描述了要在其局部空间中挤压的形状:该形状必须在xOy平面上设计,并将沿着Z轴挤压。
  • path:是一个必须的连续Vector3数组。这是形状被挤压的轴线曲线。
  • rotate: (float,默认0弧度)是沿着曲线旋转形状每一步(每个路径点)的角度值,从前一步开始(所以每一步都添加旋转)。
  • scale: (float,默认为1)是缩放形状的值。
  • cap:设置挤压形状的封顶方式。可能的值:BABYLON.Mesh。BABYLON.Mesh NO_CAP(默认)。CAP_START BABYLON.Mesh。CAP_END, BABYLON.Mesh.CAP_ALL

position & rotation & scaling

position——定位

pilot.position = new BABYLON.Vector3(2, 3, 4);//或者pilot.position.x  =  2;
pilot.position.y  =  3;
pilot.position.z  =  4;

rotation——旋转

pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);//或者pilot.rotation.x  =  alpha; //绕x轴旋转
pilot.rotation.y  =  beta;  //绕y轴旋转
pilot.rotation.z  =  gamma; //绕z轴旋转box.rotation.y = Math.PI / 4;
box.rotation.y = BABYLON.Tools.ToRadians(45);// 以度为单位,与上一行效果相同

scaling——缩放

//沿着x轴、y轴和z轴进行缩放
mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);//或单独设置
mesh.scaling.y = 5;

Material

//创建一个材质使用: 参数:名字, 场景(可选,默认当前场景)
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);

材质颜色属性

  • diffuseColor——固有色
  • specularColor——高光反射色
  • emissiveColor——放射色
  • ambientColor环境色
    • 只有场景环境颜色scene ambient color 设置好时,才会使用ambientColor
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);myMaterial.diffuseColor = new BABYLON.Color3(1, 0, 1);
myMaterial.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87);
myMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1);
myMaterial.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53);mesh.material = myMaterial;

材质纹理属性

  • diffuseTexture——固有纹理
  • specularTexture——高光反射纹理
  • emissiveTexture——放射纹理
  • ambientTexture ——环境纹理
    • 只有场景环境颜色scene ambient color 设置好时,才会使用ambientTexture
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);myMaterial.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/environments/roof.jpg", scene);
myMaterial.specularTexture = new BABYLON.Texture("PATH TO IMAGE", scene);
myMaterial.emissiveTexture = new BABYLON.Texture("PATH TO IMAGE", scene);
myMaterial.ambientTexture = new BABYLON.Texture("PATH TO IMAGE", scene);mesh.material = myMaterial;

backFaceCulling——背面剔除

myMaterial.backFaceCulling = true;//默认为false,一般情况下不渲染材质的背面,设为true即渲染材质背面,如天空盒子的应用

wireFrame——线框

materialSphere1.wireframe = true;//你可以在线框模式下看到一个网格,如碰撞检测时可见网格的应用

GUI

向场景添加图形用户界面。

将其加载到页面:

<script>https://cdn.babylonjs.com/gui/babylon.gui.min.js</script>

可通过设置光照强度来改变白天和黑夜。

AdvancedDynamicTexture

先进的动态纹理

// 基于全屏创建GUI
const adt = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");// 创建控制面板,设置其位置
const panel = new BABYLON.GUI.StackPanel();panel.width = "220px";panel.top = "-25px";panel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;panel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;adt.addControl(panel); // 并将adt GUI对象的控制权交给panel// 文本面板const header = new BABYLON.GUI.TextBlock();header.text = "Night to Day";header.height = "30px";header.color = "white";panel.addControl(header); // 滑块const slider = new BABYLON.GUI.Slider();slider.minimum = 0;slider.maximum = 1;slider.borderColor = "black";slider.color = "gray";slider.background = "white";slider.value = 1;slider.height = "20px";slider.width = "200px";// 为滑块添加数据改变事件slider.onValueChangedObservable.add((value) => {if (light) {light.intensity = value;}});panel.addControl(slider);

Animation——动画

动画是由一系列图像,帧构成的,它们依次显示。

尽管我们可以在Babylon.js中将整个成品视为动画,但动画也是一个特定的对象,它详细说明了可以应用于任何网格,相机或灯光的变换,定时和循环。

标准动画

滑动滑块:

const box = BABYLON.MeshBuilder.CreateBox("box", {});
box.position.x = 2;// 帧率
const frameRate = 10;// 参数:名称,动画属性, 帧/秒,动画数据类型,动画循环模式
const xSlide = new BABYLON.Animation("xSlide", "position.x", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);// 关键帧数组
const keyFrames = []; keyFrames.push({frame: 0,value: 2
});keyFrames.push({frame: frameRate,value: -2
});keyFrames.push({frame: 2 * frameRate,value: 2
});xSlide.setKeys(keyFrames);box.animations.push(xSlide);// 参数: 动画对象,开始动画的帧,动画结束的帧,是否循环动画
scene.beginAnimation(box, 0, 2 * frameRate, true);// 将多个动画应用于同一个目标的方法:
// 参数:动画对象,动画数组[],开始动画的帧,动画结束的帧,是否循环动画
scene.beginDirectAnimation(target, animations, from, to, loop)

动画数据类型的值:

  • BABYLON.Animation.ANIMATIONTYPE_COLOR3
    BABYLON.Animation.ANIMATIONTYPE_FLOAT
    BABYLON.Animation.ANIMATIONTYPE_MATRIX
    BABYLON.Animation.ANIMATIONTYPE_QUATERNION
    BABYLON.Animation.ANIMATIONTYPE_VECTOR2
    BABYLON.Animation.ANIMATIONTYPE_VECTOR3

循环模式的值:

  • BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE-从初始值重新启动动画
    BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT-以最终值暂停动画
    BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE-使用键值渐变重复动画递增。以这种方式,例如,可以循环显示以步行运动方式显示角色的双腿的_ clip *,以显示角色在场景中的前进过程。

动画对象的方法:

  • pause():暂停
  • restart():重新开始
  • stop():停止
  • reset():重置

排序动画

var frameRate = 20;// 相机旋转动画 0-9s不动,9-14s旋转180°
var rotate = new BABYLON.Animation("rotate", "rotation.y", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);var rotate_keys = []; rotate_keys.push({frame: 0,value: 0});rotate_keys.push({frame: 9 * frameRate,value: 0});rotate_keys.push({frame: 14 * frameRate,value: Math. PI});rotate.setKeys(rotate_keys);//相机移动动画:0-3s移动,3-5s不动,5-8s移动var movein = new BABYLON.Animation("movein", "position", frameRate, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);var movein_keys = []; movein_keys.push({frame: 0,value: new BABYLON.Vector3(0, 5, -30)});movein_keys.push({frame: 3 * frameRate,value: new BABYLON.Vector3(0, 2, -10)});movein_keys.push({frame: 5 * frameRate,value: new BABYLON.Vector3(0, 2, -10)});movein_keys.push({frame: 8 * frameRate,value: new BABYLON.Vector3(-2, 2, 3)});movein.setKeys(movein_keys);// 门的打开与关闭:0-3s不动,3-5s旋转60°,5-13s不动,13-15s旋转-60°var sweep = new BABYLON.Animation("sweep", "rotation.y", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);var sweep_keys = []; sweep_keys.push({frame: 0,value: 0});sweep_keys.push({frame: 3 * frameRate,value: 0});sweep_keys.push({frame: 5 * frameRate,value: Math.PI/3});sweep_keys.push({frame: 13 * frameRate,value: Math.PI/3});sweep_keys.push({frame: 15 * frameRate,value: 0});sweep.setKeys(sweep_keys);// 光的明暗:0-7s暗,7-10s变亮,10-14亮,14-15变暗var lightDimmer = new BABYLON.Animation("dimmer", "intensity", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);var light_keys = []; light_keys.push({frame: 0,value: 0});light_keys.push({frame: 7 * frameRate,value: 0});light_keys.push({frame: 10 * frameRate,value: 1});light_keys.push({frame: 14 * frameRate,value: 1});light_keys.push({frame: 15 * frameRate,value: 0});lightDimmer.setKeys(light_keys);// 运行动画scene.beginDirectAnimation(camera, [movein, rotate], 0, 25 * frameRate, false);scene.beginDirectAnimation(hinge, [sweep], 0, 25 * frameRate, false);scene.beginDirectAnimation(spotLights[0], [lightDimmer], 0, 25 * frameRate, false);scene.beginDirectAnimation(spotLights[1], [lightDimmer.clone()], 0, 25 * frameRate, false);

分组动画

AnAnimationGroup允许您将动画和网格链接在一起并进行播放,暂停和停止。

// 创建动画组
var animationGroup1 = new BABYLON.AnimationGroup("Group1");// 向动画组中添加动画,并与网格连接
animationGroup1.addTargetedAnimation(animation1, mesh1);
animationGroup1.addTargetedAnimation(animation3, mesh1);
animationGroup1.addTargetedAnimation(animation2, mesh2);// 由于动画可能是用不同的时间线创建的,因此必须使用规范化来对齐它们
// 从第0帧到第100帧,第一个参数不能小于动画组中所有动画的最小帧,第二个参数不能大于动画组中所有动画的最大帧
animationGroup1.normalize(0, 100);// 可以为动画组中所以动画设置组速比speedRadio,用来加快或减慢动画
animationGroup1.speedRatio = 0.25;// 从现有的动画制作组中创建一个组
var animationGroup = new BABYLON.AnimationGroup("my-animation-group");
for (anim of idleAnim.getAnimations()) {animationGroup.addTargetedAnimation(anim.animation, anim.target);
}// 动画结束后触发的回调函数:
animationGroup1.onAnimationEndObservable.add(function() {mesh2.material = redMaterial;
});// 有一个onAnimationLoopObservable对象,它可以在每个动画循环时触发一个函数。(组循环完成后,每个动画对象都会触发一次该函数)
animationGroup1.onAnimationLoopObservable.add(function(targetAnimation) {console.log(targetAnimation.animation.name);
});// 还有一个onAnimationGroupLoopObservable对象,它可以在组的所有动画都已循环完成时触发一个函数:
animationGroup1.onAnimationGroupLoopObservable.add(function(group) {console.log("Group looped!");
});

组合动画(连续动画)

为了使一个动画跟随另一个动画,则需要将另一个参数添加到beginDirectAnimation函数中。此参数本身是由beginDirectAnimation开始的动画结束时要调用的函数。

scene.beginAnimation(目标,开始帧,结束帧,循环,速度,动画结束时);

  • target - BabylonJS对象,要动画的theBabylon.js对象
  • animations - array,所有要应用于目标的动画
  • start frame - number,开始动画的帧
  • end frame - number,结束动画的帧
  • loop - boolean:可选,要激活动画的循环模式时为true ,否则为false以仅运行一次动画
  • speed - number:可选,默认值1,与动画帧速率匹配,数字越大,动画速度越快;数字越低,动画速度越慢
  • 在动画结束-功能:可选,调用函数时动画结束,需要循环是false
 var frameRate = 10;var xSlide = new BABYLON.Animation("xSlide", "position.x", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);var keyFramesP = []; keyFramesP.push({frame: 0,value: 2
});keyFramesP.push({frame: frameRate,value: -2
});keyFramesP.push({frame: 2 * frameRate,value: 2
});xSlide.setKeys(keyFramesP);var yRot = new BABYLON.Animation("yRot", "rotation.y", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);var keyFramesR = []; keyFramesR.push({frame: 0,value: 0
});keyFramesR.push({frame: 2.5 * frameRate,value: 2 * Math.PI
});keyFramesR.push({frame: 5 * frameRate,value: 4 * Math.PI
});yRot.setKeys(keyFramesR);var nextAnimation = function() {scene.beginDirectAnimation(box, [yRot, xSlide], 0, 2 * frameRate, true);
}scene.beginDirectAnimation(box, [yRot],  0, 2 * frameRate, false, 1, nextAnimation);

动画人物

在Blender中创建角色,使用Mixamo向其中添加动画并将其组合为单个模型,再到通过键盘控制动画角色的移动。

有不同的工具和可能的工作流程来创建可以在Babylon.js项目中使用的动画模型。

以下是此操作方法的详细工作流程:

  • 使用Blender创建模型
  • 将模型导出为.FBX
  • 将模型加载到Mixamo中以进行绑定并添加动画
  • 将动画模型下载为.FBX文件
  • 使用Blender将动画模型组合为一个
  • 导出为.GLB(动画为动画组)
  • 将.GLB加载到Babylon.js游乐场中,并通过键盘控制模型的移动

官方文档:https://doc.babylonjs.com/divingDeeper/animation/animatedCharacter

没看懂:

  • 先进的动画方法:https://doc.babylonjs.com/divingDeeper/animation/animatedCharacter
  • 使用渲染训话的动画:https://doc.babylonjs.com/divingDeeper/animation/render_frame_animation

Audio——声音

Babylon.js声音引擎基于Web音频规范

我们决定不对音频标签或其他机制提供后备支持。因此,要使用我们的声音引擎,您需要使用与Web Audio兼容的浏览器。

不过,如果您在不兼容的浏览器上使用它,它将不会破坏我们引擎的其余部分,它只是不播放声音。

声音引擎提供环境声音,空间声音和定向声音。可以通过代码或加载.babylon文件来创建它。它遵循了您将要看到的其他引擎的简单而强大的原理。

支持的声音格式是浏览器中的一种。通常至少是**.mp3.wav**。

环境声音:

// 加载声音并在准备好后自动播放
// 参数:名称, url, 场景, 加载完成后的回调函数, 配置{循环与自动播放等}
var music = new BABYLON.Sound("Music", "music.wav", scene, null, {loop: true,autoplay: true,// volume: volume, // 音量// spatialSound: true // 是否为空间声音
});// 回调函数的使用
var music = new BABYLON.Sound("Music", "music.wav", scene, function() {//声音已下载并解码,参数:number(几秒后播放)music.play();
});

单击鼠标或按下按键时播放声音:

var gunshot = new BABYLON.Sound("gunshot", "sounds/gunshot.wav", scene);
window.addEventListener("mousedown", function(evt) {// left click to fireif (evt.button === 0) {gunshot.play();gunshot.setVolume(volume);// 调整音量}
});
window.addEventListener("keydown", function(evt) {// Press space key to fireif (evt.keyCode === 32) {gunshot.play();}
});

设置全局音量:

BABYLON.Engine.audioEngine.setGlobalVolume(0.5);

同时播放多个声音并同步:

var music1 = new BABYLON.Sound("Violons11","sounds/violons11.wav",scene,soundReady,{ loop: true }
);var music2 = new BABYLON.Sound("Violons18","sounds/violons18.wav",scene,soundReady,{ loop: true }
);var music3 = new BABYLON.Sound("Cellolong","sounds/cellolong.wav",scene,soundReady,{ loop: true }
);var soundsReady = 0;function soundReady() {soundsReady++;if (soundsReady === 3) {music1.play();music2.play();music3.play();}
}

空间声音

// 创建空间声音
var music = new BABYLON.Sound("music", "music.wav", scene, null, {loop: true,autoplay: true,spatialSound: true
});

空间声音的默认属性是:

  • distanceModel(衰减)默认情况下使用“线性”方程式。其他选项是“”或“指数”。
  • maxDistance设置为100。这意味着一旦听众距离声音的距离超过100个单位,音量将为0。您再也听不到声音了
  • panningModel设置为“ equalpower ”;等功率平移算法通常被认为是简单而高效的。另一个可用选项是“ HRTF ”。规范说:“一种更高质量的空间化算法,使用卷积和来自人类对象的测得的冲激响应。这种平移方法呈现立体声输出“。这是使用耳机时的最佳算法。

maxDistance仅在使用“线性”衰减时使用。否则,您可以使用rolloffFactorrefDistance选项调整其他模型的衰减。默认情况下两者都设置为1,但是您当然可以更改它。

例如:

var music = new BABYLON.Sound("music", "music.wav", scene, null, {loop: true,autoplay: true,spatialSound: true,distanceModel: "exponential",rolloffFactor: 2 // 下降因子
});

声音在3D世界中的默认位置是(0,0,0)。要更改此设置,请使用以下setPosition()功能:

music.setPosition(new BABYLON.Vector3(100, 0, 0));

将声音附加到网格

var music = new BABYLON.Sound("Violons", "sounds/violons11.wav", scene, null, {loop: true,autoplay: true
});
// Sound will now follow the box mesh position
music.attachToMesh(box);

将位置设为音频监听器

默认情况下,场景的“耳朵”(即听众)始终是当前活动的摄像机。有时,例如在制作第三人称游戏时,您可能需要将另一个网格设置为侦听器-例如角色头像。这可以通过audioListenerPositionProvider在场景上设置属性来实现。

您创建的方法必须返回一个有效的Vector3对象。

//返回静态位置
scene.audioListenerPositionProvider = () => {return new BABYLON.Vector3(0, 0, 10);
};
//返回网格的当前位置
//!建议使用'absolutePosition'属性
//反映网格在世界上的位置
scene.audioListenerPositionProvider = () => {//返回静态位置return myMesh.absolutePosition;
};

要切换回使用相机作为侦听器,只需将属性设置为null

创建定向3D声音

默认情况下,空间声音是全向的。但是,如果您愿意,可以有定向声音。

**注意:**定向声音仅适用于连接到网格的空间声音。

var music = new BABYLON.Sound("Violons", "violons11.wav", scene, null, {loop: true,autoplay: true
});
// 设置定向锥,参数:内圆锥的大小(以度为单位),外部圆锥的大小(以度为单位),当您位于外部圆锥体之外时的声音音量(介于0.0和1.0之间)
music.setDirectionalCone(90, 180, 0);
music.setLocalDirectionToMesh(new BABYLON.Vector3(1, 0, 0));
music.attachToMesh(box);

锥体的外角必须大于或等于内角,否则将记录错误,并且定向声音将不起作用。

setLocalDirectionToMesh()只是与您连接到的网格有关的圆锥的方向。默认情况下为(1,0,0)

创建自己的自定义衰减

如果要使用特定算法管理衰减(或Web Audio中的距离模型),则可以使用Babylon.js自定义衰减功能绕过本机Web Audio衰减。

注意: Web Audio是硬件加速的。这意味着它主要由设备上的专用音频芯片通过本机代码(浏览器)处理。这样一来,在3D实时渲染的性能方面几乎不会花费任何成本。切换到自定义衰减将使用基于JavaScript的Babylon.js距离计算,并且速度较慢。

而且,自定义衰减仅适用于空间声音(显然),而且还适用于连接到Babylon.js网格的声音。就是说,现在让我们查看执行此操作的代码。首先,必须在选项中指定它:

//创建并加载异步声音
var music = new BABYLON.Sound("Music", "music.wav", scene, null, {loop: true,autoplay: true,useCustomAttenuation: true
});

您将切换到内部Babylon.js数学计算。默认的自定义衰减功能是线性的。

要创建自己的逻辑,您需要以下代码:

//创建自定义衰减功能。在对象附近,音量几乎为0。
//最远,更大声
music.setAttenuationFunction(function(currentVolume,currentDistance,maxDistance,refDistance,rolloffFactor
) {return (currentVolume * currentDistance) / maxDistance;
});

您可以使用这5个参数进行操作,并随心所欲地进行操作。只需返回一个数字,该数字将成为应用于声音的音量。

在此示例中,逻辑有点奇怪,因为您离网格越远,音量越大。

个人Babylonjs学习笔记相关推荐

  1. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  2. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  3. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  4. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  5. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

  6. 知识图谱学习笔记(1)

    知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...

  7. 计算机基础知识第十讲,计算机文化基础(第十讲)学习笔记

    计算机文化基础(第十讲)学习笔记 采样和量化PictureElement Pixel(像素)(链接: 采样的实质就是要用多少点(这个点我们叫像素)来描述一张图像,比如,一幅420x570的图像,就表示 ...

  8. Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)

    Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...

  9. MongoDB学习笔记(入门)

    MongoDB学习笔记(入门) 一.文档的注意事项: 1.  键值对是有序的,如:{ "name" : "stephen", "genda" ...

最新文章

  1. Swift default参数
  2. Apache Struts 和 Spring 开源漏洞状况的对比
  3. 请问spfa+stack 和spfa+queue 是什么原理
  4. 无损1080i到1080p是如何制作的
  5. 应用EtherNet IP转Modbus网关连接施耐德PLC和AB PLC
  6. stm32f103r6最小系统原理图_stm32f103c8t6封装及最小系统原理图
  7. EasyUI - panel 高度自适应
  8. PAT甲级 1012 The Best Rank
  9. hive reduce
  10. 什么是知识,什么是知识图谱,有什么作用,有哪些应用领域?
  11. 微信小程序开发基础知识2(黑马)
  12. H5身份证上传识别功能
  13. Windows 搭建 Nexus3 私服
  14. R语言一般线性模型(涉及因变量是虚拟变量(哑变量))
  15. jquery国际化 i18n.js
  16. syslog与rsyslog
  17. linux下开启、关闭、重启mysql服务
  18. PyCharm取消下划线
  19. Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)
  20. CSS实现背景网格线(background-image)

热门文章

  1. Spark 基本知识介绍
  2. 夸西莫多的一首短诗--《瞬息间是夜晚》
  3. 开放信息抽取(OIE)系统(四)-- 第三代开放信息抽取系统(基于子句, clause-based, 句子重组、删减)
  4. 装X时刻!win10/CentOS 7双系统成功安装小白教程
  5. HR做新员工线上培训,怎样做更有效果
  6. 加减乘除计算机英语,英语里的加减乘除
  7. 关于rx,tx或I2C串口不够的问题
  8. 2020届秋招 网易互娱游戏研发工程师面经(已offer)
  9. matlab语音频谱,信号与系统:用matlab分析wav音频的频谱
  10. 覆盖vue3.0的最全Vue知识点