需求场景
对模型添加不同的纹理材料,让一个盒子,展示不同面显示图面。
解决方案
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>
复制
喜欢就加关注点赞收藏,一键三连哟!