【three.js學習筆記】場景

THREE.Scene

  1. THREE.Scene 對象是全部不一樣對象的容器,也就是說該對象保存全部物體、光源、攝像機以及渲染所需的其餘對象。
  2. THREE.Scene 對象又是被稱爲場景圖,它不單單是一個對象數組,還包含了整個場景圖樹形結構中的全部節點:
    每一個添加到 Three.js 場景的對象,甚至包括 THREE.Scene 自己都是繼承自一個名爲 THREE.Object3D 的對象。
    每一個 THREE.Object3D 對象也能夠有本身的子對象,咱們可使用它的子對象來建立一個 Three.js 能解釋和渲染的對象樹。
組件 描述
相機 決定哪些東西在屏幕上渲染
光源 對材質如何顯示,以及生成陰影時材質如何使用產生影響
物體 相機裏主要的渲染對象,如方塊、球體

THREE.Scene()就像是全部這些對象的容器。下面是對場景對象最重要的函數javascript

函數/屬性 描述
add(Object) 添加對象到場景中
children 返回場景中全部對象的列表,包括相機和光源
getChildByName(name) 利用name屬性,返回場景中特定的對象
remove(Object) 把對象從場景中刪除
traverse(function) 經過traverse這個函數,咱們能夠經過回調函數訪問場景對象及其子對象
fog 經過這個屬性,能夠設置場景中的霧化效果,它能夠渲染出一層霧氣
overrideMaterial 經過這個屬性,能夠強制場景中的全部物體都使用相同的材質
background 經過這個屬性,能夠設置場景的背景,它老是第一個被渲染,能夠是Color、紋理Texture覆蓋、或者CubeTexture
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>場景</title>
    <script type="text/javascript" src="../code/js91/three.js"></script>
    <script type="text/javascript" src="../code/lib/Stats.js"></script>
    <script type="text/javascript" src="../code/lib/dat.gui.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
 
<!-- 用於顯示統計圖形 -->
<div id="Stats-output">
</div>
 
<!-- 做爲Three.js渲染器輸出元素 -->
<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, 0.1, 1000);
        //設置攝像機的位置,並讓其指向場景的中心(0,0,0)
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);
 
        //建立一個WebGL渲染器並設置其大小
        var renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMapEnabled = true;
 
        //建立一個平面
        var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.receiveShadow = true;
        //設置平面的旋轉角度和位置
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = 0;
        plane.position.z = 0;
        //將平面添加場景中
        scene.add(plane);
 
        //添加環境光
        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
 
        //添加聚光燈光源
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);
 
        //將渲染的結果輸出到指定頁面元素中
        document.getElementById("WebGL-output").appendChild(renderer.domElement);
 
        //dat.GUI對象使用的配置(存放有全部須要改變的屬性的對象)
        var controls = new function () {
            //旋轉速度
            this.rotationSpeed = 0.02;
 
            //場景對象個數
            this.numberOfObjects = scene.children.length;
 
            //增長一個立方體
            this.addCube = function () {
                var cubeSize = Math.ceil((Math.random() * 3));
                var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
                var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
                var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
                cube.castShadow = true;
                //設置立方體的名字
                cube.name = "cube-" + scene.children.length;
 
                //立方體位置隨機
                cube.position.x = -30 + Math.round(
                  (Math.random() * planeGeometry.parameters.width));
                cube.position.y = Math.round((Math.random() * 5));
                cube.position.z = -20 + Math.round(
                  (Math.random() * planeGeometry.parameters.height));
 
                //將立方體添加到場景中
                scene.add(cube);
                this.numberOfObjects = scene.children.length;
            };
 
            //移除最後一個立方體
            this.removeCube = function () {
                var allChildren = scene.children;
                var lastObject = allChildren[allChildren.length - 1];
                if (lastObject instanceof THREE.Mesh) {
                    scene.remove(lastObject);
                    this.numberOfObjects = scene.children.length;
                }
            };
 
            //全部物體強制使用某個材質
            this.overrideMaterial = function() {
              scene.overrideMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
            }
 
            //霧化
            this.foggy = function() {
              scene.fog = new THREE.Fog(0xffffff, 0.015, 100);
            }
 
            //輸出全部對象
            this.outputObjects = function () {
                console.log(scene.children);
            }
        };
 
        //建立dat.GUI,傳遞並設置屬性
        var gui = new dat.GUI();
        gui.add(controls, 'numberOfObjects').name("當前對象個數").listen();
        gui.add(controls, 'rotationSpeed', 0, 0.5);
        gui.add(controls, 'addCube');
        gui.add(controls, 'removeCube');
        gui.add(controls, 'overrideMaterial').name("使用相同材質");
        gui.add(controls, 'foggy').name("霧化");
        gui.add(controls, 'outputObjects').name("輸出全部對象");
 
        //渲染場景
        render();
 
        //渲染場景
        function render() {
            stats.update();
 
            //旋轉全部的立方體
            scene.traverse(function (e) {
                if (e instanceof THREE.Mesh && e != plane) {
 
                    e.rotation.x += controls.rotationSpeed;
                    e.rotation.y += controls.rotationSpeed;
                    e.rotation.z += controls.rotationSpeed;
                }
            });
 
            //經過requestAnimationFrame方法在特定時間間隔從新渲染場景
            requestAnimationFrame(render);
            //渲染場景
            renderer.render(scene, camera);
        }
 
        //初始化統計對象
        function initStats() {
            var stats = new Stats();
            //設置統計模式
            stats.setMode(0); // 0: fps, 1: ms
            //統計信息顯示在左上角
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';
            //將統計對象添加到對應的<div>元素中
            document.getElementById("Stats-output").appendChild(stats.domElement);
            return stats;
        }
    }
 
    //確保init方法在網頁加載完畢後被調用
    window.onload = init
</script>
</body>
</html>
相關文章
相關標籤/搜索