初學WebGL引擎-BabylonJS:第4篇-燈光動畫與叢林場景


前幾章接觸的案例都是接近靜態的,由這張開始開始接觸大量動態的內容,包括

球體燈光,變動的形體,以及一個虛擬的叢林場景

下章我會試着結合1-9案例的內容做出一個demo出來

【playground】-lights(燈光)

源碼

 

var createScene = function () {
    var scene = new BABYLON.Scene(engine);

    // Setup camera
    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);
    camera.setPosition(new BABYLON.Vector3(-10, 10, 0));
    camera.attachControl(canvas, true);

    // Lights
    var light0 = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(0, 10, 0), scene);
    var light1 = new BABYLON.PointLight("Omni1", new BABYLON.Vector3(0, -10, 0), scene);
    var light2 = new BABYLON.PointLight("Omni2", new BABYLON.Vector3(10, 0, 0), scene);
    var light3 = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(1, -1, 0), scene);

    var material = new BABYLON.StandardMaterial("kosh", scene);
    var sphere = BABYLON.Mesh.CreateSphere("Sphere", 16, 3, scene);

    // Creating light sphere
    var lightSphere0 = BABYLON.Mesh.CreateSphere("Sphere0", 16, 0.5, scene);
    var lightSphere1 = BABYLON.Mesh.CreateSphere("Sphere1", 16, 0.5, scene);
    var lightSphere2 = BABYLON.Mesh.CreateSphere("Sphere2", 16, 0.5, scene);

    lightSphere0.material = new BABYLON.StandardMaterial("red", scene);
    lightSphere0.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
    lightSphere0.material.specularColor = new BABYLON.Color3(0, 0, 0);
    lightSphere0.material.emissiveColor = new BABYLON.Color3(1, 0, 0);

    lightSphere1.material = new BABYLON.StandardMaterial("green", scene);
    lightSphere1.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
    lightSphere1.material.specularColor = new BABYLON.Color3(0, 0, 0);
    lightSphere1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);

    lightSphere2.material = new BABYLON.StandardMaterial("blue", scene);
    lightSphere2.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
    lightSphere2.material.specularColor = new BABYLON.Color3(0, 0, 0);
    lightSphere2.material.emissiveColor = new BABYLON.Color3(0, 0, 1);

    // Sphere material
    material.diffuseColor = new BABYLON.Color3(1, 1, 1);
    sphere.material = material;

    // Lights colors
    light0.diffuse = new BABYLON.Color3(1, 0, 0);
    light0.specular = new BABYLON.Color3(1, 0, 0);

    light1.diffuse = new BABYLON.Color3(0, 1, 0);
    light1.specular = new BABYLON.Color3(0, 1, 0);

    light2.diffuse = new BABYLON.Color3(0, 0, 1);
    light2.specular = new BABYLON.Color3(0, 0, 1);

    light3.diffuse = new BABYLON.Color3(1, 1, 1);
    light3.specular = new BABYLON.Color3(1, 1, 1);

    // Animations
    var alpha = 0;
    scene.beforeRender = function () {
        light0.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, 10 * Math.cos(alpha));
        light1.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, -10 * Math.cos(alpha));
        light2.position = new BABYLON.Vector3(10 * Math.cos(alpha), 0, 10 * Math.sin(alpha));

        lightSphere0.position = light0.position;
        lightSphere1.position = light1.position;
        lightSphere2.position = light2.position;

        alpha += 0.01;
    };

    return scene;
}
View Code

 

效果

 

筆記:

定義光源-點光源:

new BABYLON.PointLight("Omni0", new BABYLON.Vector3(0, 10, 0), scene);//(3個光點)

 

定義光源-定向光源:

new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(1, -1, 0), scene);//(類似於太陽)

 

光源參數樹立:   

light0.diffuse = new BABYLON.Color3(1, 0, 0);//(擴散光源)
light0.specular = new BABYLON.Color3(1, 0, 0);//(鏡面光源)

 

球體光源處理:

    lightSphere0.material.diffuseColor = new BABYLON.Color3(0, 0, 0);//(球體擴散光源)
    lightSphere0.material.specularColor = new BABYLON.Color3(0, 0, 0);//(球體鏡面光源)
    lightSphere0.material.emissiveColor = new BABYLON.Color3(1, 0, 0);//(球體反射光源)

 

 

