Vue 3 中使用 Three.js 模拟楼栋阳光照射时长

在 Vue 3 中使用 Three.js 模拟楼栋阳光照射时长

本文将介绍如何在 Vue 3 应用程序中使用 Three.js 创建一个三维场景,模拟一天中不同时段楼栋落地窗接收到的阳光照射时长。

技术要点

  • Three.js 场景搭建:通过 THREE.SceneTHREE.PerspectiveCameraTHREE.WebGLRenderer 构建基础三维场景。
  • 光源与阴影:使用 THREE.AmbientLight 提供环境光和 THREE.DirectionalLight 模拟太阳光,并启用阴影映射以增强光照效果的真实性。
  • 相机控制:利用 [OrbitControls](file://h:\project_induce\24\project\vue3-demo\public\jsm\controls\OrbitControls.js#L42-L1113) 实现交互式视角控制,便于观察整个建筑群。
  • 建筑模型创建:定义 createBuilding 函数生成具有多楼层结构的楼体及其窗户,采用 THREE.BoxGeometry 结合材质对象创建几何形状并设置位置信息。
  • 日照时间计算
    • 使用 THREE.Raycaster 对象检测每个窗户是否被其他建筑物遮挡。
    • 遍历指定时间段内的每一分钟,更新太阳的位置,并记录未被遮挡的窗户所接收到的日光时数。
  • 动画循环:通过 requestAnimationFrame 实现持续渲染,动态调整太阳位置模拟日升日落过程。

整体代码

以下为完整的实现代码:

<template>
    <div ref="container"></div>
</template>

<script setup>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { ref, onMounted } from 'vue';

const container = ref(null);

onMounted(() => {
    // 初始化场景、相机和渲染器
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 30;
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; 
    container.value.appendChild(renderer.domElement);

    // 添加环境光和方向光
    const ambientLight = new THREE.AmbientLight(0x404040);
    scene.add(ambientLight);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
    directionalLight.castShadow = true;
    directionalLight.shadow.camera.left = -20;
    directionalLight.shadow.camera.right = 20;
    directionalLight.shadow.camera.top = 20;
    directionalLight.shadow.camera.bottom = -20;
    directionalLight.shadow.camera.near = 0.1;
    directionalLight.shadow.camera.far = 50;
    directionalLight.shadow.mapSize.width = 1024;
    directionalLight.shadow.mapSize.height = 1024; 
    scene.add(directionalLight);

    // 控制器
    const controls = new OrbitControls(camera, renderer.domElement);

    // 定义楼层参数
    const floorHeight = 3.3;
    const floorCount = 5;
    const frontBackDistance = 10;
    const leftRightDistance = 7;

    // 创建楼栋函数
    function createBuilding(xOffset, zOffset) {
        const buildingGroup = new THREE.Group();
        for (let i = 0; i < floorCount; i++) {
            // 楼栋
            const buildingGeometry = new THREE.BoxGeometry(5, floorHeight, 3);
            const buildingMaterial = new THREE.MeshPhongMaterial({ color
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值