GameMcu 原神启动 工程项目分析

5 分钟阅读
threejs

视频:【超还原!three.js复刻原神启动,网页就能玩】

github: https://github.com/gamemcu/www-genshin


原神启动项目技术分析

1. 项目概述

这是一个基于 Three.js 开发的原神登录界面复刻项目,使用 React + TypeScript + Vite 作为主要技术栈。项目通过 WebGL 技术重现了原神游戏的登录场景效果。

2. 技术分析

核心技术

  • 前端框架: React
  • 开发语言: TypeScript
  • 构建工具: Vite
  • 3D 渲染: Three.js/WebGL
  • 样式处理: Less
  • 动画处理: TWEEN.js

项目结构

www-genshin/
├── src/
│   ├── core/           # 核心逻辑
│   │   ├── components/ # 3D组件
│   │   └── datas/     # 场景数据
│   ├── libs/          # 工具库
│   ├── pages/         # 页面组件
│   └── shader/        # 着色器
├── public/            # 静态资源
└── index.html         # 入口文件

启动流程分析

flowchart TD
    A[index.html] --> B[main.tsx]
    B --> C[App.tsx]
    C --> D{是否加载中?}
    D -->|是| E[显示Preloader]
    D -->|否| F[显示Menu]
    
    E --> G[GameManager预加载]
    G --> H[加载场景组件]
    H --> I[加载完成触发preloaded事件]
    I --> J[设置loading为false]
    J --> F
    
    subgraph 场景组件
        K[Cloud/云]
        L[Light/光照]
        M[Road/道路]
        N[PolarLight/极光]
        O[BigCloud/大云]
    end
    
    F --> P[等待用户交互]
    P --> Q[开始游戏动画]
    Q --> R[相机移动]
    R --> S[显示门特效]
  1. 从 index.html 作为入口,加载 main.tsx
  2. App.tsx 作为主组件被渲染,包含三个主要部分:Canvas、Preloader 和 Menu
  3. 初始时 loading 为 true,显示 Preloader 组件
  4. GameManager 负责资源预加载和游戏状态管理
  5. 预加载完成后,触发 "preloaded" 事件,loading 设为 false
  6. 显示 Menu 组件,等待用户交互
  7. 场景中包含多个组件如云、光照、道路等,它们都继承自 Component 基类

核心代码分析

  • GameManager.ts
class TaskManager {
    private _taskCount: number = 0;
    private _taskFinished: number = 0;
    private _resolve: Promise<void> = Promise.resolve();
    private _progress: number = 0;

    // 获取加载进度
    public get progress() {
        return this._progress;
    }

    // 任务管理方法
    public task(handle: Function | Promise<any>, props = {}) {
        // ... 任务处理逻辑
    }
}

class GameManager extends EventEmitter {
    private taskManger = new TaskManager();
    
    // 重启游戏
    public restart() {
        window.location.href = 'https://www.bilibili.com/video/BV1E8411v7xy'
    }

    // 添加任务
    public task(handle: Function | Promise<any>, props = {}) {
        return this.taskManger.task(handle, props);
    }
}

// 导出单例
export const gameManager = new GameManager();

GameManager的主要职责是:

  1. 资源预加载管理:
  • 通过TaskManager来管理所有需要加载的资源
  • 提供progress属性来追踪加载进度
  • 提供task()方法来添加新的加载任务
  1. 游戏状态管理:
  • 继承自EventEmitter,可以发布/订阅游戏中的各种事件
  • 提供restart()等游戏控制方法

3. 核心功能实现

class Main {
    constructor() {
        // 初始化渲染器
        this.renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true
        });
        
        // 初始化场景
        this.scene = new THREE.Scene();
        
        // 初始化资源加载器
        this.loader = new ResourceLoader();
        
        // 开始加载流程
        this.init();
    }

    async init() {
        // 显示加载界面
        this.showLoadingScreen();
        
        // 开始预加载资源
        await this.loader.preload();
        
        // 初始化场景
        this.initScene();
        
        // 开始渲染循环
        this.startRenderLoop();
    }
}
  1. 场景渲染系统
  • 使用自定义的 xviewer.js 封装了 Three.js 的场景管理
  • 实现了组件化的场景对象管理系统
  • 支持材质、光照等效果的实时调整
  1. 云层效果
  • 通过 Cloud.ts 和 BigCloud.ts 实现两层云效果
  • 使用实例化渲染(Instance Rendering)优化性能
  • 云层数据通过 CloudList.ts 配置化管理
  1. 光照系统
// 环境光
AmbientLightComponent
// 平行光
DirectionalLightComponent
// 极光效果
PolarLight
  1. 特效处理
  • 使用自定义 Shader 实现各种视觉效果
  • 实现了 ACES 色调映射
  • 支持 Bloom 效果的过渡动画
  1. 场景动画
  • 使用 TWEEN.js 处理动画过渡
  • 实现了镜头移动、门开启等动画效果
  • 支持动画链式调用和时间线控制

4. 性能优化

  1. 实例化渲染
  • 云层使用 InstancedMesh 减少 DrawCall
  • 通过 Matrix4 优化实例变换计算
  1. 着色器优化
  • 自定义 Shader 实现高效的视觉效果
  • 使用 uniform 变量减少 GPU 数据传输
  1. 资源管理
  • 使用 .gitignore 合理管理项目文件
  • 静态资源优化加载策略

5. 项目特点

  1. 模块化设计 组件化的场景管理
  2. 可配置性
  • 场景数据外部配置
  • 材质参数可调整
  1. 性能优化
  • 使用多种优化技术
  • 注重渲染效率
  1. 代码质量
  • 使用 TypeScript 保证代码质量
  • 完善的类型定义和接口设计

6. 技术难点

  1. 云层渲染性能优化
  2. 光照效果的真实还原
  3. 场景动画的流畅过渡
  4. Shader 效果的实现
  5. 大规模实例化渲染的管理

7. 总结

该项目展示了现代 Web 3D 技术的应用能力,通过合理的架构设计和优化策略,成功实现了原神登录界面的还原。项目代码组织清晰,具有较好的可维护性和扩展性。