入門threejs第三天讓場景動起來

一、想讓場景動起來,第一個解決的問題就是如何在特定的時間間隔重新渲染場景。

之前是使用setInterval方法。比如每個100ms執行一次。但是這會導致較高的CPU使用率和性能不良。

現代瀏覽器提供了在特定時間間隔重新渲染場景的解決方案:即requestAnimationFrame方法。

 

二、在實現動畫效果之前,先來介紹一個輔助庫,用於檢測動畫運行時幀數。在動畫運行時,該庫可以在一個圖片中顯示畫面每秒傳輸幀數。

①先在head處添加這個js文件

<script type="text/javascript" src="../libs/stats.js"></script>

②添加div用於顯示統計圖形。

<div id="Stats-output">
</div>

③初始化統計對象,將該對象添加到div元素中(整個方法一般不會變)

function initStats() {
       var stats = new Stats();
       stats.setMode(0); // 0: fps, 1: ms

       // Align top-left
       stats.domElement.style.position = 'absolute';
       stats.domElement.style.left = '0px';
       stats.domElement.style.top = '0px';
       document.getElementById("Stats-output").appendChild(stats.domElement);
       return stats;
}

④在init方法裏面調用initStats()

function init(){
  var stats = initStats()
}

完成以上步驟就可以看到屏幕左上角這個東西。

 

⑤動畫要添加如下代碼:

        function renderScene() {
            stats.update();
            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }
        document.getElementById('WebGL-output').appendChild(renderer.domElement);
        renderer.render(scene,camera);
        renderScene();

想讓球旋轉起來,則:

 

⑥在創建三維場景和動畫時,我們需要嘗試很多次才能確定最合適的速度和顏色,如果有一個GUI(可視化圖形界面)允許我們在運行期間修改這些屬性。

⑦添加這個js

    <script type="text/javascript" src="../libs/dat.gui.js"></script>

⑧定義一個對象,該對象將保存希望通過該dat.GUI改變的屬性。

var controls = new function(){
  this.rotationSpeed = 0.02;
}
var gui = new dat.GUI(); // 
gui.add(controls,'rotationspeed',0,0.5);

 

 

在render方法裏面,將0.02用controls.rotationSpeec替代

function renderScene() {
            stats.update();
            console.log(controls)
            // 讓球繞x軸旋轉起來
            sphere1.rotation.x += controls.rotationSpeed

            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }

 

 

<!--
 * @Author: your name
 * @Date: 2018-09-17 05:22:00
 * @LastEditTime: 2021-04-03 16:33:56
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /learning-threejs-master/chapter-01/01-basic-skeleton.html
-->
<!DOCTYPE html>

<html>

<head>
    <title></title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/stats.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to
             use the complete page */
            /*將邊距設置爲0並溢出到隱藏的使用整個頁面*/
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
  <div id="Stats-output">
  </div>
<div id="WebGL-output">
</div>

<script type="text/javascript">
           
    function init() {
        var stats = initStats();
        
         
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight);
        var renderer = new THREE.WebGLRenderer();
        
        var spotLight = new THREE.SpotLight(0xff4400);
        spotLight.position.set(10,100,60);
        spotLight.castShadow = true;
        scene.add(spotLight)
        // 設置背景色和背景大小 
        renderer.setClearColorHex();
        renderer.setClearColor(new THREE.Color("#ccc"));
        renderer.setSize(window.innerWidth,window.innerHeight);
        renderer.shadowMapEnabled = true; // 開啓陰影
        // create the ground plane 創建地平面
        var planeGeometry = new THREE.PlaneGeometry(60, 20);
        // 創建面板顏色
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.receiveShadow = true;
        // rotate and position the plane
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = 0;
        plane.position.z = 0;
        // add the plane to the scene
        scene.add(plane);

        // 定義一個球體
        var sphereGeometry = new THREE.SphereGeometry(2,20,20);
        var sphereMaterial = new THREE.MeshLambertMaterial({color:0xffffff,wireframe:true})
        var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
        scene.add(sphere);
        sphere.position.x = 0;
        sphere.position.y = 2;
        sphere.position.z = 0;
        sphere.castShadow = true;

        
        

         // 定義一個球體
        var sphereGeometry1 = new THREE.SphereGeometry(2,20,20);
        var sphereMaterial1 = new THREE.MeshBasicMaterial({color:0xff0000,wireframe:false})
        var sphere1 = new THREE.Mesh(sphereGeometry,sphereMaterial);
        scene.add(sphere1);
        sphere1.position.x = 0;
        sphere1.position.y = 10;
        sphere1.position.z = 0;
        sphere1.castShadow = true;

        camera.position.x = 20;
        camera.position.y = 20;
        camera.position.z = 20;
        camera.lookAt(scene.position);
        document.getElementById('WebGL-output').appendChild(renderer.domElement);
        renderer.render(scene,camera);
        
        var controls = new function(){
          this.rotationSpeed = 0.02;
        }
        var gui = new dat.GUI(); // 
        gui.add(controls,'rotationSpeed',0,0.5);
        

        renderScene();
        function renderScene() {
            stats.update();
            console.log(controls)
            // 讓球繞x軸旋轉起來
            sphere1.rotation.x += controls.rotationSpeed

            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }


        function initStats() {

          var stats = new Stats();

          stats.setMode(0); // 0: fps, 1: ms

          // Align top-left
          stats.domElement.style.position = 'absolute';
          stats.domElement.style.left = '0px';
          stats.domElement.style.top = '0px';

          document.getElementById("Stats-output").appendChild(stats.domElement);

          return stats;
          }
        
    }
    window.onload = init

</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章