Babylon.js游乐场初体验,Babylon.js第一个demo程序


Babylon.JS是什么

Babylon.JS是在Web上编写3D程序的一套框架。好像亮哥已经第二次说了,不要闲烦哦,因为如果你有女朋友了,会更烦。

代码下载请单击这里Babylon.JS案例代码下载


游乐场(The Playground)

Babylon.JS提供了一个在线编辑器,它叫做The Playground,它是制作自己场景的最快捷,最简单的方法。The Playground是游乐场的意思,这个名字有点古怪,可能不好理解,你只需要知道,The Playground是一个实验学习Babylon.JS的地方,就很好理解了。

好了,废话说太多了,容易引起人方案,我们直接点击进入Babylon Playground来看看吧。

有时候网络不好,可能打不开,耐心等待,可能需要2分钟左右才能打开。


游乐场的使用

游乐场的使用相对来说比较简单,左边输入代码,点击顶部的执行按钮,右边就出现结果了。如下图所示:

babylonjs游乐场

上面游乐场中有个下载按钮比较重要,点击代码,你能下载一份源代码下来研究。

先不管左边的代码是什么意思,因为一来就看这么多的代码,其实有点难懂。所以,解决烦恼的办法就是逃避烦恼,我们先看看其他的。


引入Babylon.js引擎文件

Babylon.js引擎怎么嵌入网页中,让它运行起来呢?很简单,只要html文件中引入Babylon.js文件就可以了。代码如下:

1.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
    <title>Babylon - 开始之旅</title>
    <!-- Link to the last version of BabylonJS -->
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <!-- Link to the last version of BabylonJS loaders to enable loading filetypes such as .gltf -->
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <!-- Link to pep.js to ensure pointer events work consistently in all browsers -->
    <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
</body>
</html>

代码第7行:这里引入了babylon.js文件,这个文件会自己初始化babylon.js的一些变量和环境。注意,这里引用的是最新的babylon.js库文件。

如果 https://preview.babylonjs.com/babylon.js这个文件无法下载,可能是无法访问国外网站的原因,你可以下载本课的代码,并更改一下这个js引用地址就可以了。

上面的代码中,我们引入了3个文件: |文件名|含义| |---|---| |babylon.js|最新的babylon.js库文件| |babylonjs.loaders.min.js |BabylonJS load 用于加载文件,如.gltf| |pep.js|用于光标操作,如鼠标移动,手指移动。这个库主要处理在手机、电脑上光标移动的一致性。|

这里要强调一下pep.js这个文件,这个一个jquery的插件,并不是babylon.js引擎独有的,没有出现babylon.js之前,pep.js就已经有了。

上面的代码,我们在<body>中插入了<canvas>画布。这个<canvas>画布将是我们显示3D渲染结果的地方。只不过,它现在很孤独,什么都没有。


加入一些样式

在中插入一些样式,让页面更美观,如下:

<style>
    html, body {
        overflow: hidden;
        width   : 100%;
        height  : 100%;
        margin  : 0;
        padding : 0;
    }

    #renderCanvas {
        width   : 100%;
        height  : 100%;
        touch-action: none;
    }
</style>

上面代码将renderCanvas设置为整个浏览器的宽度和高度。

首先,我们在的末尾插入一些js代码:

<script>
    window.addEventListener('DOMContentLoaded', function() {
        // 在这里添加代码.
    });
</script>

上面的代码,我们将javascript代码包装在DOMContentLoaded事件处理程序中,这样网页加载完成后,才会执行js代码。


第一个demo中由哪些组成

我们下面接着添加一些代码,我们的第一个demo由如下内容组成:

先看一下效果图: babylonjs第一个demo

  • 一个场景
  • 两个形状(一个球体、一个地平面),形状也可以叫做物体

找到画布

我们将逐步完成它。首先,从HTML文档中获取canvas元素的引用,canvas是绘图3D的地方:

var canvas = document.getElementById('renderCanvas');

创建引擎类

然后,我们初始化后一个Babylon 3D引擎,调用BABYLON.Engine函数,BABYLON是引擎的全局类,它有很多成员变量,其中Engine就是引擎函数。

var engine = new BABYLON.Engine(canvas, true);

