项目依赖
拖拽控件
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
性能检测控件
import * as THREE from "three";
import Stats from "three/addons/libs/stats.module.js";
创建模型
创建正方体
初始化环境
const scene = new THREE.Scene();
添加需要模型
const boxGeometry = new THREE.BoxGeometry(200, 200, 200);
添加材质
几种常见材质
MeshBasicMaterial
无光照MeshLambertMaterial
漫反射MeshPhongMaterial
高光网格材质MeshStandardMaterial
物理光照MeshPhysicalMaterial
物理光照
const material = new THREE.MeshLambertMaterial({
color: 0xff0000,
// shininess: 1000, // 高光部分亮度,默认30
// specular: 0x444444,
transparent: true,
opacity: 1,
});
实例
// 添加材质
const material = new THREE.MeshLambertMaterial({
color: 0x67c23a,
transparent: true,
opacity: 0.9,
});
创建网格模型
// 创建网格模型
const mesh = new THREE.Mesh(boxGeometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
结果
const scene = new THREE.Scene();
const boxGeometry = new THREE.BoxGeometry(200, 200, 200);
// 添加材质
const material = new THREE.MeshLambertMaterial({
color: 0x67c23a,
transparent: true,
opacity: 0.9,
});
// 创建网格模型
const mesh = new THREE.Mesh(boxGeometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
环境相关
创建三维坐标
// 创建三维坐标
const axesHelper = new THREE.AxesHelper(8888);
scene.add(axesHelper);
创建环境光
// 创建环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);
创建点光源相关
点光源
// 创建点光源
const pointLgiht = new THREE.PointLight(0xffffff);
pointLgiht.position.set(500, 500, 500);
scene.add(pointLgiht);
可视化点光源
// 创建可视化点光源
const pointLigheHelper = new THREE.PointLightHelper(pointLgiht, 5);
scene.add(pointLigheHelper);
创建平行光相关
创建平行光
// 创建平行光
const directionalLight = new THREE.DirectionalLight(0xffff00, 10);
directionalLight.position.set(200, 0, 0)
scene.add(directionalLight);
可视化平行光
// 可视化平行光
const directionalLightHelper = new THREE.DirectionalLightHelper(
directionalLight,
10,
0xff00ff
);
scene.add(directionalLightHelper);
设定相机
// 设定相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
8000
);
camera.position.set(500, 500, 500);
camera.lookAt(300, 300, 300);
渲染页面内容
添加渲染器
- 需要有渲染器并且添加到页面才可以
// 创建wbe渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio); // 设置屏幕像素比---必写
renderer.setClearAlpha(0x6ea84e, 0.5); // 颜色和透明度
renderer.render(scene, camera);
添加抗锯齿
// 创建渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true, // 启动抗锯齿
});
添加页面内容
// 添加到页面元素中
document.body.appendChild(renderer.domElement);
控件相关
动画效果
- 可以添加函数名的方式调用,也可以使用函数自执行
// 渲染动画
(function render() {
stats.update();// 更新插件显示
mesh.rotateX(0.01);
mesh.rotateY(0.01);
requestAnimationFrame(render);// 请求动画帧
renderer.render(scene, camera);// 重新渲染页面
})();
优化全屏显示
// 显示全屏
window.addEventListener("resize", () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
});
帧率插件
// 创建渲染帧率插件
const stats = new Stats();
const statsElement = document
.getElementById("stats")
.appendChild(stats.domElement);
statsElement.querySelectorAll("canvas").forEach((element) => {
element.style.width = "200px";
element.style.height = "150px";
});
拖拽效果
// 拖拽动画
const controls = new OrbitControls(camera, renderer.domElement);
controls.update();
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
控制显示位置
- 在设置
lookAt
值时,需要将下面controls.target.set
也设置成相同值
- 两个值设置相同时会出现中间显示
-
如果单独设置
lookAt
值不会有任何变化 -
并且要设置
controls.update();
是页面更新*
camera.lookAt(3000, 300, 3000);
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(3000, 300, 3000);
GUI库的使用
值修改和设置步长
直接修改值
/* ------------ 直接修改值 ------------ */
gui.add(mesh.position, "y", 0, 10000);
修改显示名
/* ------------ 修改显示名 ------------ */
gui.add(mesh.position, "z", 0, 10000).name("z轴变更");
设置不步长
/* ------------ 设置不步长 ------------ */
gui.add(ambientLight, "intensity", 0, 1).step(0.1).name("光照强度");
设置环境光颜色
/* ------------ 设置环境光颜色 ------------ */
gui.addColor(coordinates, "color").onChange((value) => {
ambientLight.color.set(value);
});
变更参数设定
数组方式修改
/* ------------ 设置数据类型-数组 ------------ */
gui.add(mesh.position, "x", [0, 100, 200]).name("设置 x 坐标");
参数类型设定
/* ------------ 参数数据类型---可以使用中文 ------------ */
gui.add(mesh.position, "x", {
// left: -100,
// center: 0,
// right: 100,
左: -100,
中: 0,
右: 100,
}).name("设置显示位置");
添加子组
// ------------ 添加子菜单 可以嵌套循环 ------------
const boolClass = gui.addFolder("布尔值");
/* ------------ 布尔值的设置 ------------ */
boolClass.add(pointLightHelper, "visible").name("设置是否显示");
/* ------------ 设置是否旋转 ------------ */
boolClass.add(coordinates, "isRotate").name("是否旋转");
子组默认状态
- 默认是打开状态,可以使用下面这行进行默认关闭
/* 默认关闭 */
boolClass.close();
功能相关
设置颜色
实例化颜色
const color = new THREE.Color();
color.setRGB(0, 0, 1);
console.log("color :>> ", color);// 之后将值赋值
通过前端设置
// 通过前端设置,以下两种都可以
color.setStyle("#fba");
color.set("#fef");
color.set("rgb(255,255,210)");
color.set(0xffffff);
通过属性直接访问
// 通过属性直接访问
const pointLight = new THREE.PointLight(0xffffff);
pointLight.color.r = 0;
pointLight.color.g = 1;
设置贴图
// 创建纹理加载器
const TextureLoader = new THREE.TextureLoader();
// 将创建的纹理加载器去加载
const texture = TextureLoader.load("./test.jpg");
// 添加材质
const material = new THREE.MeshLambertMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.9,
map: texture,// 将贴图赋值
});
uv坐标设置
/* -------------设置贴图-------------- */
// 创建纹理加载器
const TextureLoader = new THREE.TextureLoader();
// 将创建的纹理加载器去加载
const texture = TextureLoader.load("./730a293671f994af5078e71634b3e8f9.jpg");
// 纹理坐标值范围在 0~1 之间
const uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
/* -------------设置贴图-------------- */
const scene = new THREE.Scene();
// 正方体材质
const planGeometry = new THREE.PlaneGeometry(200, 100);
planGeometry.attributes.uv = new THREE.BufferAttribute(uvs, 2); // 设置iv坐标位置属性,2个为一组
// 添加材质
const material = new THREE.MeshLambertMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.9,
side: THREE.DoubleSide,
map: texture, // 将贴图赋值
});
const mesh = new THREE.Mesh(planGeometry, material);
mesh.position.set(100, 0, 0);
scene.add(mesh);
阵列
import * as THREE from "three";
// 创建纹理加载器
const TextureLoader = new THREE.TextureLoader();
// 将创建的纹理加载器去加载
const texture = TextureLoader.load("./0e5a1da8da4f88c1ac2fa98a692f4922.jpg");
// 设置整列模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(12, 12);
// 正方体材质
const planeGeometry = new THREE.PlaneGeometry(2000, 2000);
// planeGeometry.attributes.uv = new THREE.BufferAttribute(uvs, 2); // 设置iv坐标位置属性,2个为一组
// 添加材质
const material = new THREE.MeshLambertMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.9,
side: THREE.DoubleSide,
map: texture, // 将贴图赋值
});
const mesh = new THREE.Mesh(planeGeometry, material);
mesh.position.set(100, 0, 0);
export default mesh;