threejs 加载两个场景_three.js多场景切换和资源释放代码示例(含一个简单的资源管理器原型实现)...

HTML

导入代码模板:

import * as THREE from '//techbrood.com/threejs/build/three.module.js';

import {GLTFLoader} from '//techbrood.com/threejs/examples/jsm/loaders/GLTFLoader.js';

class ResourceTracker {

constructor() {

this.resources = new Set();

}

track(resource) {

if (!resource) {

return resource;

}

// handle children and when material is an array of materials or

// uniform is array of textures

if (Array.isArray(resource)) {

resource.forEach(resource => this.track(resource));

return resource;

}

if (resource.dispose || resource instanceof THREE.Object3D) {

this.resources.add(resource);

}

if (resource instanceof THREE.Object3D) {

this.track(resource.geometry);

this.track(resource.material);

this.track(resource.children);

} else if (resource instanceof THREE.Material) {

// We have to check if there are any textures on the material

for (const value of Object.values(resource)) {

if (value instanceof THREE.Texture) {

this.track(value);

}

}

// We also have to check if any uniforms reference textures or arrays of textures

if (resource.uniforms) {

for (const value of Object.values(resource.uniforms)) {

if (value) {

const uniformValue = value.value;

if (uniformValue instanceof THREE.Texture ||

Array.isArray(uniformValue)) {

this.track(uniformValue);

}

}

}

}

}

return resource;

}

untrack(resource) {

this.resources.delete(resource);

}

dispose() {

for (const resource of this.resources) {

if (resource instanceof THREE.Object3D) {

if (resource.parent) {

resource.parent.remove(resource);

}

}

if (resource.dispose) {

resource.dispose();

}

}

this.resources.clear();

}

}

function main() {

const canvas = document.querySelector('#c');

const renderer = new THREE.WebGLRenderer({canvas});

const fov = 75;

const aspect = 2; // the canvas default

const near = 0.1;

const far = 5;

const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

camera.position.z = 2;

const scene = new THREE.Scene();

scene.background = new THREE.Color('lightblue');

function addLight(...pos) {

const color = 0xFFFFFF;

const intensity = 1;

const light = new THREE.DirectionalLight(color, intensity);

light.position.set(...pos);

scene.add(light);

}

addLight(-1, 2, 4);

addLight( 2, -2, 3);

function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {

const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;

const halfFovY = THREE.Math.degToRad(camera.fov * .5);

const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);

// compute a unit vector that points in the direction the camera is now

// in the xz plane from the center of the box

const direction = (new THREE.Vector3())

.subVectors(camera.position, boxCenter)

.multiply(new THREE.Vector3(1, 0, 1))

.normalize();

// move the camera to a position distance units way from the center

// in whatever direction the camera was from the center already

camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));

// pick some near and far values for the frustum that

// will contain the box.

camera.near = boxSize / 100;

camera.far = boxSize * 100;

camera.updateProjectionMatrix();

// point the camera to look at the center of the box

camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);

}

const gltfLoader = new GLTFLoader();

function loadGLTF(url) {

return new Promise((resolve, reject) => {

gltfLoader.load(url, resolve, undefined, reject);

});

}

function waitSeconds(seconds = 0) {

return new Promise(resolve => setTimeout(resolve, seconds * 1000));

}

const fileURLs = [

'/uploads/1911/3dlut/queen.gltf',

'/uploads/1911/scene.gltf',

];

async function loadFiles() {

for (;;) {

for (const url of fileURLs) {

const resMgr = new ResourceTracker();

const track = resMgr.track.bind(resMgr);

const gltf = await loadGLTF(url);

const root = track(gltf.scene);

scene.add(root);

// compute the box that contains all the stuff

// from root and below

const box = new THREE.Box3().setFromObject(root);

const boxSize = box.getSize(new THREE.Vector3()).length();

const boxCenter = box.getCenter(new THREE.Vector3());

// set the camera to frame the box

frameArea(boxSize * 1.1, boxSize, boxCenter, camera);

await waitSeconds(2);

renderer.render(scene, camera);

resMgr.dispose();

await waitSeconds(1);

}

}

}

loadFiles();

function resizeRendererToDisplaySize(renderer) {

const canvas = renderer.domElement;

const width = canvas.clientWidth;

const height = canvas.clientHeight;

const needResize = canvas.width !== width || canvas.height !== height;

if (needResize) {

renderer.setSize(width, height, false);

}

return needResize;

}

function render() {

if (resizeRendererToDisplaySize(renderer)) {

const canvas = renderer.domElement;

camera.aspect = canvas.clientWidth / canvas.clientHeight;

camera.updateProjectionMatrix();

}

renderer.render(scene, camera);

requestAnimationFrame(render);

}

requestAnimationFrame(render);

}

main();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的threejs实现切换场景代码: ```javascript // 初始化场景1 var scene1 = new THREE.Scene(); var camera1 = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer1 = new THREE.WebGLRenderer(); renderer1.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer1.domElement ); var geometry1 = new THREE.BoxGeometry( 1, 1, 1 ); var material1 = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube1 = new THREE.Mesh( geometry1, material1 ); scene1.add( cube1 ); camera1.position.z = 5; // 初始化场景2 var scene2 = new THREE.Scene(); var camera2 = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer2 = new THREE.WebGLRenderer(); renderer2.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer2.domElement ); var geometry2 = new THREE.BoxGeometry( 1, 1, 1 ); var material2 = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var cube2 = new THREE.Mesh( geometry2, material2 ); scene2.add( cube2 ); camera2.position.z = 5; // 切换场景函数 function switchScene(scene, camera, renderer) { renderer.setClearColor('#000000'); renderer.render(scene, camera); } // 初始场景1 switchScene(scene1, camera1, renderer1); // 监听键盘事件 document.addEventListener('keydown', function(event) { // 按下1键,切换场景1 if(event.keyCode == 49) { switchScene(scene1, camera1, renderer1); } // 按下2键,切换场景2 else if(event.keyCode == 50) { switchScene(scene2, camera2, renderer2); } }); ``` 在这个代码中,我们首先初始化了两个场景和渲染器。然后,我们定义了一个 `switchScene` 函数,该函数接受场景、相机和渲染器作为参数,并在渲染器上渲染场景。最后,我们监听键盘事件,并根据按下的键码切换到不同的场景

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值