美文网首页
vite+vue3+threejs实现一个简单展示案例

vite+vue3+threejs实现一个简单展示案例

作者: 似朝朝我心 | 来源:发表于2022-04-18 11:46 被阅读0次

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' //导入整个 three.js核心库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //导入控制器模块,轨道控制器
//声明一个类
class Base3d {
    //构造器
    constructor(selector) {
        this.container = document.querySelector(selector)
        this.camera
        this.scene
        this.renderer
        this.controls
        this.spotLight
        this.init()
        this.animate()
    }
    init() {
        //初始化场景
        this.initScene()
        //初始化相机
        this.initCamera()
        //初始化渲染器
        this.initRender()
        //初始化控制器,控制摄像头,控制器一定要在渲染器后
        this.initControls()
        //监听场景大小改变,跳转渲染尺寸
        window.addEventListener("resize", this.onWindowResize.bind(this))
        //初始化三维坐标系
        this.initAxesHelper()
        //初始化几何体网格模型
        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 }) //设置抗锯齿
        //设置屏幕像素比
        this.renderer.setPixelRatio(window.devicePixelRatio)
        //渲染的尺寸大小
        this.renderer.setSize(window.innerWidth, window.innerHeight)
        //色调映射
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping
        //曝光
        this.renderer.toneMappingExposure = 3
        //初始化背景颜色
        this.renderer.setClearColor(new THREE.Color(0xeeeeee));
        // 设置渲染物体阴影
        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() { //调整屏幕大小
        this.camera.aspect = window.innerWidth / window.innerHeight //摄像机宽高比例
        this.camera.updateProjectionMatrix() //相机更新矩阵,将3d内容投射到2d面上转换
        this.renderer.setSize(window.innerWidth, window.innerHeight)
    }
    initAxesHelper() {//三维坐标系
        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 });
        // 创建地面
        const plane = new THREE.Mesh(planeGeometry, planeMaterial)
        // 物体移动位置
        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;
        // 对象是否渲染到阴影贴图当中
        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;
        // 对象是否渲染到阴影贴图当中
        sphere.castShadow = true;
        this.scene.add(sphere)
    }
    initLight() {
        // 创建聚光灯
        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

相关文章

网友评论

      本文标题:vite+vue3+threejs实现一个简单展示案例

      本文链接:https://www.haomeiwen.com/subject/jbhdertx.html