事件處理:

beforeRender

    var alpha = 0;
    scene.beforeRender = function () {
        light0.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, 10 * Math.cos(alpha));
        light1.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, -10 * Math.cos(alpha));
        light2.position = new BABYLON.Vector3(10 * Math.cos(alpha), 0, 10 * Math.sin(alpha));

        lightSphere0.position = light0.position;
        lightSphere1.position = light1.position;
        lightSphere2.position = light2.position;

        alpha += 0.01;
    };

以上代碼基於alpha的自增,控制參數的變化

 

以上各參數還需要各位自行調節后run看看效果影響


 

【playground】-animations(動畫)

源碼

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);

    //Boxes
    var box1 = BABYLON.Mesh.CreateBox("Box1", 10.0, scene);
    box1.position.x = -20;
    var box2 = BABYLON.Mesh.CreateBox("Box2", 10.0, scene);

    var materialBox = new BABYLON.StandardMaterial("texture1", scene);
    materialBox.diffuseColor = new BABYLON.Color3(0, 1, 0);//Green
    var materialBox2 = new BABYLON.StandardMaterial("texture2", scene);

    //Applying materials
    box1.material = materialBox;
    box2.material = materialBox2;

    //Positioning box
    box2.position.x = 20;

    // Creation of a basic animation with box 1
    //----------------------------------------

    //Create a scaling animation at 30 FPS
    var animationBox = new BABYLON.Animation("tutoAnimation", "scaling.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                                                                    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
    //Here we have chosen a loop mode, but you can change to :
    //  Use previous values and increment it (BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE)
    //  Restart from initial value (BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE)
    //  Keep the final value (BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT)

    // Animation keys
    var keys = [];
    //At the animation key 0, the value of scaling is "1"
    keys.push({
        frame: 0,
        value: 1
    });

    //At the animation key 20, the value of scaling is "0.2"
    keys.push({
        frame: 20,
        value: 0.2
    });

    //At the animation key 100, the value of scaling is "1"
    keys.push({
        frame: 100,
        value: 1
    });

    //Adding keys to the animation object
    animationBox.setKeys(keys);

    //Then add the animation object to box1
    box1.animations.push(animationBox);

    //Finally, launch animations on box1, from key 0 to key 100 with loop activated
    scene.beginAnimation(box1, 0, 100, true);

    // Creation of a manual animation with box 2
    //------------------------------------------
    scene.registerBeforeRender(function () {

        //The color is defined at run time with random()
        box2.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());

    });

    return scene;
}
View Code

效果

筆記

盒子動畫

    var animationBox = new BABYLON.Animation("tutoAnimation", "scaling.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                                                                    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

 

 

參數分別是:name,變化的值,頻率(改成130可以看到綠色的跟抽風一樣抖動),【該參數不確定】,頻率結束后的處理類型

這里類型提供了以下幾種(機器翻譯)

/ /這里我們選擇一個循環模式,但你可以改變:

/ /使用前值和增量(BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE)

/ /重新啟動的初始值(BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE)

/ /保持最后的值(BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT)

 

接着定義動畫過程中的參數

 

var keys = [];
    //At the animation key 0, the value of scaling is "1"
    keys.push({
        frame: 0,
        value: 1
    });

    //At the animation key 20, the value of scaling is "0.2"
    keys.push({
        frame: 20,
        value: 0.2
    });

    //At the animation key 100, the value of scaling is "1"
    keys.push({
        frame: 100,
        value: 1
    });

 

frame:為時間量

value:為屬性值(此處為拉伸x的值)

//綁定值在動畫中

animationBox.setKeys(keys);

//盒子加載動畫

box1.animations.push(animationBox);

//場景內激活動畫

scene.beginAnimation(box1, 0, 100, true);

 

 

以上為左邊綠盒子的動畫

 

面顏色閃動的動畫代碼如下

    scene.registerBeforeRender(function () {

        //The color is defined at run time with random()
        box2.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());

    });

通過Math的隨機數改變box的三原色


 

【playground】-sprites(叢林場景)

 

廢話不都說,先貼源碼

