当前位置: 代码迷 >> 综合 >> Babylon.js阅读笔记一
  详细解决方案

Babylon.js阅读笔记一

热度:53   发布时间:2023-10-01 00:13:17.0

Babylon.js101

  • 创建一个基本的Demo
    <style>html, body {overflow: hidden;width   : 100%;height  : 100%;margin  : 0;padding : 0;}#renderCanvas {width   : 100%;height  : 100%;touch-action: none;}</style>
    </head>
    <body><canvas id="renderCanvas"></canvas>
    </body>
    <script>window.addEventListener('DOMContentLoaded', function() {// All the following code is entered here.var canvas = document.getElementById('renderCanvas');var engine = new BABYLON.Engine(canvas,true);var createScene = function(){var scene = new BABYLON.Scene(engine); // 创建场景var camera = new BABYLON.FreeCamera('camera',new BABYLON.Vector3(0,5,-10),scene); // 创建相机camera.setTarget(BABYLON.Vector3.Zero()); //设置相机方向camera.attachControl(canvas,false);  // 将相机绑定到canvasvar light = new BABYLON.HemisphericLight('light1',new BABYLON.Vector3(0,1,0),scene); // 创建灯光var sphere = BABYLON.MeshBuilder.CreateSphere('sphere',{segments:16,diameter:2},scene); // 创建立方体sphere.position.y = 1; // 设置立方体位置var ground = BABYLON.MeshBuilder.CreateGround('ground1',{height:6,width:6,subdivisions:2},scene); // 创建地板var myPoints = [];var poreturn scene;}var scene = createScene();// 必要步骤。循环渲染engine.runRenderLoop(function(){scene.render();})});
    </script>
    

网格

  • 创建一个固定形状网格的一般形式:
    var shape = BABYLON.MeshBuilder.CreateShape(name,potions,scene);
    option参数允许你设置形状的大小以及是否可以更新它。
  • 立方体模型
    var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene); // default box
    var myBox = BABYLON.MeshBuilder.CreateBox("myBox", {height: 5, width: 2, depth: 0.5}, scene);
    
    option value 默认值
    size 每个盒子的尺寸(数字) 1
    height 盒子高度(数字)(设置的话会覆盖size属性) size
    width 宽度(数字)(设置会覆盖size属性) size
    depth 深度(数字)(设置会覆盖size属性) size
    faceColors 有六个Color4类型值的数组,每个值对应立方体的一面 含6个Color4(1,1,1,1)值的数组
    faceUV 有六个Vector4类型值的数组,每个值对应立方体的一面 含6个Color4(1,1,1,1)值的数组
    updatable 网格可更新则为true false
    sideOrientation (数字类型) 排列方向 DEFAULTSIDE

sideOrientation和Threejs的side类似,为0的时候正面隐藏只能看到形状的反面,为1时看到的是正面,为2时为双面显示

  • 球型网格

    var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene); //default sphere
    var mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2, diameterX: 3}, scene);
    
    option value 默认值
    segments (数字) 水平分段的数值 32
    diameter 球直径(数字) 1
    diameterX X轴上的直径(数字),如果设置会覆盖diameter diameter
    diameterY Y轴上的直径(数字),如果设置会覆盖diameter diameter
    diameterZ Z轴上的直径(数字),如果设置会覆盖diameter diameter
    arc (数字) 周长(纬度)在0和1之间的比率 1
    slice (数字) 高度(经度)在0和1之间的比率 1
    updatable 网格可更新则为true false
    sideOrientation (数字)排列方向 DEFAULTSIDE
  • 平面网格

    var plane = BABYLON.MeshBuilder.CreatePlane("plane", {}, scene); // default plane
    var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 5, height: 2}, scene);
    
    option value 默认值
    size 平面的尺寸 1
    height 高(长)度 size
    width 宽度 size
    updatable 网格可更新则为true false
    sideOrientation (数字类型) side orientation DEFAULTSIDE
    faceUV 含一个Vector4类型值的数组,ONLY WHEN sideOrientation:BABYLON.Mesh.DOUBLESIDE set Vector4(0,0,1,1)
    backUVs 含一个Vector4类型值的数组,ONLY WHEN sideOrientation:BABYLON.Mesh.DOUBLESIDE set Vector4(0,0,1,1)
    sourcePlane (Plane) source plane (maths) the mesh will be transformed to null

    sourcePlane 对平面来说是一个唯一的选项,它提供一种排列摆放位置的方法,目前它的排列定向为向量vector(0,0,1)。如果你希望方向是向量vector(0,-1,1),那么你就创建一个源平面。

    var sourcePlane = new BABYLON.Plane(0, -1, 1, 0);
    sourcePlane.normalize();
    

    这就创建了一个数学平面,作为方向源。第四个参数是在方向向量方向移动的距离。

  • 地面

    var ground = BABYLON.MeshBuilder.CreateGround("ground", {}, scene); //default ground
    var myGround = BABYLON.MeshBuilder.CreateGround("myGround", {width: 6, height: 4, subdivisions: 4}, scene);
    
    option value 默认值
    height 高(长)度 size
    width 宽度 size
    updatable 网格可更新则为true false
    subdivisions (数字类型) 平方细分数 1

    可以通过heightMap使用CreateGroundFromHeightMap创造一个形成起伏的地面而不是一个平坦的地面。

