Babylon.js引擎

        Babylon.js是由HTML5和WebGL构建的3D游戏的完整javascript,与Three.js引擎不同,它倾向于基于Web进行游戏开发与碰撞检测 。

一、简介

        Babylon.js支持WebGL 2.0的新特性包括多重渲染目标,顶点数组对象,一致缓冲区对象,遮挡查询和3D纹理等。

具体功能:
        ❑ 根据开发人员的需求可方便快捷地创建出3D图形。
        ❑ 为物体的渲染提供多种类型的纹理和材质。
        ❑ 自带强大的阴影计算功能,支持PCF和PCSS阴影算法。
        ❑ 对物理引擎进行封装,为Web游戏开发者提供了极大的便利。
        ❑ 支持多种格式的3D物体模型和骨骼动画,让3D场景更加丰富。
        ❑ 引擎中带有多种着色器,可以实现多种逼真的效果。

二、应用

此示例显示一个旋转球体,具体代码如下:

 <! DOCTYPE html>
        2    <html>
        3        <head>
        4             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        5             <title>Babylon.js sample code</title>
        6             <script type="text/javascript" src="bulid/babylon.custom.js"></script>
        7             <style>
        8                 ......//此处省略CSS样式的定义,请读者自行查看随书源代码
        9             </style>
        10        </head>
        11    <body>
        12        <span  id="fpsLabel">FPS</span>
        13        <span  id="versionLabel">Version</span>
        14        <canvas id="renderCanvas"></canvas>
        15        <script>
        16             var canvas = document.getElementById("renderCanvas"); //获取Canvas对象
        17             var engine = new BABYLON.Engine(canvas, true);   //获取Babylon引擎对象
        18             document.getElementById("versionLabel").innerHTML=
        19                 '&nbspVersion&nbsp<br>WebGL '+engine.webGLVersion; //获取引擎的WebGL版本
        20             var createScene = function () {                   //创建场景的方法
        21                 var scene = new BABYLON.Scene(engine);       //创建场景对象
        22                 var camera = new BABYLON.ArcRotateCamera("camera1",
        23                     0, 0, 0, new BABYLON.Vector3(0, 0, 0), scene); //创建弧度旋转摄像机
        24                 camera.setPosition(new BABYLON.Vector3(0,40,40)); //设置摄像机的位置
        25                 camera.attachControl(canvas, true);          //添加对Canvas的控制
        26                 var light = new BABYLON.DirectionalLight("DirectionalLight",
        27                     new BABYLON.Vector3(-1, -1, -1), scene); //创建平行光
        28                 light.position=new BABYLON.Vector3(30,30,30); //设置阴影投射的位置
        29                 var materialSphere1=new BABYLON.StandardMaterial("materialSphere1", scene);
        30                 materialSphere1.wireframe = true;             //是否使用网格
        31                 var sphere=BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:
                          30}, scene); //球体
        32                 sphere.material=materialSphere1;              //设置球体的材质
        33                 var angle=0;                                   //角度
        34                 scene.onBeforeRenderObservable.add(()=>{     //渲染前的执行函数
        35                     angle=angle+0.01;                         //增加角度
        36                     sphere.rotation.set(0, angle,0);          //修改球体的旋转角度
        37                 })
        38                 return scene; };                               //返回场景对象
        39             var fpsLabel=document.getElementById('fpsLabel'); //获取FPS标签的DOM对象
        40             var scene=createScene();                          //创建场景
        41             engine.runRenderLoop(function () {                //启动渲染循环
        42                 if (scene) {                                   //如果场景创建完成
        43                     fpsLabel.innerHTML='&nbspFPS&nbsp<br>&nbsp${Math.floor(engine
        .getFps())}';
44                     scene.render();                           //渲染场景
45                 }});
46             window.addEventListener("resize", function () {  //窗口变化监听
47                 engine.resize();                              //引擎重新设置窗口尺寸
48             });
49        </script>
50    </body>
51    </html>

        ❑ 第1~14行为网页开发中经常使用的一些标签。其功能为设置网页标题,显示页面的全屏效果,显示FPS和引擎使用的WebGL的版本以及将build目录下的babylon.custom.js作为外部文件引入案例中进行使用。
        ❑ 第16~19行的代码为获取Canvas的DOM对象、Babylon的引擎对象和当前Babylon.js使用的WebGL版本。根据浏览器对WebGL的支持度不同,此处获取到的版本会有所不用。
        ❑ 第20~38行的代码为创建场景。主要包括创建场景对象和摄像机并添加控制,创建光源、材质、球体并指定其材质,以及在渲染之前修改球体的旋转角度。这些都是Babylon.js开发中必不可少的部分,后文将详细介绍。
        ❑ 第39~51行代码的功能为获取FPS标签对象,创建场景,启动渲染循环以进行场景的渲染以及FPS的更新。最后添加窗口变化监听,当窗口大小发生变化时,引擎会重新设置渲染窗口的大小,保证渲染出的画面不会变形。

