three.js 矩形的每个面都贴上不同的图片

需求场景

        对模型添加不同的纹理材料,让一个盒子,展示不同面显示图面。

解决方案        

        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>

喜欢就加关注点赞收藏,一键三连哟!

  • 37
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值