1. 程式人生 > >Three.js建立隨機立體幾何體示例

Three.js建立隨機立體幾何體示例

效果

demo

<template>
    <div>
        <div ref="StatsBox"></div>
        <div ref="ThreeBox"></div>
    </div>
</template>

<script>
/* eslint-disable */
import * as THREE from 'three';
import Stats from '../assets/js/stats.js';
import * as dat from 'dat.gui';


var scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 0.015, 100 ); // 建立霧,離得越遠越模糊
// scene.overrideMaterial = new THREE.MeshLambertMaterial({color : 0xffffff }); // 設定統一材質

var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xEFD9BE, 1.0); 
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;


var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true; 
scene.add(spotLight);

var planeGeometry = new THREE.PlaneGeometry(90,40,1,1); 
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}); 
var plane = new THREE.Mesh(planeGeometry,planeMaterial); 
plane.rotation.x = -0.5*Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
plane.receiveShadow = true;
scene.add(plane);

camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position); 


let step = 0;
const gui = new dat.GUI(); // 建立gui工具,控制變數
var controls= new function() {

    this.rotationSpeed = 0.02;
    this.numberOfObjects = scene.children.length;

    this.addCube = function( ) {
        // 隨機大小
        var cubeSize = Math.ceil((Math.random() * 8));
        var cubeGeometry = new THREE.BoxBufferGeometry(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; // 可以使用 Scene.getChildByName ( name ) 獲取

        // 隨機位置
        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.outputObjects = function(){
        console.log(scene.children); 
    }
}

gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls,'numberOfObjects').listen(); 
gui.add(controls,'addCube'); 
gui.add(controls,'removeCube'); 
gui.add(controls,'outputObjects'); 

let stats = null;

export default {
    mounted() {
        // 監視FPS
        stats = new Stats ();
        stats.setMode(0);
        stats.showPanel( 1 );
        this.$refs.StatsBox.appendChild(stats.dom);

        this.$refs.ThreeBox.appendChild( renderer.domElement );
        renderer.render(scene, camera );
        this.renderScene();
    },
    methods: {
        renderScene(){
            stats.begin();

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

            renderer.render(scene, camera);
            stats.end();

            requestAnimationFrame(this.renderScene);
            
        }
    }
}
</script>