【Three.js】二、three.js中的场景——Scene

【Three.js】二、three.js中的场景——Scene

three.js中的场景用来保存所有对象、光源和所渲染的其他对象。使用new THREE.Scene()可以创建场景。

一、Sence常用属性及方法:

方法及属性说明
scene.children获取场景中所有的子对象列表
scene.fog场景雾化效果
scene.overrideMaterial如果不为空,它将迫使在场景中的一切对象都使用该材料进行渲染,默认为null。
scene.add(object)向场景中添加对象
scene.remove(object)从场景中移除对象
scene.traverse(callback)在这个对象和所有的子对象上执行回调。
getObjectByName(name, recursive)在创建对象时可以指定唯一name,使用该方法可找到该对象。如果recursive为false时,在调用者子元素上查找,若为true,在调用者的所有后代对象上查找。

二、示例

  下面我们制作这样一个实例:实现向一个场景中动态添加删除对象:
1.首先创建三大基本对象(Scene、Camera、Renderer)

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,100);
let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
// 添加白色雾化
/*scene.fog = new THREE.Fog(0xffffff, 10, 100);
scene.overrideMaterial = new THREE.MeshLambertMaterial({
	color: 0x3489fe
});*/
scene.add(camera);

2.创建平面及光源

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

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

    let ambientLight = new THREE.AmbientLight(0x3c3c3c);
    scene.add(ambientLight);

3.开始渲染

	// 调整摄像机位置
	camera.position.x = -30;
    camera.position.y = 50;
    camera.position.z = 40;
    camera.lookAt(scene.position);
    document.body.appendChild(renderer.domElement);
    renderer.render(scene, camera);

此时我们可以在页面中看到一个有渐变效果的平面,下面我们开始动态添加立方体
4.添加立方体:借助dat.GUI提供可视化的控制操作

	let controls = new function() {
        this.rotationSpeed = 0.02;
        this.numberOfObjects = scene.children.length;
        this.addCube = function () { // 添加立方体
            let cubeSize = Math.ceil((Math.random() * 3));
            let cubeGeometry = new THREE.BoxGeometry(cubeSize,cubeSize,cubeSize);
            let cubeMaterial = new THREE.MeshLambertMaterial({
                color: 0xffffff * Math.random()
            });
            let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
            cube.castShadow = true;
            cube.position.x = -30 + Math.round(Math.random() * planeGeometry.parameters.width);
            cube.position.y = Math.ceil(Math.random() * 3) + 2;
            cube.position.z = -20 + Math.round(Math.random() * planeGeometry.parameters.height);
            cube.name = `cube-${this.numberOfObjects}`;
            scene.add(cube);
            this.numberOfObjects = scene.children.length;
            // ...render
        };
        this.removeCube = function () { // 删除立方体
            let allChilden = scene.children;
            let lastObject = allChilden[allChilden.length - 1];
            if (lastObject instanceof THREE.Mesh) {
                scene.remove(lastObject);
                this.numberOfObjects = scene.children.length;
                // ...render
            }
        };
    };
    let gui = new dat.GUI();
    gui.add(controls, 'rotationSpeed', 0, 0.5);
    gui.add(controls, 'addCube');
    gui.add(controls, 'removeCube');
    gui.add(controls, 'numberOfObjects').listen();

此时可以动态地添加及删除立方体,下面我们们给每个立方体添加一个自转动画:

	function render() {
        stats.update(); // 更新帧数
        scene.traverse((obj) => {
            if (obj instanceof THREE.Mesh && obj != plane) {
                obj.rotation.x += controls.rotationSpeed;
                obj.rotation.y += controls.rotationSpeed;
                obj.rotation.z += controls.rotationSpeed;
            }
        });
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }

效果:
在这里插入图片描述
如果想要通过拖动页面调整视角的话,需要借助TrackballControls。安装TrackballControls,通过cnpm或npm安装的话搜索three-trackballcontrols:

cnpm i three-trackballcontrols -S

添加如下代码:

function initTrackballControls(camera, renderer){
    let trackballControls = new TrackballControls(camera,renderer.domElement);
    // 旋转速度
    trackballControls.rotateSpeed = 1.0;
    // 变焦速度
    trackballControls.zoomSpeed = 1.2;
    // 平移速度
    trackballControls.panSpeed = 0.8;
    // 是否不变焦
    trackballControls.noZoom = false;
    // 是否不平移
    trackballControls.noPan = false;
    // 是否开启移动惯性
    trackballControls.staticMoving = true;
    // 动态阻尼系数 就是灵敏度
    trackballControls.dynamicDampingFactor = 0.3;
    // ???
    trackballControls.keys = [65, 83, 68];
    return trackballControls;
}

let trackballControls = initTrackballControls(camera, renderer);
function render(){
	trackballControls.update(); // 更新控制器
	...
}

添加控制后效果:
在这里插入图片描述

完整示例:https://github.com/MAXLZ1/threejs_demo

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MAXLZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值