看效果
一、下载threejs
yarn add three
引入 threejs
import * as THREE from "three";
二、创建一个放模型的盒子
<template>
<div class="canvasContainer" ref="canvasContainer"></div>
</template>
三、在页面初始话完成之后创建场景和摄像机
<script setup>
import { onMounted, onUnmounted } from "vue";
import { reactive, ref, toRefs } from "@vue/reactivity";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
const canvasContainer = ref(null);
onMounted(() => {
// 初始化场景
const scene = new THREE.Scene();
// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 初始化相机
camera.position.set(1.5, 1, 1.5);
//曲面屏宽高比
camera.aspect = window.innerWidth / window.innerHeight;
//加载背景纹理
/****************************/
//加载模型
/***************************/
// 更新相机投影矩阵
// 注意,如果相机对象的投影矩阵相关属性没有变化,每次执行.render()方法的时候,都重新计算相机投影矩阵值,
// 会浪费不必要的计算资源,一般来说就是首次渲染计算一次,后面不执行.updateProjectionMatrix()
camera.updateProjectionMatrix();
// 初始化渲染器 antialias是否执行抗锯齿。默认值为false。
const renderer = new THREE.WebGLRenderer({ antialias: true });
// 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 添加到页面
canvasContainer.value.appendChild(renderer.domElement);
// 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置阻尼
controls.enableDamping = true;
// 渲染函数
const render = () => {
// 更新控制器
controls.update();
renderer.render(scene, camera);
// 循环渲染
requestAnimationFrame(render);
};
render();
});
</script>
四、加载背景纹理
// 加载背景纹理
const loader = new THREE.TextureLoader();
const bgTexture = loader.load(require("../assets/050.jpg"));
// 球行全景纹理EquirectangularRefractionMapping折射纹理
// 映射场景(球状体里面)
bgTexture.mapping = THREE.EquirectangularRefractionMapping;
// 场景背景添加纹理
scene.background = bgTexture;
// 场景环境添加纹理
scene.environment = bgTexture;
五、给物体加上自己想要的环境光
// 添加环境光
const ambient = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambient);
六、加载模型 我们需要导入
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 加载模型
const gltfLoader = new GLTFLoader();
gltfLoader.load("/assets/imgs/tablelamp.gltf",(gltf)=>{
const model = gltf.scene.children[0];
model.material = new THREE.MeshPhongMaterial({
color: 0xffffff,
envMap: bgTexture,
refractionRatio: 0.7,
reflectivity: 0.99,
});
scene.add(model);
})
完整代码 静态文件要放在public\assets里不然会报错
<template>
<div class="canvasContainer" ref="canvasContainer"></div>
</template>
<script setup>
import { onMounted, onUnmounted } from "vue";
import { reactive, ref, toRefs } from "@vue/reactivity";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
const canvasContainer = ref(null);
onMounted(() => {
// 初始化场景
const scene = new THREE.Scene();
// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 初始化相机
camera.position.set(1.5, 1, 1.5);
//曲面屏宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新相机投影矩阵
// 注意,如果相机对象的投影矩阵相关属性没有变化,每次执行.render()方法的时候,都重新计算相机投影矩阵值,
// 会浪费不必要的计算资源,一般来说就是首次渲染计算一次,后面不执行.updateProjectionMatrix()
camera.updateProjectionMatrix();
// 加载背景纹理
const loader = new THREE.TextureLoader();
const bgTexture = loader.load(require("../assets/050.jpg"));
// 球行全景纹理EquirectangularRefractionMapping折射纹理
// 映射场景(球状体里面)
bgTexture.mapping = THREE.EquirectangularRefractionMapping;
// 场景背景添加纹理
scene.background = bgTexture;
// 场景环境添加纹理
scene.environment = bgTexture;
// 添加环境光
const ambient = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambient);
// 加载模型
const gltfLoader = new GLTFLoader();
gltfLoader.load("/assets/imgs/tablelamp.gltf",(gltf)=>{
const model = gltf.scene.children[0];
// model.material = new THREE.MeshPhongMaterial({
// color: '#434620',
// envMap: bgTexture,
// refractionRatio: 0.7,
// reflectivity: 0.99,
// });
scene.add(model);
})
// 初始化渲染器 antialias是否执行抗锯齿。默认值为false。
const renderer = new THREE.WebGLRenderer({ antialias: true });
// 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 监听屏幕大小变化
// window.addEventListener("resize", () => {
// renderer.setSize(window.innerWidth, window.innerHeight);
// (camera.aspect = window.innerWidth), window.innerHeight;
// camera.updateProjectionMatrix();
// });
// 添加到页面
canvasContainer.value.appendChild(renderer.domElement);
// 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置阻尼
controls.enableDamping = true;
// 渲染函数
const render = () => {
// 更新控制器
controls.update();
renderer.render(scene, camera);
// 循环渲染
requestAnimationFrame(render);
};
render();
});
</script>