三  组件 

(1)场景

它是其它组件的容器,有许多操作函数,下面简要介绍几种操作函数 。

        getScene()   获取与场景关联的引擎

         getMeshByName() :根据名字获取场景中的网格对象

         removeMesh() :删除场景网格列表中的网格对象  

        registerBeforeRender()  :在每帧渲染之前注册一个函数

(2)摄像机

        与Three.js中正交、透视摄像机不同,此处摄像机更加专注于控制,主要有通用摄像机、弧度旋转相机、跟随相机等。

        通用相机是其默认相机,它可以通过键盘和鼠标对其进行控制,在移动端可以通过手指触摸控制相机 ,示例如下:

1    var createScene = function () {                    //创建场景
        2         var scene = new BABYLON.Scene(engine);       //获取场景对象
        3         //创建通用相机,并指定相机的名字和位置
        4         var camera = new BABYLON.UniversalCamera("camera", new BABYLON.Vector3(0,
                  0, 5), scene);
        5         camera.setTarget(BABYLON.Vector3.Zero());      //设置观察目标
        6         camera.attachControl(canvas, true);             //开启对Canvas的控制
        7         //创建半球光源,并指明其名字和光线投射方向
        8         var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1,
                  0), scene);
        9         var material=new BABYLON.StandardMaterial("boxMaterial", scene); //创建材质
        10        material.diffuseTexture=new BABYLON.Texture("textures/crate.png", scene);
                  //设置漫反射纹理
        11        var box1=BABYLON.MeshBuilder.CreateBox("box1", {height:3, width:3, depth:3},
                  scene)
        12        box1.position.set(-3,0,0);                    //设置立方体1的位置
        13        box1.material=material;                       //设置立方体1的材质
        14        var box2=box1.clone();                        //克隆网格对象
        15        box2.position.set(3,0,0);                     //设置立方体2的位置
        16        return scene;                                 //返回场景对象
        17      };

        ❑ 第1~6行代码的功能为获取场景对象,创建通用相机并指定相机名字和位置,设置相机的观察目标位置。这样就完成了场景和通用相机的创建。
        ❑ 第7~16行代码的功能为创建半球光源并指明其名字和光线投射的方向,创建材质并设置材质的漫反射纹理,创建两个立方体并放置在场景的不同位置。

     弧度旋转相机始终指向给定的目标位置 ,并且可以围绕该目标旋转,目标作为旋转中心。示例如下:

1     var createScene = function () {//创建场景方法
        2         var scene = new BABYLON.Scene(engine); //创建场景
        3         //创建弧形旋转摄像机,并指定它的初始纵向旋转角度、初始横向旋转角度和旋转半径以及观察目标位置
        4         var camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2,
        5         Math.PI / 8, 20, BABYLON.Vector3.Zero(), scene);
        6         camera.attachControl(canvas, true);   //添加控制
        7         camera.lowerRadiusLimit = 6;            //设置最低旋转半径
        8         camera.upperRadiusLimit = 20;          //设置最高旋转半径
        9         camera.useAutoRotationBehavior = true; //设置自动旋转
        10        //创建半球光源,并指定光源方向
        11        var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1,
                  0), scene);
        12        var material=new BABYLON.StandardMaterial("boxMaterial", scene); //创建材质
        13        material.diffuseTexture=new BABYLON.Texture("textures/crate.png", scene);
                  //设置漫反射纹理
        14        var box1=BABYLON.MeshBuilder.CreateBox("box1", {height:3, width:3, depth:3},
                  scene);
        15        box1.position.set(3,0,0);              //设置立方体1的位置
        16        box1.material=material;                //设置立方体1的材质
        17        var box2=box1.clone();                 //克隆立方体1的网格对象
        18        box2.position.set(-3,0,0);             //设置立方体2的位置
        19        return scene;                          //返回场景对象
        20    }

        ❑ 第1~9行代码的功能为创建场景对象,创建弧形旋转相机并指定初始纵向旋转角度、初始横向旋转角度和旋转半径以及观察目标的位置,开启对Canvas的控制和设置相机的最低旋转半径、最高旋转半径和开启相机自动旋转。
        ❑ 第10~19行代码的功能为创建半球光源并指明其名字和光线投射方向,创建材质并设置材质的漫反射纹理和创建两个立方体并放置在场景的不同位置。

        跟随相机是跟随目标运动改变位置而改变位置的相机,当目标网格对象的位置发生变化时,相机 会跟随目标网格对象改变位置。示例如下:

