基于three.js的室内全景3D展馆案例分享

  • 先看效果图
    • 实现了第一人称行走,WASD
    • 点击目标画册进行预览查看
    • 位置音乐播放环绕
    • 地面镜面反光
    • 碰撞检测等等.

地址在gitee上gallery: 数字展馆概念的demo项目,本项目中使用的技术栈为three.js

有兴趣的伙伴可以去下载看看,有这方面的项目应该能受很大启发。

import Core from "../core";

import Environment from "../environment";

import Character from "../character";

import Css3DRenderer from "../css3DRenderer";

import Audio from "../audio";

import RayCasterControls from "../rayCasterControls";

import {ON_CLICK_RAY_CAST, ON_HIDE_TOOLTIP, ON_LOAD_MODEL_FINISH, ON_LOAD_PROGRESS, ON_ENTER_APP, ON_SHOW_TOOLTIP} from "../Constants";

import {Object3D} from "three";

export default class World {

private core: Core;

private environment: Environment;

private character: Character;

private css_3d_renderer: Css3DRenderer;

private audio: Audio;

private ray_caster_controls: RayCasterControls;

constructor() {

this.core = new Core();

this.core.$on(ON_LOAD_PROGRESS, this._handleLoadProgress.bind(this));

this.core.$on(ON_LOAD_MODEL_FINISH, this._onLoadModelFinish.bind(this));

this.core.$on(ON_CLICK_RAY_CAST, this._onClickRayCast.bind(this));

this.core.$on(ON_SHOW_TOOLTIP, this._onShowTooltip.bind(this));

this.core.$on(ON_HIDE_TOOLTIP, this._onHideTooltip.bind(this));

this.core.$on(ON_ENTER_APP, this._onEnterApp.bind(this));

this.environment = new Environment();

this.character = new Character({speed: 12});

this.css_3d_renderer = new Css3DRenderer();

this.audio = new Audio();

this.ray_caster_controls = new RayCasterControls();

}

update(delta: number) {

if (this.environment.collider && this.environment.is_load_finished) {

this.css_3d_renderer.update();

this.character.update(delta, this.environment.collider);

this.ray_caster_controls.updateTooltipRayCast(this.environment.raycast_objects);

}

}

/*

* 点击进入展馆后的回调

* */

private _onEnterApp() {

this.audio.playAudio();

// 进入后才允许控制键盘

this.core.control_manage.enabled();

}

private async _onLoadModelFinish() {

// 场景模型加载完毕后开始加载音频

await this.audio.createAudio();

// 音频加载完毕后移除加载进度UI,显示进入确认UI

this.core.ui.removeLoading();

this.core.ui.showLoadingConfirm();

// 场景模型加载完毕后将场景中需要光线投射检测的物体传入给rayCasterControls

this.ray_caster_controls.bindClickRayCastObj(this.environment.raycast_objects);

}

private _handleLoadProgress({url, loaded, total}: {url: string, loaded: number, total: number}) {

const percentage = ((loaded / total) * 100).toFixed(2);

if (/.*\.(blob|glb)$/i.test(url)) {

this.core.ui.updateLoadingProgress(`{url.includes("collision") ? "加载碰撞场景模型" : "加载其他场景模型"}:{percentage}%`);

}

if (/.*\.(jpg|png|jpeg)$/i.test(url)) {

this.core.ui.updateLoadingProgress("加载图片素材中...");

}

if (/.*\.(m4a|mp3)$/i.test(url)) {

this.core.ui.updateLoadingProgress("加载声音资源中...");

}

}

private _onClickRayCast(object: object: Object3D) {

this.core.ui.showBoardsBox(

object.userData.title,

object.userData.author,

object.userData.describe,

object.userData.src,

);

}

private _onShowTooltip({msg, show_preview_tips}: { msg: string, show_preview_tips: boolean }) {

this.core.ui.showPreviewTooltip(msg, show_preview_tips);

}

private _onHideTooltip() {

this.core.ui.hidePreviewTooltip();

}

}

相关推荐
Jmyd01237 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
半个落月7 小时前
LangChain Agent 中间件实战(上):生命周期、状态、短路与工具包
javascript·langchain
LiuPig刘皮哥7 小时前
2026年开源3D陪玩对比:xiaoke.ai、AIRI、Open-LLM-VTuber、Amica 有什么、没有什么
人工智能·3d·开源
半个落月7 小时前
LangChain Agent 中间件实战(下):DeepAgents文件权限、长期记忆与对话摘要
javascript·langchain
程序猿追8 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓8 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播8 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
墨云安全9 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
u0111026759 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
摇滚侠9 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记