第一个参数是canvas,表示画布,引擎渲染的结果需要有一个地方放,就是canvas画布

第二个参数antialias,代表是否反锯齿,这里为true,表示渲染的物体边缘不会出现锯齿,这样会消耗更多的GPU资源,如果为false,表示不反锯齿,这样物体边缘看上去会很毛躁,但是不会消耗过多的GPU资源。

BABYLON.Engine函数的api可以在这里查看


创建场景

现在我们的场景,需要相机和灯光以及一些几何体。

这里的几何体就是一些形状、3D模型之类的东西,例如三角形,正方形。

下面的 createScene()函数主要用来生成场景,场景大家可以理解为一个舞台。下面的代码创建一个场景。

var createScene = function() {
    // 创建一个基本的BABYLON场景(舞台)对象。
    var scene = new BABYLON.Scene(engine);

    // 创建一个FreeCamera,并将其位置设置为(x:0,y:5,z:-10)。
    var camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 5,-10), scene);

    // 将相机的焦点指向场景的原点。
    camera.setTarget(BABYLON.Vector3.Zero());

    // 将相机连接到画布,这样画布才知道渲染什么。
    camera.attachControl(canvas, false);

    // 创造一个灯光,指向(0,1,0)方向  - 意思是指向天空。
    var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);

    // 创建一个内置的“球体”形状。
    var sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {segments:16, diameter:2}, scene);

    // 将球体向上移动1个单位。
    sphere.position.y = 1;

    // 创建一个内置的“地面”形状。
    var ground = BABYLON.MeshBuilder.CreateGround('ground1', {height:6, width:6, subdivisions: 2}, scene);

    // 返回创建的场景。
    return scene;
}

这个函数做的事情有点多,不过在注释中有一些说明了。这里,我们不厌其烦再给大家解释一下。

BABYLON.Scene这一行代码创建一个场景,或者叫做舞台,你可以理解为演话剧的舞台。这个函数接受前面生成的engine作为参数,返回一个场景。


创建一个相机

为了让舞台中的内容能够显示到电视上,需要一个相机来摄影,上面代码中BABYLON.FreeCamera就是创建一个相机。

FreeCamera在巴比伦中叫做自由相机,其实是一个透视相机,你就把它理解成一个普通的手机就可以了。

FreeCamera的原型如下:

FreeCamera(name: string, position: Vector3, scene: Scene, setActiveOnSceneIfNoneActive?: boolean)
  • 第一个参数name:定义这个相机的名字,随便去一个你顺眼的名字,如 尼康
  • 第二个参数position是位置,它是一个向量,表示相机在场景中的位置。
  • 第三个参数是场景,是我们上面一小节生成的scene。
  • 第4个参数是一个可选参数,你可以不填写,本课的代码中就没有写这个参数。

ok,这个函数会返回一个相机对象。

创建一个相机后,我们把相机指向原点,使用的是下面的代码:

camera.setTarget(BABYLON.Vector3.Zero());

通过:camera.attachControl这函数可以把相机和canvas关联起来,这样相机渲染的内容,就可以显示在canvas上了。

如果对FreeCamera API感兴趣,你可以看它的API文档


创建一个灯光

如果没有灯光,那么整个场景是黑色的,我们需要增加一个灯光,灯光有很多种,这里使用HemisphericLight,翻译成中文是球形灯光的意思,关于灯光后面我们再介绍,你这里只有理解它是一个光源就可以了。HemisphericLight的原型如下:

HemisphericLight(name: string, direction: Vector3, scene: Scene): HemisphericLight
  • 第一个参数:光的名字,随便取,你记得住就行。

  • 第二个参数:光的方向

  • 第三个参数:光要加入到的场景

  • 返回值:返回一个生成的灯光。

var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);

上面的代码的意思是:创造一个灯光,指向(0,1,0)方向,我怀疑你现在不知道方向的概念,也不知道这光指向何方,不过没关系,后面说光源的时候,再回来了解也不迟。


创建物体

舞台、灯光、相机都已经准备就绪,现在差演员上场了,这里的演员就是物体本身。

BABYLON.MeshBuilder是一个创建物体,我们一般称为网格物体的创建者,它有一个CreateSphere函数,可以创建一个椭圆。