1      var createScene = function () {               //创建场景的方法
        2         var scene = new BABYLON.Scene(engine);    //获取场景对象
        3         var camera = new BABYLON.FollowCamera("FollowCam",
        4                  new BABYLON.Vector3(0, 10, -10), scene); //创建跟随相机
        5         camera.radius = 30;                        //设置相机与目标网格对象的距离
        6         camera.heightOffset = 10;                  //设置相机的高度偏移
        7         camera.rotationOffset =0;                  //设置相机在 xOy平面上的角度偏移
        8         camera.cameraAcceleration = 0.005         //设置相机在移动目标位置上的加速度
        9         camera.maxCameraSpeed = 10                 //设置相机的最大速度
        10        camera.attachControl(canvas, true);       //开启控制
        11        var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1,
                  0), scene);
        12        var mat = new BABYLON.StandardMaterial("mat1", scene);         //创建材质
        13        var texture = new BABYLON.Texture("textures/crate.png", scene); //加载纹理
        14        mat.diffuseTexture = texture;             //设置漫反射纹理
        15        var box = BABYLON.MeshBuilder.CreateBox("box", {size: 2}, scene);
        16        box.position = new BABYLON.Vector3(20, 0, 10);   //设置立方体的位置
        17        box.material = mat;                               //设置立方体的材质
        18        var boxesSPS = new BABYLON.SolidParticleSystem("boxes", scene, {updatable:
                  false});
        19        var set_boxes = function(particle, i, s) {       //设置立方体位置函数
        20             particle.position = new BABYLON.Vector3(-50 + Math.random()*100, -50 +
                      Math.random()*100,
        21                                                  -50 + Math.random()*100); }
        22        boxesSPS.addShape(box, 400, {positionFunction:set_boxes});    //向粒子系统中
                  添加400个立方体
        23        var boxes = boxesSPS.buildMesh();                 //粒子系统创建网格对象
        24        camera.lockedTarget = box;                        //设置相机的目标网格对象
        25        var alpha = 0;                                     //立方体运动角度
        26        var orbit_radius = 20;                            //立方体运动半径
        27        scene.registerBeforeRender(function () {         //渲染之前执行的函数
        28         alpha +=0.01;                                     //更改运动角度
        29         box.position.x = orbit_radius*Math.cos(alpha);  //更改立方体的 x位置
        30         box.position.y = orbit_radius*Math.sin(alpha);  //更改立方体的 y位置
        31         box.position.z = 10*Math.sin(2*alpha);          //更改立方体的 z位置
        32         camera.rotationOffset = (18*alpha)%360;         //更改摄像机的旋转偏移
        33        });
        34        return scene; };

        ❑ 第1~9行代码的主要功能为获取场景对象和创建跟随相机,以及设置相机与目标网格对象的距离、相机的高度偏移、相机在xOy平面上的角度偏移和相机移动到目标位置的加速度。
        ❑ 第10~16行代码的主要功能为创建标准材质并设置它的漫反射纹理,创建立方体网格对象并设置它的位置和材质。
        ❑ 第17~23行代码的主要功能为创建粒子系统,向粒子系统中添加400个立方体网格对象并设置每个立方体网格对象的位置。粒子系统创建网格对象以及将跟随相机的观察目标指向带有纹理贴图的立方体网格对象。需在目标网格对象之后,指定跟随相机的目标时。
        ❑ 第24~31行的代码主要功能为不断改变立方体网格对象的位置使跟随相机跟随其运动,同时也要不断改变相机的旋转偏移,以呈现出更好的相机跟随效果。

(3)网格对象

        自带的网格对象包括 立方体、球体、圆柱体、曲面细分多边形等,创建网格对象时,最大的不同就是options参数的不同。options是一个参数数组,包含这个网格对象的构建信息。示例如下: 

