THREE初始化(场景 相机 渲染器 控制器等)

<template>
    <div class="webgl-container">
        <div id="webglDom" ref="webglDom" style="height: 1080px;"></div>
    </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

export default {
    name:'',

    data(): {
        return {
            // 场景 相机 渲染器 控制器
            scene: undefined,
            camera: undefined,
            renderer: undefined,
            controls: undefined,

            // 容器宽高
            containerWidth: 0,
            containerHeight: 0,
            
            // requestAnimationFrame
            requestAnimationId: undefined,

            // 平行光 环境光
            directionalLight: undefined,
            ambient: undefined,

            // 相机参数
            //  fov — 摄像机视锥体垂直视野角度
            fov: 45,
            // far — 摄像机视锥体远端面
            far: 10000,
            // near — 摄像机视锥体近端面
            near: 0.01,
        },

    mounted() {
        this.$nextTick(() => {
            this.init();
        });
    },

    // 在页面卸载时或重新加载场景时调用 clearCache 方法
    beforeDestroy() {
        // 页面卸载前清除内存,定时器,渲染器等
        cancelAnimationFrame(this.requestAnimationId);
        new THREE.Cache.clear();
        window.removeEventListener("resize", this.onWindowResize);
        window.removeEventListener("mousewheel", this.mousewheel);
    },

    methods: {
        // 初始化场景
        initScene() {
            this.scene = new THREE.Scene();
            // 背景
            this.scene.background = new THREE.Color(0xeaeaea);
        },

        // 初始化相机
        initCamera() {
            this.camera = new THREE.PerspectiveCamera(
                this.fov,
                this.containerWidth / this.containerHeight,
                this.near,
                this.far
            );
            // 相机位置
            this.camera.position.set(-4000, 8000, 6400);
            this.scene.add(this.camera);
            // 摄像头朝向
            this.camera.lookAt(this.scene.position);
        },

        // 初始化灯光
        initLight() {
            // 平行光  类似太阳的光源
            this.directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
            this.directionalLight.color.setHSL(0.1, 1, 0.95);
            this.directionalLight.position.set(0, 1000, 0).normalize();
            this.scene.add(this.directionalLight);
            // 环境光  影响整个场景的光源
            this.ambient = new THREE.AmbientLight(0xffffff, 1);
            this.ambient.position.set(0, 0, 0);
            this.scene.add(this.ambient);
        },

        // 初始化渲染器
        initRenderer() {
            this.renderer = new THREE.WebGLRenderer({
                antialias: true,
                logarithmicDepthBuffer: true,
            });
            this.renderer.setSize(this.containerWidth, this.containerHeight);
            this.renderer.setClearColor(0x4682b4, 1.0);
            document
                .getElementById("webglDom")
                .appendChild(this.renderer.domElement);
        },

        // 实时渲染
        animate() {
            // 不要同时使用 requestAnimationFrame()和controls.addEventListener('change', render)调用同一个函数,这样会冲突。
            this.requestAnimationId = requestAnimationFrame(this.animate);
            this.renderer.render(this.scene, this.camera);
            this.update();
        },

        // 初始化轨迹球控件
        initControls() {
            this.controls = new OrbitControls(
                this.camera,
                this.renderer.domElement
            );
            this.controls.enableDamping = true;
            this.controls.dampingFactor = 0.5;
            // 视角最小距离
            this.controls.minDistance = 2000;
            // 视角最远距离
            this.controls.maxDistance = 5500;
            // 最大角度
            this.controls.maxPolarAngle = Math.PI / 2.2;
        },

        // 更新控件
        update() {
            this.controls.update();
        },

        // 窗口变动触发的方法
        onWindowResize() {
            this.camera.aspect = this.containerWidth / this.containerHeight;
            this.camera.updateProjectionMatrix();
            this.renderer.setSize(this.containerWidth / this.containerHeight);
        },

        // 鼠标滑轮 放大缩小
        mousewheel(e) {
            e.preventDefault();
            //e.stopPropagation();
            if (e.wheelDelta) {
                //判断浏览器IE,谷歌滑轮事件
                if (e.wheelDelta > 0) {
                    //当滑轮向上滚动时
                    this.fov -= this.near < this.fov ? 1 : 0;
                }
                if (e.wheelDelta < 0) {
                    //当滑轮向下滚动时
                    this.fov += this.fov < this.far ? 1 : 0;
                }
            } else if (e.detail) {
                //Firefox滑轮事件
                if (e.detail > 0) {
                    //当滑轮向上滚动时
                    this.fov -= 1;
                }
                if (e.detail < 0) {
                    //当滑轮向下滚动时
                    this.fov += 1;
                }
                this.camera.fov = this.fov;
                this.camera.updateProjectionMatrix();
                this.renderer.render(this.scene, this.camera);
            }
        },

        //初始化
        init() {
            //获取div盒子
            const container = this.$refs.webglDom;
            //div盒子的宽高
            this.containerWidth = container.offsetWidth;
            this.containerHeight = container.offsetHeight;

            // 场景
            this.initScene();
            // 相机
            this.initCamera();
            // 渲染器
            this.initRenderer();
            // 灯光
            this.initLight();
            // 控制器
            this.initControls();

            // 实时渲染
            this.animate();

            // 事件监听
            document
                .getElementById("webglDom")
                .addEventListener("resize", this.onWindowResize, false);
            document
                .getElementById("webglDom")
                .addEventListener("mousewheel", this.mousewheel, {
                    passive: false,
                });
        },
    },
}
</script>

<style scoped>
#webglDom,
.webgl-container {
    width: 100%;
    height: 98%;
    overflow: hidden;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,three.js 中可以通过鼠标控制相机的位置和朝向,这可以通过引入 `OrbitControls` 来实现。`OrbitControls` 是 three.js 中一个常用的控制器,可以通过鼠标控制相机的位置、朝向和缩放等操作。下面是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Three.js 相机鼠标控制示例</title> <style> body { margin: 0; padding: 0; } canvas { width: 100%; height: 100%; } </style> </head> <body> <script src="https://cdn.jsdelivr.net/npm/three@0.131.0/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three/examples/js/controls/OrbitControls.js"></script> <script> // 初始化场景相机渲染 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加一个立方体 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 添加光源 const light = new THREE.PointLight(0xffffff, 1, 100); light.position.set(0, 0, 10); scene.add(light); // 添加鼠标控制 const controls = new THREE.OrbitControls(camera, renderer.domElement); // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); </script> </body> </html> ``` 在这个示例中,我们首先初始化场景相机渲染,并添加了一个立方体和一个光源。接着,我们引入了 `OrbitControls`,并使用 `OrbitControls` 创建了一个控制器 `controls`,将相机渲染传入。最后,我们开启了渲染循环,并在循环中调用 `renderer.render` 方法和 `controls.update` 方法。这样,我们就实现了通过鼠标控制相机的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值