3D教程 Three.js

2_什么是 webgl

作者做的一些 threejs 案例


Alt text
Alt text

3_basic_scene

从官网下载 threejs, 然后复制里面的 threejs min 到项目文件夹下

Alt text
Alt text
Alt text
Alt text
Alt text

scene

Alt text

const scene = new THREE.Scene();

objects

Alt text
Alt text
Alt text
Alt text

// 创建objects(一个红立方体)
const geometry = new THREE.BoxGeometry(1, 1, 1);

Alt text

Material (材质细节)

Alt text

color: 颜色

Alt text

// 材质细节
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });

Mesh

Alt text

// 网格
const mesh = new THREE.Mesh(geometry, material);
// 添加网格到画布
scene.add(mesh);

Camera

Alt text

field 可见范围(角度?)

Alt text

aspect ratio 纵横比

Alt text

// Sizes 视窗大小
const sizes = {
  width: 800,
  height: 600,
};
// 相机(perspective: 透视)
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
scene.add(camera);

renderer 渲染器,渲染图像

Alt text
Alt text
Alt text

// 要被渲染的画布
const canvas = document.querySelector(".webgl");
// 渲染器
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});
// 设置渲染器大小
renderer.setSize(sizes.width, sizes.height);
// 渲染
renderer.render(scene, camera);

默认情况下,相机和对象都在 scene 中心,什么都看不到,要调整相机位置

// 向屏幕外移动
camera.position.z = 3;

over

Alt text

// console.log(THREE);
// 场景,一个画布,容器...
const scene = new THREE.Scene();
// 创建objects(一个红立方体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 材质细节
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// 网格
const mesh = new THREE.Mesh(geometry, material);
// 添加网格到画布
scene.add(mesh);
// Sizes 视窗大小
const sizes = {
  width: 800,
  height: 600,
};
// 相机(perspective: 透视)
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
// 向屏幕外移动
camera.position.z = 3;
// 向屏幕右侧移动
// camera.position.x = 2
// 向屏幕上侧移动
// camera.position.y = 2
scene.add(camera);
// 要被渲染的画布
const canvas = document.querySelector(".webgl");
// 渲染器
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});
// 设置渲染器大小
renderer.setSize(sizes.width, sizes.height);
// 渲染
renderer.render(scene, camera);

Alt text

<!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>03 - Basic Scene</title>
  </head>

  <body>
    <!-- 画布,用于渲染threejs图像 -->
    <canvas class="webgl"></canvas>
    <!-- 导入threejs -->
    <script src="./three.min.js"></script>
    <script src="./script.js"></script>
  </body>
</html>

Alt text

4_webpack

下载 threejs 官网 webpack 章节示例

Alt text
Alt text

npm install
yarn dev

Alt text
Alt text
Alt text
Alt text

5_tranforms_objects

变换对象有 4 个属性

Alt text

position 移动

Alt text

正方体向上移动了,我们看到它的底部

mesh.position.y = 1;

Alt text

# 放在渲染之前才生效
mesh.position.x = 0.7
mesh.position.y = -0.6
mesh.position.z = 1

Alt text

vector3

Alt text

// position向量的长度
console.log(mesh.position.length());

Alt text

// 和某个位置的距离
console.log(
  "和某个位置的距离: ",
  mesh.position.distanceTo(new THREE.Vector3(0, 1, 2))
);
console.log("和相机的距离: ", mesh.position.distanceTo(camera.position));

Alt text

// 回到向量长为1的位置
console.log("当前位置: ", mesh.position.length());
mesh.position.normalize();

Alt text

// mesh.position.x = 0.7
// mesh.position.y = -0.6
// mesh.position.z = 1
mesh.position.set(0.7, -0.6, 1);

axesHelper

Alt text

// axis helper 坐标轴
const axisHelper = new THREE.AxesHelper(); // 轴长为1
// const axisHelper = new THREE.AxesHelper(3) // 轴长为3

Alt text

scale 缩放

Alt text

// 每条边的长度缩放
// mesh.scale.x = 2 // 放大2倍
// mesh.scale.y = 0.5 // 缩小为0.5
// mesh.scale.z = 0.5 // 缩小为0.5
mesh.scale.set(2, 0.5, 0.5);

Alt text

rotate 旋转

有 rotation 和 quaternion 两种旋转,更新一个,就自动更新另一个

Alt text

// 旋转
mesh.rotation.y = 0.25;
// mesh.rotation.y = 3.14159  // 转半圈
// mesh.rotation.y = Math.PI / 2 // 转1/4圈
mesh.rotation.x = Math.PI * 0.25;
mesh.rotation.z = Math.PI * 0.25;

Alt text