1      var createScene = function () {
        2          var scene = new BABYLON.Scene(engine);               //创建场景和摄像机
        3          var camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 0,
        4                 new BABYLON.Vector3(0, 0, -0), scene);        //创建摄像机
        5          camera.setPosition(new BABYLON.Vector3(0,30,35));   //设置摄像机的位置
        6          camera.attachControl(canvas, true);                  //开启摄像机控制
        7          var light = new BABYLON.PointLight("light", new BABYLON.Vector3(30,30,20),
                    scene);
        8          light.intensity = 0.7;                               //设置光照强度
        9          var meshArray=[];                                     //网格对象数组
        10         meshArray.push(BABYLON.MeshBuilder.CreateBox("box",
        11             {height:6, width:6, depth:6}, scene))               //新建立方体
        12         meshArray.push(BABYLON.MeshBuilder.CreateSphere("sphere",
        13             {diameter: 5}, scene))                            //新建球体
        14         meshArray.push(BABYLON.MeshBuilder.CreateCylinder("cone",
        15             {diameterTop: 0, diameterBottom:6, height:5, tessellation: 8}, scene))
                      //新建圆柱体
        16         meshArray.push( BABYLON.MeshBuilder.CreatePlane("plane",
        17             {width: 4, height:4, sideOrientation:BABYLON.Mesh.DOUBLESIDE}, scene))
                      //新建平面
        18         meshArray.push(BABYLON.MeshBuilder.CreateDisc("disc",
        19             {radius:4, tessellation: 3, sideOrientation:BABYLON.Mesh.DOUBLESIDE}, scene))
        20         meshArray.push(BABYLON.MeshBuilder.CreateTorusKnot("tk", {}, scene));
                    //新建圆环结
        21         meshArray.push(BABYLON.MeshBuilder.CreateTorus("torus",
        22             {diameter:5, thickness:1.5}, scene));                    //新建圆环
        23         meshArray.push(BABYLON.MeshBuilder.CreateGround("gd",
        24             {width: 6, height:6, subdivsions:4}, scene));              //新建地面
        25         var groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
        26         var ground =BABYLON.MeshBuilder.CreateGround("gd",
        27             {width: 40, height:15 , subdivsions: 4}, scene);         //创建地板
        28         ground.material = groundMaterial;                          //设置地板的材质

QQQ:
29         var meshMaterial=new BABYLON.StandardMaterial("meshMaterial", scene)
                    //创建材质
        30         for(var i=0; i<meshArray.length; i++){                //遍历网格对象数组
        31                 meshArray[i].material=meshMaterial;         //指定网格对象的材质
        32                 meshArray[i].material.diffuseColor=new BABYLON.Color3(1, Math.random
                          (), Math.random());
        33                 meshArray[i].position.x=-16+Math.floor(i/2)*10; //指定网格对象的x位置
        34                 meshArray[i].position.y=4;                      //指定网格对象的y位置
        35                 meshArray[i].position.z=(i%2==0)? -4:6;         //指定网格对象的z位置
        36              }
        37                 return scene;                                    //返回场景对象
        38      };

              ❑ 第1~8行代码的功能为创建场景、摄像机和光照等基本组件。读者可能对摄像机和光照的知识不熟悉,不要担心,这些知识将在下文进行详细介绍。
             ❑ 第9~24的代码为新建不同的网格对象,包括立方体、球体、圆柱体、圆环结和圆环等,然后将其放进网格对象数组进行管理,以及创建地板并指定地板的材质。
             ❑ 第25~37行代码的功能为遍历网格对象数组,指定各个网格对象的材质并设置材质的漫反射颜色,指定各网格对象的x、y、z坐标,最后返回场景对象。
           高度图网格对象就是根据灰度图中各个像素的灰度值计算出地形的顶点坐标数据,示例如下:

1    //创建标准材质,并指定其漫反射纹理
        2    var groundMaterial=new BABYLON.StandardMaterial("groudMaterial", scene);
        3    groundMaterial.diffuseTexture=new BABYLON.Texture("textures/ground.jpg", scene)
        4    //根据高度图创建网格对象,指定灰度图的宽度和高度以及细分数量,设置地形的最大高度
        5    var ground = BABYLON.MeshBuilder.CreateGroundFromHeightMap("gdhm",
        6        "textures/default.png", {width:257, height :257, subdivisions:257,
                  maxHeight: 128}, scene);
        7    ground.material=groundMaterial;

        本段代码的功能为创建标准材质并指定其漫反射纹理,根据高度图创建网格对象并指定灰度图的宽度和高度以及细分数量,设置地形的最大高度,最后指定高度图网格对象的材质。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值