BABYLON.MeshBuilder.CreateSphere的函数原型如下:

CreateSphere(name: string, options: object, scene?: Nullable<Scene>): Mesh
  • 第一个参数:椭圆的名字,随便取,你记得住就行。

  • 第二个参数:椭圆的一些参数,这是一个对象{},里面可以写你希望设置的参数。如segments表示分段,椭圆有多少段组成,这个概念有点难以理解,不过没关系,我们后面再说。diameter表示半径,就是这个椭圆的半径,注意一般椭圆有x,y两个半径,这里取一样的,那么就是一个圆了。

  • 第三个参数:椭圆要加入到的场景

  • 返回值:返回一个生成的椭圆网格模型。

我们重新把上面的代码copy一份在这里:

var sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {segments:16, diameter:2}, scene);

这里表示创建一个名字为sphere的椭圆,半径为2,分16段,并且把这个椭圆放到scene场景中。


设置椭圆的位置

sphere.position.y = 1;

设置椭圆的位置。


创建一个底面

BABYLON.MeshBuilder.CreateGround函数是创建一个底面,代码如下:

// 创建一个内置的“地面”形状。
var ground = BABYLON.MeshBuilder.CreateGround('ground1', {height:6, width:6, subdivisions: 2}, scene);

底面的宽度,高度都是6,其实把他理解为长、宽可能更容易理解一些。

ok,讲了这么多,终于把createScene函数讲完了,现在我们需要调用它:

var scene = createScene();

好了,这里我建议你打开这段代码,看一下。


渲染循环

接下来的三行javascript代码非常重要,因为它们注册了一个渲染循环来重复渲染画布上的场景,什么是渲染循环,我们后面再给各位大大夜谈:

engine.runRenderLoop(function() {
    scene.render();
});

最后,我们监听一个canvas或者window 的resize事件,用于当窗口变化时,引擎也能适应大小:

window.addEventListener('resize', function() {
    engine.resize();
});

就是这样!保存文件并使用Web浏览器打开2.html。你应该看到以下结果,如果打开很慢,是因为下载文件很慢,不要慌张,我预计国外的网速需要2分钟。如果你嫌慢,可以直接打开 3.html,我把js文件,放在了本地,代码可以在这里下载[]()

babylonjsd-emo

为了让大家有更清晰的理解,我们将2.html的所有代码列出如下:

2.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
    <title>Babylon - Getting Started</title>
    <!--- Link to the last version of BabylonJS --->
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <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>
    <script>
        window.addEventListener('DOMContentLoaded', function(){
            // get the canvas DOM element
            var canvas = document.getElementById('renderCanvas');

            // load the 3D engine
            var engine = new BABYLON.Engine(canvas, true);

            // createScene function that creates and return the scene
            var createScene = function(){
                // create a basic BJS Scene object
                var scene = new BABYLON.Scene(engine);

                // create a FreeCamera, and set its position to (x:0, y:5, z:-10)
                var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5,-10), scene);

                // target the camera to scene origin
                camera.setTarget(BABYLON.Vector3.Zero());

                // attach the camera to the canvas
                camera.attachControl(canvas, false);

                // create a basic light, aiming 0,1,0 - meaning, to the sky
                var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);

                // create a built-in "sphere" shape; its constructor takes 6 params: name, segment, diameter, scene, updatable, sideOrientation 
                var sphere = BABYLON.Mesh.CreateSphere('sphere1', 16, 2, scene);

                // move the sphere upward 1/2 of its height
                sphere.position.y = 1;

                // create a built-in "ground" shape;
                var ground = BABYLON.Mesh.CreateGround('ground1', 6, 6, 2, scene);

                // return the created scene
                return scene;
            }

            // call the createScene function
            var scene = createScene();

            // run the render loop
            engine.runRenderLoop(function(){
                scene.render();
            });

            // the canvas/window resize event handler
            window.addEventListener('resize', function(){
                engine.resize();
            });
        });
    </script>
</body>
</html>

感谢大家

感谢大家的阅读,可能有很多概念大家还不太理解,不过没关系,知识像追女孩子,还是要花一些时间,才能和她发生点什么的。