vite+vue3+threejs實(shí)現(xiàn)一個(gè)簡單展示案例

app.vue

<template>
    <div class="scene" id="scene"></div>
</template>

<script setup>
import Base3d from './utils/Base3d2';
import { reactive,onMounted } from 'vue';
const data = reactive({
    base3d:{}
})
onMounted(()=>{
    data.base3d = new Base3d('#scene')
})
</script>

<style>
*{
    margin:0;
    padding: 0;
    overflow: hidden;
}
</style>

Base3d2.js

import * as THREE from 'three' //導(dǎo)入整個(gè) three.js核心庫
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //導(dǎo)入控制器模塊,軌道控制器
//聲明一個(gè)類
class Base3d {
    //構(gòu)造器
    constructor(selector) {
        this.container = document.querySelector(selector)
        this.camera
        this.scene
        this.renderer
        this.controls
        this.spotLight
        this.init()
        this.animate()
    }
    init() {
        //初始化場景
        this.initScene()
        //初始化相機(jī)
        this.initCamera()
        //初始化渲染器
        this.initRender()
        //初始化控制器,控制攝像頭,控制器一定要在渲染器后
        this.initControls()
        //監(jiān)聽場景大小改變,跳轉(zhuǎn)渲染尺寸
        window.addEventListener("resize", this.onWindowResize.bind(this))
        //初始化三維坐標(biāo)系
        this.initAxesHelper()
        //初始化幾何體網(wǎng)格模型
        this.initGeometry()
        //初始化燈光
        this.initLight()
    }
    initScene() {
        this.scene = new THREE.Scene()
    }
    initCamera() {
        this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 2000)
        this.camera.position.set(30, 30, 30)
        this.camera.lookAt(this.scene.position)
    }
    initRender() {
        this.renderer = new THREE.WebGLRenderer({ antialias: true }) //設(shè)置抗鋸齒
        //設(shè)置屏幕像素比
        this.renderer.setPixelRatio(window.devicePixelRatio)
        //渲染的尺寸大小
        this.renderer.setSize(window.innerWidth, window.innerHeight)
        //色調(diào)映射
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping
        //曝光
        this.renderer.toneMappingExposure = 3
        //初始化背景顏色
        this.renderer.setClearColor(new THREE.Color(0xeeeeee));
        // 設(shè)置渲染物體陰影
        this.renderer.shadowMap.enabled = true;
        this.container.appendChild(this.renderer.domElement)
    }
    render() {
        this.renderer.render(this.scene, this.camera)
    }
    animate() {
        this.renderer.setAnimationLoop(this.render.bind(this))
    }
    initControls() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    }
    onWindowResize() { //調(diào)整屏幕大小
        this.camera.aspect = window.innerWidth / window.innerHeight //攝像機(jī)寬高比例
        this.camera.updateProjectionMatrix() //相機(jī)更新矩陣,將3d內(nèi)容投射到2d面上轉(zhuǎn)換
        this.renderer.setSize(window.innerWidth, window.innerHeight)
    }
    initAxesHelper() {//三維坐標(biāo)系
        this.axes = new THREE.AxesHelper(20)
        this.scene.add(this.axes)
    }
    initGeometry() {
        const planeGeometry = new THREE.PlaneGeometry(60, 60);
        // 給地面物體上色
        const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xcccccc });
        // 創(chuàng)建地面
        const plane = new THREE.Mesh(planeGeometry, planeMaterial)
        // 物體移動(dòng)位置
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = 0;
        plane.position.z = 0;
        plane.castShadow = true;
        // 接收陰影
        plane.receiveShadow = true;
        // 將地面添加到場景中
        this.scene.add(plane);

        // 添加立方體
        const cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
        const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 })
        const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.position.x = 0;
        cube.position.y = 4;
        cube.position.z = 2;
        // 對象是否渲染到陰影貼圖當(dāng)中
        cube.castShadow = true;
        this.scene.add(cube)

        // 球體
        const sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
        const spherMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 })
        const sphere = new THREE.Mesh(sphereGeometry, spherMaterial)
        sphere.position.x = 10;
        sphere.position.y = 4;
        sphere.position.z = 0;
        // 對象是否渲染到陰影貼圖當(dāng)中
        sphere.castShadow = true;
        this.scene.add(sphere)
    }
    initLight() {
        // 創(chuàng)建聚光燈
        const spotLight = new THREE.SpotLight(0xFFFFFF);
        spotLight.position.set(130, 130, -130);
        spotLight.castShadow = true;
        spotLight.angle = Math.PI / 4;
        spotLight.shadow.penumbra = 0.05
        spotLight.shadow.mapSize.width = 1024;
        spotLight.shadow.mapSize.innerHeight = 1024;
        // 添加聚光燈
        this.scene.add(spotLight)
    }
}
export default Base3d
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容