var createScene = function () {
    var scene = new BABYLON.Scene(engine);

    // Create camera and light
    var light = new BABYLON.PointLight("Point", new BABYLON.Vector3(5, 10, 5), scene);
    var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 8, new BABYLON.Vector3(0, 0, 0), scene);
    camera.attachControl(canvas, true);

    // Create a sprite manager to optimize GPU ressources
    // Parameters : name, imgUrl, capacity, cellSize, scene
    var spriteManagerTrees = new BABYLON.SpriteManager("treesManager", "textures/palm.png", 2000, 800, scene);

    //We create 2000 trees at random positions
    for (var i = 0; i < 2000; i++) {
        var tree = new BABYLON.Sprite("tree", spriteManagerTrees);
        tree.position.x = Math.random() * 100 - 50;
        tree.position.z = Math.random() * 100 - 50;
        tree.isPickable = true;

        //Some "dead" trees
        if (Math.round(Math.random() * 5) === 0) {
            tree.angle = Math.PI * 90 / 180;
            tree.position.y = -0.3;
        }
    }

    //Create a manager for the player's sprite animation
    var spriteManagerPlayer = new BABYLON.SpriteManager("playerManager", "textures/player.png", 2, 64, scene);

    // First animated player
    var player = new BABYLON.Sprite("player", spriteManagerPlayer);
    player.playAnimation(0, 40, true, 100);
    player.position.y = -0.3;
    player.size = 0.3;
    player.isPickable = true;

    // Second standing player
    var player2 = new BABYLON.Sprite("player2", spriteManagerPlayer);
    player2.stopAnimation(); // Not animated
    player2.cellIndex = 2; // Going to frame number 2
    player2.position.y = -0.3;
    player2.position.x = 1;
    player2.size = 0.3;
    player2.invertU = -1; //Change orientation
    player2.isPickable = true;


    // Picking
    spriteManagerTrees.isPickable = true;
    spriteManagerPlayer.isPickable = true;

    scene.onPointerDown = function (evt) {
        var pickResult = scene.pickSprite(this.pointerX, this.pointerY);
        if (pickResult.hit) {
            pickResult.pickedSprite.angle += 0.5;
        }
    };


    return scene;
}
View Code

效果

 

效果描述:

1.隨機產生樹。2.運動的小人。3.樹的點擊事件。4.鏡頭的處理

 

筆記

樹的處理

//建立一個精靈?個人理解為一個對象的引入。英文描述提示利用GPU運算,並且提供參數,機翻效果如下:名稱,圖片地址,能力,調用大小,場景。
//此處作為管理處
var spriteManagerTrees = new BABYLON.SpriteManager("treesManager", "textures/palm.png", 2000, 800, scene); //隨機產生樹2000個 for (var i = 0; i < 2000; i++) { //創建樹 var tree = new BABYLON.Sprite("tree", spriteManagerTrees); //樹坐標隨機 tree.position.x = Math.random() * 100 - 50; tree.position.z = Math.random() * 100 - 50; //提供選擇事件 tree.isPickable = true; //隨機選擇,處理旋轉樹的角度,並且固定樹在一個平面 if (Math.round(Math.random() * 5) === 0) { tree.angle = Math.PI * 90 / 180; tree.position.y = -0.3; } }

人物的處理(動的角色)

    var player = new BABYLON.Sprite("player", spriteManagerPlayer);
    player.playAnimation(0, 40, true, 100);//動畫處理
    player.position.y = -0.3;//定位
    player.size = 1.3;//模型大小()
    player.isPickable = true;//選擇事件

人物的處理(靜態的角色)

    // Second standing player
    var player2 = new BABYLON.Sprite("player2", spriteManagerPlayer);
    player2.stopAnimation(); // 靜止的動畫
    player2.cellIndex = 2; // 幀數
    player2.position.y = -0.3;
    player2.position.x = 1;
    player2.size = 0.3;
    player2.invertU = -1; //改變方向?
    player2.isPickable = true;

 

 

管理處添加點擊事件與點擊反應(此處點擊事件為旋轉方向)

    
    spriteManagerTrees.isPickable = true;
    spriteManagerPlayer.isPickable = true;

    scene.onPointerDown = function (evt) {
        var pickResult = scene.pickSprite(this.pointerX, this.pointerY);
        if (pickResult.hit) {
            pickResult.pickedSprite.angle += 0.5;
        }
    };

 

本章就到這里,下一張我會集中前1-9章學習到的內容。建立一個小場景

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM