Three.js的基础使用

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构建一个场景,大致步骤如下:

材质Material

Mesh

几何体Geometry

场景Scene

渲染器Renderer

相机Camera

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

<!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 光照

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

材质Material

Mesh

几何体Geometry

场景Scene

光照Light

渲染器Renderer

相机Camera

<!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:

材质Material

Mesh1

几何体Geometry

场景Scene

材质Material2

Mesh2

光照Light

渲染器Renderer

相机Camera

<!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实现场景拖动:

材质Material

Mesh

几何体Geometry

场景Scene

光照Light

渲染器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模型:

材质Material

Mesh

几何体Geometry

场景Scene

加载器Loader

模型Model

光照Light

渲染器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)

posted @   当时明月在曾照彩云归  阅读(355)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示