vue结合threejs实现贴图
vue结合threejs实现贴图的方法
安装依赖
确保项目中已安装three和vue-threejs(可选)。通过npm或yarn安装:
npm install three @vueuse/core
基础场景搭建
在Vue组件中初始化Three.js场景、相机和渲染器:

import * as THREE from 'three';
import { onMounted } from 'vue';
export default {
setup() {
let scene, camera, renderer;
onMounted(() => {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('container').appendChild(renderer.domElement);
});
}
};
加载纹理贴图
使用THREE.TextureLoader加载图片作为纹理:
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('/path/to/texture.jpg');
// 创建带贴图的材质
const material = new THREE.MeshBasicMaterial({ map: texture });
应用贴图到几何体
将材质应用到几何体(如立方体)并添加到场景:

const geometry = new THREE.BoxGeometry();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
动画循环
通过requestAnimationFrame实现渲染循环:
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
响应式处理
使用@vueuse/core的useResizeObserver实现画布自适应:
import { useResizeObserver } from '@vueuse/core';
useResizeObserver(document.body, () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
进阶优化(可选)
- 使用
THREE.OrbitControls添加交互控制 - 通过
THREE.CubeTextureLoader加载环境贴图 - 使用
THREE.MeshStandardMaterial配合光照实现PBR效果
完整组件示例
<template>
<div id="container"></div>
</template>
<script setup>
import * as THREE from 'three';
import { onMounted } from 'vue';
import { useResizeObserver } from '@vueuse/core';
let scene, camera, renderer, cube;
onMounted(() => {
initThree();
animate();
});
function initThree() {
// 初始化场景
scene = new THREE.Scene();
// 初始化相机
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 初始化渲染器
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('container').appendChild(renderer.domElement);
// 加载贴图
const texture = new THREE.TextureLoader().load('/texture.jpg');
const material = new THREE.MeshBasicMaterial({ map: texture });
// 创建立方体
const geometry = new THREE.BoxGeometry();
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 响应式处理
useResizeObserver(document.body, () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
</script>
注意事项
- 贴图文件需放在
public目录或通过Webpack配置别名 - 跨域图片需确保服务器配置CORS或使用代理
- 性能敏感场景建议使用
THREE.CompressedTextureLoader加载压缩纹理