option解释

  • Face Colors or UV
    只在数量有限的拥有不同的面的形状可用,比如一个立方体,而不是一个球体。这允许你给这些网格的每个面添加独立的颜色或图像。详情:https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
  • Updatable
    当网格的可更新参数设置为true时,意味着可以更改与网格的每个顶点关联的数据,从而更改网格的形状。详情:https://doc.babylonjs.com/how_to/updating_vertices
  • Side Orientation(排列顺序)
    这个选项被用来描述图形的每一个面如何被观察。
    这个选项有四个可能的值:
    BABYLON.Mesh.FRONTSIDE,//前面
    BABYLON.Mesh.BACKSIDE,// 后面
    BABYLON.Mesh.DOUBLESIDE,// 双面
    BABYLON.Mesh.DEFAULT 默认值,当前等于FRONTSIDE,
  • Front and Back UV
    当一个网格有一个Side Orientation选项并被设为DOUBLESIDE ,那么它的前面和后面才可以显示不同的图像。更多内容详见https://doc.babylonjs.com/babylon101/LINK

位移和旋转

本文仅考虑设置一个网格的位置,旋转和缩放,如果想要了解多个网格的变换和旋转参考https://doc.babylonjs.com/babylon101/position#further-reading
BabylonJs的3D场景中通过特定的方法传入数值来调整物体的位置、旋转与尺寸缩放。

  • 坐标系:对网格进行变换必须有一个参考系:用于描述位置,旋转,缩放,并有助于可视化应用这些方法效果。可视化可以帮助使用者建立一个不对称的形状。(Babylon.js使用左手坐标系)
    坐标系有两种,世界坐标系和局部坐标系。世界坐标系的位置永远不变,局部坐标系会随网格变换而变化,无论网格的位置如何,局部坐标系原点总是位于网格创建时的中心点处。不过局部坐标系原点可以通过TransformNode或利用矩阵设置pivot point来更改。
    网格进行旋转和缩放的中心点位于局部坐标系的原点处。
    在所有坐标系中,x轴为红色,y轴为绿色,z轴为蓝色。当物体网格(meshes)被创建时,它们的中心点被放置在世界坐标的原点,它们的位置总是相对于世界坐标的。
  • Vectors:所有的位移,旋转,和缩放的值都通过Vector(矢量)来设置。
  • The Pilot(这里应该翻译为网格或模型吧):网格创建之后,其中心点在世界原点处,所有轴旋转值为0,缩放值为1,世界坐标系与网格的局部坐标系重合
  • Position:使用Vector(x,y,z)使模型在世界坐标系中移动,局部坐标系随模型一起移动。
    pilot.position = new BABYLON.Vector3(2,3,4);
    
    或者分别设置:(此时局部坐标系坐标轴和世界坐标系坐标轴保持相同的方向)
    pilot.position.x  =  2;
    pilot.position.y  =  3;
    pilot.position.z  =  4;
    
  • 旋转
    注意:在3D空间中旋转很棘手,模型多次旋转时,旋转的发生顺序不同,模型的最终方向将不同,你还需要注意旋转使用的是哪个坐标系。三维建模中应用旋转有很多不同的约定,Babylon中约定的相关细节详见https://doc.babylonjs.com/resources/rotation_conventions
    babylon中旋转:
     pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);
    
    或者:(注意:旋转角度运用弧度制而非角度制)
    pilot.rotation.x  =  alpha; //绕X轴旋转
    pilot.rotation.y  =  beta;  //绕Y轴旋转
    pilot.rotation.z  =  gamma; //绕Z轴旋转
    
    在这里三个旋转给出了三个不同的轴,你可能会有疑问——“它适用于哪一个参照系?它是以什么样的顺序来描述的?以及它在哪个方向?”
    以下两种约定都是Babylon使用的,因为这两种约定都会导致相同的结果。
    公约一(以局部坐标系来描述旋转): 对于使用局部坐标轴旋转物体时,是先以Y、X、Z轴的顺序旋转网格物体的,旋转的顺序是逆时针。
    以下图像序列依次显示了图形的初始位置,然后围绕局部坐标系的Y轴旋转(顺时针还是逆时针…)90度,然后绕局部坐标系的X轴旋转90度,然后围绕局部Z轴旋转90度。 (小轴代表世界坐标轴方向)Babylon.js阅读笔记一
    公约二(以世界坐标系来描述旋转, 与公约1相比,旋转中心及旋转轴都没有改变。):对于使用世界坐标轴旋转物体时,是先以Z、X、Y轴的顺序旋转网格物体的,旋转的顺序是逆时针。
    以下图像序列依次显示了图形的初始位置,然后绕世界坐标轴的Z轴旋转90度,然后绕世界坐标轴的X轴旋转90度,然后绕世界坐标轴的Y轴旋转90度。
    Babylon.js阅读笔记一
    当以世界坐标系来描述旋转时,以网格与世界坐标轴平行的轴,以局部坐标系原点为旋转中心来旋转,沿着坐标轴正方向看所有的旋转都是逆时针的

