Three.js的基础使用

three,js,基础,使用 · 浏览次数 : 67

小编点评

文章中关于如何创建场景和加载三D模型的具体步骤有变动结果,以下是一些关键细节: 1. 创建场景 – three.js docs (threejs.org)[2] mrdoob/three.js: JavaScript 3D Library. (github.com)[3] three.js manual (threejs.org)。归纳总结以上内容,生成内容时需要带简单的排版 2. mrdoob/three.js: JavaScript 3D Library. (github.com)[3] 中提供了关于如何创建场景的代码,但该代码需要带一些排版才能运行。 3. three.js manual (threejs.org)。归纳总结以上内容,生成内容时需要带简单的排版 4. 创建场景 – three.js docs (threejs.org)[2] mrdoob/three.js: JavaScript 3D Library. (github.com)[3] 中提供了关于如何加载三D模型的代码,但该代码需要带一些排版才能运行。

正文

1. 引言

Three.js是著名的JavaScript 3D图形库,用于浏览器中开发 3D 交互场景的 JS 引擎,可以快速的搭建三维场景

Three.js官网为:创建一个场景 – three.js docs (threejs.org)

GitHub站点为:mrdoob/three.js: JavaScript 3D Library. (github.com)

本文描述Three.js的基础使用与搭建一个场景

2. 基础使用

2.1 基础场景

使用Three.js构建一个场景,大致步骤如下:

graph LR 材质Material --> Mesh 几何体Geometry --> Mesh --> 场景Scene --> 渲染器Renderer 相机Camera --> 渲染器Renderer

按照上述流程,简要设置几个参数,就可以构建出一个简单的场景:

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
</head>

<body>
	<canvas id="canvas"></canvas>
	<script type="module">
		import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js';

		const scene = new THREE.Scene();
        
		const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
		camera.position.z = 5;
        
        const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
        
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshBasicMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>

</html>

结果如下:

image-20230509113757228

2.2 光照

添加光照并修改一下材质(使其可以反光):

graph LR 材质Material --> Mesh 几何体Geometry --> Mesh --> 场景Scene 光照Light --> 场景Scene --> 渲染器Renderer 相机Camera --> 渲染器Renderer
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
</head>

<body>
	<canvas id="canvas"></canvas>
	<script type="module">
		import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js';

		const scene = new THREE.Scene();

		const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
		camera.position.z = 5;

		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
		
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);

		const light = new THREE.DirectionalLight(0xffffff, 1);
		light.position.set(0, 0, 5);
		scene.add(light);
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>

</html>

结果如下:

image-20230509135822844

2.3 多个Mesh

添加两个Mesh到场景中,并共用一个Geometry:

graph LR 材质Material --> Mesh1 几何体Geometry --> Mesh1 --> 场景Scene 材质Material2 --> Mesh2 几何体Geometry --> Mesh2 --> 场景Scene 光照Light --> 场景Scene --> 渲染器Renderer 相机Camera --> 渲染器Renderer
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
</head>

<body>
	<canvas id="canvas"></canvas>
	<script type="module">
		import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js';

		const scene = new THREE.Scene();

		const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
		camera.position.z = 5;

		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
		
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);

		const material2 = new THREE.MeshPhongMaterial({
			color: 0x0000ff
		});
		const cube2 = new THREE.Mesh(geometry, material2);
		cube2.position.x = 2;
		scene.add(cube2);

		const light = new THREE.DirectionalLight(0xffffff, 1);
		light.position.set(0, 0, 5);
		scene.add(light);
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>

</html>

结果如下:

image-20230509140647651

2.4 控制器

加入轨道控制器OrbitControls实现场景拖动:

graph LR 材质Material --> Mesh 几何体Geometry --> Mesh --> 场景Scene 光照Light --> 场景Scene --> 渲染器Renderer 相机Camera --> 渲染器Renderer 相机Camera --> 控制器Controls
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
	
</head>

<body>
	<canvas id="canvas"></canvas>

	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three/build/three.module.js",
				"three/addons/": "https://unpkg.com/three/examples/jsm/"
			}
		}
	</script>
	
	<script type="module">
		import * as THREE from 'three';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

		const scene = new THREE.Scene();

		const canvas = document.querySelector('#canvas');
		const camera = new THREE.PerspectiveCamera(75,  canvas.clientWidth / canvas.clientHeight , 0.1, 1000);
		camera.position.z = 5;

		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
		
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);

		const light = new THREE.DirectionalLight(0xffffff, 1);
		light.position.set(0, 0, 5);
		scene.add(light);

		const controls = new OrbitControls( camera, renderer.domElement );
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>

</html>
  • 注意这里的CDN地址、加载方式有变动

结果如下:

image-20230509144649341

2.5 模型加载

加入GLTFLoader加载GLTF模型:

graph LR 材质Material --> Mesh 几何体Geometry --> Mesh --> 场景Scene 加载器Loader -->模型Model --> 场景Scene 光照Light --> 场景Scene --> 渲染器Renderer 相机Camera --> 渲染器Renderer 相机Camera --> 控制器Controls

模型下载自:three.js/Xbot.glb at dev · mrdoob/three.js · GitHub

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
	
</head>

<body>
	<canvas id="canvas"></canvas>

	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three/build/three.module.js",
				"three/addons/": "https://unpkg.com/three/examples/jsm/"
			}
		}
	</script>
	
	<script type="module">
		import * as THREE from 'three';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
		import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

		const scene = new THREE.Scene();

		const canvas = document.querySelector('#canvas');
		const camera = new THREE.PerspectiveCamera(75,  canvas.clientWidth / canvas.clientHeight , 0.1, 1000);
		camera.position.z = 5;

		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
		
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);

		const gltfLoader = new GLTFLoader();
		gltfLoader.load('./models/Xbot.glb', (gltf) => {
			scene.add(gltf.scene)
			gltf.scene.position.z = 2
		})

		const light = new THREE.DirectionalLight(0xffffff, 1);
		light.position.set(0, 0, 5);
		scene.add(light);

		const controls = new OrbitControls( camera, renderer.domElement );
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>

</html>

结果如下:

image-20230509152226585

3. 参考资料

[1] 创建一个场景 – three.js docs (threejs.org)

[2] mrdoob/three.js: JavaScript 3D Library. (github.com)

[3] three.js manual (threejs.org)

与Three.js的基础使用相似的内容:

Three.js的基础使用

本文描述Three.js的基础使用与搭建一个场景

three.js高性能渲染室外场景

大家好,本文在相关文章的基础上,使用three.js渲染了高性能的室外场景,在移动端也有较好的性能,并给出了代码,分析了关键点,感谢大家~ 关键词:three.js、Web3D、WebGL、室外场景、Instanced Draw、大场景、LOD、Frustum Cull、优化、开源 代码:Githu

第135篇:Three.js基础入门

好家伙,这东西太帅了,我要学会 先放张帅图(都是用three.js做出来的,这我学习动力直接拉满) 还有另外一个 Junni is... 帧数太高,录不了 开始学习 官方文档 1.Three.js是什么? Three.js是一款运行在浏览器中的 3D 引擎(基于WebGL的API的封装),你可以用它

基于 Three.js 的 3D 模型加载优化

作为一个3D的项目,从用户打开页面到最终模型的渲染加载的时间也会比普通的H5项目要更长一些,从而造成大量的用户流失。为了提升首屏加载的转化率,需要尽可能的降低loading的时间。这里就分享一些我们在模型加载优化方面的心得。

如何基于three.js(webgl)引擎架构,研发一套通过配置就能自动生成的3D机房系统

自动化3D机房、微模块、3D机房、3D数据中心、科技感数据中心、三维机房、3d建筑,3d消防,消防演习模拟,3d库房,3d档案室,3d密集架,webGL,threejs,3d机房,bim管理系统

IoTBrowser V2.0:引领物联网时代的全新浏览器

强大的兼容性,无限的可能 IoTBrowser V2.0,基于Chromium内核,完美支持H5/css/js开发界面,让您的物联网应用拥有与主流浏览器同等的流畅体验。同时,它还支持CSS 3动画、Cesium.js、Three.js等先进技术,让您的界面更加绚丽、动态。无论是ES6的Prom

Three.js中实现对InstanceMesh的碰撞检测

1. 概述 之前的文章提到,在Three.js中使用InstanceMesh来实现性能优化,可以实现单个Mesh的拾取功能 那,能不能实现碰撞检测呢?肯定是可以的,不过Three.js中并没有直接的API可以实现对InstanceMesh的碰撞检测,需要手动实现 回顾本文的描述的Three.js的场

Three.js实现可透视的水面效果

本文描述使用Three.js实现可透视的水面效果

Three.js使用InstancedMesh实现性能优化

本文记述在three.js中使用InstancedMesh来实现绘制大量几何体的性能优化

three.js实现相机碰撞,相机不穿墙壁、物体

大家好,本文实现了相机碰撞检测,使相机不穿墙壁、物体,并给出了思路和代码,感谢大家~ 关键词:数字孪生、three.js、Web3D、WebGL、相机碰撞、游戏相机 我正在承接Web3D数字孪生项目,具体介绍可看承接各种Web3D业务 目录实现原理参考资料 实现前: 移动第三人称相机时,相机可能会穿