需求场景
对模型添加不同的纹理材料,让一个盒子,展示不同面显示图面。
解决方案
1、所有的模型都是一张图片的情况下,可以直接赋值;如果是多种图片,需要将不同的不通过用mesh融合,然后展示出来。
遇到的问题
1、每个面都是同一张图片?
2、不同的图片放不同的面?
3、图片如何在模型上进行x轴y轴平铺?
4、注意立方体纹理加载器和环境纹理加载器的区别?
TextureLoader:加载立方体(模型)贴图。
CubeTextureLoader:加载环境贴图。
5、vue3中加载assets中的模型是需要注意根节点?
以上四个问题,在代码注释中都有详细的说明,可以阅读下方的代码。
代码实施
<template>
<div ref="containerRef"></div>
</template>
<script setup>
import * as THREE from 'three'
import Stat from 'three/examples/jsm/libs/stats.module'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import * as dat from 'dat.gui'
import { onMounted, ref } from 'vue';
const containerRef = ref()
let w = window.innerWidth
let h = window.innerHeight
const stat = new Stat()
//设置场景
const scene = new THREE.Scene()
//设置相机
const camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 100)
//设置位置
camera.position.set(0, 1, 3)
//设置原点
camera.lookAt(0, 0, 0)
//渲染
const renderer = new THREE.WebGLRenderer()
//设置屏幕的尺寸
renderer.setSize(w, h)
//设置颜色
renderer.setClearColor(0x95e4e8)
renderer.shadowMap.enabled = true
//加载页面样式
document.body.append(renderer.domElement)
document.body.append(stat.dom)
const orbitControls = new OrbitControls(camera, renderer.domElement)
//添加光
//增加平行光
const light = new THREE.DirectionalLight({ color: 0xffffff, intensity: 0.1 })
//设置光的位置
light.position.set(1, 1, 1)
light.castShadow = true
//将光加入场景
scene.add(light)
//加入自然光
scene.add(new THREE.AmbientLight(0xffffff, 0.2))
//贴图
//立方体纹理加载器
//该加载器智能加载一张图片
const loader = new THREE.TextureLoader()
const texture7 = loader.load('src/assets/img/tietu/tietu7.jpg')
//多个面贴多张图片
const texture1 = loader.load('src/assets/img/tietu/tietu1.png')
const texture2 = loader.load('src/assets/img/tietu/tietu2.png')
const texture3 = loader.load('src/assets/img/tietu/tietu3.png')
const texture4 = loader.load('src/assets/img/tietu/tietu4.png')
const texture5 = loader.load('src/assets/img/tietu/tietu5.png')
const texture6 = loader.load('src/assets/img/tietu/tietu6.png')
texture4.magFilter = THREE.NearestFilter
texture4.wrapS = THREE.RepeatWrapping
texture4.wrapT = THREE.RepeatWrapping
// texture4.repeat.set(20, 20)
texture5.wrapS = THREE.RepeatWrapping
texture5.wrapT = THREE.MirroredRepeatWrapping
//设置在盒子模型内,x轴y轴平铺多少个
texture5.repeat.set(3, 3)
texture5.offset.set(0.5, 0)
//增加盒子模型
const cubeG = new THREE.BoxGeometry(1, 1, 1)
const cubeM = new THREE.MeshStandardMaterial({ map: texture7 })
const cube = new THREE.Mesh(cubeG, cubeM)
cube.position.y = 0.4
cube.castShadow = true
scene.add(cube)
//多个面添加多张图片 多种材料需要融合
let material = [
new THREE.MeshStandardMaterial({ map: texture1 }),
new THREE.MeshStandardMaterial({ map: texture2 }),
new THREE.MeshStandardMaterial({ map: texture3 }),
new THREE.MeshStandardMaterial({ map: texture4 }),
new THREE.MeshStandardMaterial({ map: texture5 }),
new THREE.MeshStandardMaterial({ map: texture6 }),
];
const cubeMore = new THREE.BoxGeometry(1, 1, 1)
const cubeMgore = new THREE.Mesh(cubeMore,material)
cubeMgore.position.y = 1.5
cubeMgore.castShadow = true
scene.add(cubeMgore)
//Plane
//添加一个矩形平面
const planeG = new THREE.PlaneGeometry(5, 5)
//设置材料为网络标准材料
const planeM = new THREE.MeshStandardMaterial({
map: texture5,
side: THREE.DoubleSide,
})
const plane = new THREE.Mesh(planeG, planeM)
plane.rotation.x = -0.5 * Math.PI
plane.receiveShadow = true
scene.add(plane)
//渲染器
const initData = () => {
requestAnimationFrame(initData)
renderer.render(scene, camera)
camera.updateProjectionMatrix()
stat.update()
orbitControls.update()
}
onMounted(() => {
initData()
//resize
window.addEventListener('resize', () => {
w = window.innerWidth
h = window.innerHeight
//Camera
camera.aspect = w / h
camera.updateProjectionMatrix()
//Renderer
renderer.setSize(w, h)
})
})
</script>
<style scoped lang="less"></style>
喜欢就加关注点赞收藏,一键三连哟!