最进研究 Three.js 所以 发布及记录一篇 3D 的文章
第一步 引入 Three
npm install three
然后 页面引入 整个页面 基本每行 我都有标注 应该很清楚 并且 复制粘贴 整个页面 替换一下 模型模型 也可以使用
模型的位置:
下附代码
<template>
<div ref="threeContainer"></div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
export default {
name: "Index",
data() {
return {
scene: null,
camera: null,
renderer: null,
loader: null,
model: null,
newModel: null,
pointLight: null,
controls: null,
point: null,
ground: null,
loaderOn: null,
models: [], // 用于存储场景中的所有模型
axesHelper: null,
loader2: null,
loader3: null,
loader3Model: null,
loader2Model: null,
raycaster: null
};
},
mounted() {
this.initThree(); // 创建场景、相机和渲染器
this.Dmodel(); // 初始化及加载 3D模型方法
this.animate(); // 在动画循环中更新和渲染场景,同时更新OrbitControls
this.xyz(); // 创建一个原点坐标轴辅助对象 在线上环境时 关闭辅助线 开发时 进行拼接模型时 我喜欢对照辅助线进行参考
},
methods: {
// 初始化及加载 3D模型方法
Dmodel(){
// 初始化 模型一
this.loader2 = new GLTFLoader();
this.loader2.load('./模型一.glb', (gltf) => {
this.loader2Model = gltf.scene;
this.loader2Model.position.x = 154.6; // 此模型在 三维空间的 X 轴位置
this.loader2Model.position.y = 100; // 此模型在 三维空间的 y 轴位置
this.loader2Model.position.z = 100; // 此模型在 三维空间的 z 轴位置
this.scene.add(this.loader2Model); // 添加到场景
});
// 初始化 模型二
this.loader3 = new GLTFLoader();
this.loader3.load('./模型二.glb', (gltf) => {
this.loader3Model = gltf.scene;
this.loader3Model.position.x = 152.2; // 此模型在 三维空间的 X 轴位置
this.loader3Model.position.y = 100; // 此模型在 三维空间的 y 轴位置
this.loader3Model.position.z = 100; // 此模型在 三维空间的 z 轴位置
this.scene.add(this.loader52Model); // 添加到场景
});
},
initThree() {
// 创建场景、相机和渲染器
this.scene = new THREE.Scene(); // 场景
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); // 相机
this.renderer = new THREE.WebGLRenderer({ // 光源
antialias: true, // 抗锯齿
});
this.renderer.setClearColor(0xb2b2b2, 1); // 设置背景颜色
// 创建一个环境光源
const ambientLight = new THREE.AmbientLight( 0xc0c0c0 ); // soft white light
ambientLight.castShadow = true; // 开启阴影效果
this.scene.add(ambientLight);
// 设置渲染器的大小和将其添加到DOM元素中
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.$refs.threeContainer.appendChild(this.renderer.domElement);
// 将相机放置在合适的位置,以便看到模型 调整相机位置 参考 xyz轴线 和模型位置
this.camera.position.z = 30;
this.camera.position.x = 70;
this.camera.position.y = 120;
// 初始化OrbitControls并将相机传递给它
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
// 设置阴影贴图大小和软阴影效果
this.renderer.shadowMapWidth = 512; // 设置阴影贴图宽度
this.renderer.shadowMapHeight = 512; // 设置阴影贴图高度
this.renderer.shadowMapSoft = true; // 开启软阴影效果
},
animate() {
// 在动画循环中更新和渲染场景,同时更新OrbitControls
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera); // 渲染场景
},
xyz(){
// 创建一个原点坐标轴辅助对象
this.axesHelper = new THREE.AxesHelper(300); // 这里的数字表示坐标轴的长度
this.scene.add(this.axesHelper);
},
},
};
</script>
<style>
#threeContainer {
width: 100%;
height: 100vh;
}
</style>
10月18日 修改 优化模型加载方式 多个模型 节省代码量 及 添加点光源
下附代码
<template>
<div ref="threeContainer"></div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
export default {
name: "Index",
data() {
return {
};
},
mounted() {
this.initThree();
this.Dmodel();
this.animate();
this.xyz();
},
methods: {
// 初始化及加载 3D模型方法
Dmodel(){
// 初始化 模型一GLTFLoader
let loader1 = new GLTFLoader();
// 定义一个包含所有 模型位置的数组
let positions = [
{ x: 100, y: 100, z: 150 }, 1模型的位置 相同模型
{ x: 100, y: 100, z: 134.5 }, 2模型的位置 相同模型 一个对象后面遍历
];
// 使用循环初始化所有 模型
for (let i = 0; i < positions.length; i++) {
loader1.load('./机器.glb', (gltf) => {
let loader1Model = gltf.scene;
loader1Model.receiveShadow = true; // 开启模型接收阴影的特性
loader1Model.castShadow = true; // 开启模型投射阴影的特性
loader1Model.position.copy(positions[i]); // 使用从数组中获取的位置
this.scene.add(loader1Model);
});
}
// 初始化 模型二GLTFLoader
let loader1 = new GLTFLoader();
// 定义一个包含所有 模型位置的数组
let positions = [
{ x: 100, y: 100, z: 150 }, 1模型的位置 相同模型
{ x: 100, y: 140, z: 134.5 }, 2模型的位置 相同模型 一个对象后面遍历
{ x: 100, y: 110, z: 150 }, 3模型的位置 相同模型
{ x: 100, y: 130, z: 134.5 }, 4模型的位置 相同模型
{ x: 100, y: 120, z: 134.5 }, 5模型的位置 相同模型
];
// 使用循环初始化所有 模型
for (let i = 0; i < positions.length; i++) {
loader1.load('./机器2.glb', (gltf) => {
let loader1Model = gltf.scene;
loader1Model.receiveShadow = true; // 开启模型接收阴影的特性
loader1Model.castShadow = true; // 开启模型投射阴影的特性
loader1Model.position.copy(positions[i]); // 使用从数组中获取的位置
this.scene.add(loader1Model);
});
}
},
initThree() {
// 创建场景、相机和渲染器
this.scene = new THREE.Scene(); // 场景
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); // 相机
this.renderer = new THREE.WebGLRenderer({ // 光源
antialias: true, // 抗鋸齿
gammaFactor: 2.2, // gamma校正因子
outputEncoding: THREE.sRGBEncoding, // 输出编码方式
});
this.renderer.setClearColor(0xb2b2b2, 1); // 设置背景颜色
// 设置渲染器的大小和将其添加到DOM元素中
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.$refs.threeContainer.appendChild(this.renderer.domElement);
// 将相机放置在合适的位置,以便看到模型
this.camera.position.z = 30;
this.camera.position.x = 130;
this.camera.position.y = 120;
// 初始化OrbitControls并将相机传递给它
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
// 创建一个环境光源
const ambientLight = new THREE.AmbientLight(0xc0c0c0);
ambientLight.castShadow = true;
this.scene.add(ambientLight);
// 创建一个点光源
const pointLight = new THREE.PointLight(0xc0c0c0, 0.5);
// 设置点光源的位置
pointLight.position.set(75, 110, 25);
// // 测试 点光源位置
// const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // RGB值为红色
// const sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 10, 10), sphereMaterial);
// this.scene.add(sphere);
// sphere.add(pointLight);
// sphere.position.x = 75;
// sphere.position.y = 90;
// sphere.position.z = 25;
// 将点光源添加到场景中
this.scene.add(pointLight);
},
animate() {
// 在动画循环中更新和渲染场景,同时更新OrbitControls
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera); // 渲染场景
},
xyz(){
// 创建一个原点坐标轴辅助对象
this.axesHelper = new THREE.AxesHelper(300); // 这里的数字表示坐标轴的长度
this.scene.add(this.axesHelper);
},
},
};
</script>
<style>
#threeContainer {
width: 100%;
height: 100vh;
}
</style>