有时,旋转了某个轴,则另一个轴的位置变了,旋转另一个轴会发生和预期不同的结果;有时,旋转不生效,发生了方向锁

调整旋转的次序,谁最优先

// 旋转
// 旋转的次序,声明在旋转动作前才生效
mesh.rotation.reorder("YXZ");
mesh.rotation.y = 0.25;
// mesh.rotation.y = 3.14159  // 转半圈
// mesh.rotation.y = Math.PI / 2 // 转1/4圈
mesh.rotation.z = Math.PI * 0.25;
mesh.rotation.x = Math.PI * 0.25;

Alt text

quaternion 可以更好地解决问题

lookat

// 看3D对象
// camera.lookAt(new THREE.Vector3(3, 0, 0))
camera.lookAt(mesh.position); // 看向mesh

Alt textAlt text

import "./style.css";
import * as THREE from "three";

// Canvas
const canvas = document.querySelector("canvas.webgl");

// Scene
const scene = new THREE.Scene();
/**
 * Objects
 */
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
// 位移
// mesh.position.x = 0.7
// mesh.position.y = -0.6
// mesh.position.z = 1
mesh.position.set(0.7, -0.6, 1);
// 每条边的长度缩放
// mesh.scale.x = 2 // 放大2倍
// mesh.scale.y = 0.5 // 缩小为0.5
// mesh.scale.z = 0.5 // 缩小为0.5
mesh.scale.set(2, 0.5, 0.5);
// 旋转
// 旋转的次序,声明在旋转动作前才生效
mesh.rotation.reorder("YXZ");
mesh.rotation.y = 0.25;
// mesh.rotation.y = 3.14159  // 转半圈
// mesh.rotation.y = Math.PI / 2 // 转1/4圈
mesh.rotation.z = Math.PI * 0.25;
mesh.rotation.x = Math.PI * 0.25;
scene.add(mesh);
// axis helper 坐标轴
const axisHelper = new THREE.AxesHelper(); // 轴长为1
// const axisHelper = new THREE.AxesHelper(3) // 轴长为3
scene.add(axisHelper);
// position向量的长度
console.log(" position向量的长度: ", mesh.position.length());
// 和某个位置的距离
console.log(
  "和某个位置的距离: ",
  mesh.position.distanceTo(new THREE.Vector3(0, 1, 2))
);
// 回到向量长为1的位置
// mesh.position.normalize()
console.log("当前位置: ", mesh.position.length());
/**
 * Sizes
 */
const sizes = {
  width: 800,
  height: 600,
};

/**
 * Camera
 */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 3;
// camera.position.y = 1
// camera.position.x = 1
scene.add(camera);
// 看3D对象
// camera.lookAt(new THREE.Vector3(3, 0, 0))
camera.lookAt(mesh.position); // 看向mesh
console.log("和相机的距离: ", mesh.position.distanceTo(camera.position));
/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});
renderer.setSize(sizes.width, sizes.height);
renderer.render(scene, camera);

group 组,将一些对象加到组里,方便统一处理和修改

Alt textAlt text

import "./style.css";
import * as THREE from "three";

// Canvas
const canvas = document.querySelector("canvas.webgl");

// Scene
const scene = new THREE.Scene();
// 组
const group = new THREE.Group();
scene.add(group);
// 几何体
const cube1 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
group.add(cube1);
const cube2 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
cube2.position.x = -2;
group.add(cube2);
const cube3 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: 0x0000ff })
);
cube3.position.x = 2;
group.add(cube3);
// 可以对group里的对象统一变换
group.position.y = 1;
group.scale.y = 2;
group.rotation.y = 1;
// axis helper 坐标轴
const axisHelper = new THREE.AxesHelper(); // 轴长为1
// const axisHelper = new THREE.AxesHelper(3) // 轴长为3
scene.add(axisHelper);
/**
 * Sizes
 */
const sizes = {
  width: 800,
  height: 600,
};

/**
 * Camera
 */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 3;
// camera.position.y = 1
// camera.position.x = 1
scene.add(camera);
// 看3D对象
// camera.lookAt(new THREE.Vector3(3, 0, 0))
/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});
renderer.setSize(sizes.width, sizes.height);
renderer.render(scene, camera);

Alt text

6_animations


  转载请注明: malred-blog 3D教程 Three.js

 上一篇
let virtualMachine = function (program) { let programCounter = 0 let stack = [] let stackPointer = 0 wh
2023-07-28 malred
下一篇 
Developing_Web_Components_with_Svelte Developing_Web_Components_with_Svelte
CHAPTER 1 Getting Started setupnpm create vite@latest cobalt --template svelte npm create vite@latest malui --template s
2023-07-23
  目录