以下代码会产生相同的效果

pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);
pilot.rotation.x  =  alpha;
pilot.rotation.y  =  beta;
pilot.rotation.z  =  gamma;pilot.rotation.z  =  gamma;
pilot.rotation.x  =  alpha;
pilot.rotation.y  =  beta;pilot.rotation.y  =  beta;
pilot.rotation.z  =  gamma;
pilot.rotation.x  =  alpha;
  • 旋转队列
    现在的问题是:如果你想要一系列的旋转,从X轴开始,然后是Y轴,然后Z轴,该怎么做。对世界坐标轴和局部坐标轴而言,BabylonJs都有对应的rotate和addRotation方法 。.你可以使用addRotation将一系列旋转链接起来,如下所示,这个方法提供三次关于某个轴的旋转角度,然后将他们链式链接起来
mesh.addRotation(Math.PI/2, 0, 0).addRotation(0, Math.PI/2, 0).addRotation(0, 0, Math.PI/2);

下边的序列图像显示了上述代码的旋转过程: 从原始位置开始,绕局部坐标系X轴旋转90度,然后绕局部Y轴旋转90度,然后绕局部Z轴旋转90度。(小轴代表世界坐标轴方向)
Babylon.js阅读笔记一
在一般的网格里,使用addRotation(alpha, beta, gamma)进行旋转,通常都有其中两个属性为0。,alpha是绕局部X轴旋转,beta是绕局部Y轴旋转,gamma是绕局部Z轴旋转

  • RotationQuaternions(旋转四元数)
    旋转的另一个替代方法是rotationQuaternions,尽管他们使用起来很复杂,但可以克服万向节锁的问题。在一个网格上同时使用rotation和rotationQuaternions是不允许的,如果用了rotationQuaternions,那么rotation就会失效。详情https://doc.babylonjs.com/resources/rotation_conventions#warning
  • 缩放
    沿着局部坐标系的x,y,z轴缩放设置:
    mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);
    或者分别设置:
    mesh.scaling.y = 5;
    下图显示了一个单元立方体绕Z轴旋转,并沿局部Y轴缩放
    Babylon.js阅读笔记一