vtj-resource-management

star 144

Loads and manages 3D assets via the Resources system. Use when adding models, textures, or fonts; declare in sources.js and access via core:ready event.

hexianWeb By hexianWeb schedule Updated 2/2/2026

name: vtj-resource-management description: Loads and manages 3D assets via the Resources system. Use when adding models, textures, or fonts; declare in sources.js and access via core:ready event.

vite-threejs Resource Management

Overview

所有资源(模型、纹理、字体等)通过 Resources 类统一加载。资源在 sources.js 中声明,加载完成后通过 this.experience.resources.items 访问。

核心原则:在 sources.js 声明,通过 items 访问,在 core:ready 事件后使用。

When to Use

  • 添加新模型(GLB/GLTF/FBX/OBJ)
  • 添加新纹理(PNG/JPG/HDR/EXR/KTX2)
  • 添加字体、音频、视频等资源
  • 需要等待资源加载完成后执行逻辑

资源声明 (sources.js)

所有资源在 src/js/sources.js 中统一声明:

// src/js/sources.js
export default [
  {
    name: 'playerModel',        // 资源名称(用于访问)
    type: 'gltfModel',          // 资源类型
    path: 'models/character/player.glb',  // 相对于 public/ 的路径
  },
  {
    name: 'grass_block_top_texture',
    type: 'texture',
    path: 'textures/blocks/grass_block_top.png',
  },
  // ...
]

支持的资源类型

type 加载器 用途 示例路径
gltfModel GLTFLoader GLB/GLTF 模型 models/xxx.glb
fbxModel FBXLoader FBX 模型 models/xxx.fbx
objModel OBJLoader OBJ 模型 models/xxx.obj
texture TextureLoader 普通纹理 textures/xxx.png
hdrTexture RGBELoader HDR 环境贴图 textures/xxx.hdr
exrTexture EXRLoader EXR 高动态范围 textures/xxx.exr
ktx2Texture KTX2Loader KTX2 压缩纹理 textures/xxx.ktx2
cubeTexture CubeTextureLoader 立方体贴图 ['px.jpg', 'nx.jpg', ...]
font FontLoader 字体文件 fonts/xxx.json
audio AudioLoader 音频文件 audio/xxx.mp3
svg SVGLoader SVG 文件 images/xxx.svg
video VideoTexture 视频纹理 videos/xxx.mp4

访问已加载资源

// 在组件中访问资源
constructor() {
  this.experience = new Experience()
  this.resources = this.experience.resources
}

// 通过 items[name] 访问
const texture = this.resources.items['grass_block_top_texture']
const model = this.resources.items['playerModel']

GLTF 模型结构

const gltf = this.resources.items['playerModel']

// 完整 GLTF 对象
gltf.scene        // THREE.Group - 场景根节点
gltf.animations   // AnimationClip[] - 动画列表
gltf.cameras      // Camera[] - 相机(如有)
gltf.asset        // 元数据

// 添加到场景
this.scene.add(gltf.scene)

// 克隆模型(多实例)
const clone = gltf.scene.clone()

纹理配置

const texture = this.resources.items['grass_block_top_texture']

// 常见纹理配置
texture.colorSpace = THREE.SRGBColorSpace  // 颜色空间
texture.wrapS = THREE.RepeatWrapping       // 水平重复
texture.wrapT = THREE.RepeatWrapping       // 垂直重复
texture.minFilter = THREE.NearestFilter    // 像素风格
texture.magFilter = THREE.NearestFilter
texture.generateMipmaps = false            // 像素风格关闭 mipmap

等待资源加载完成

资源全部加载完成后触发 core:ready 事件:

import emitter from './utils/event-bus.js'

// 在需要等待资源的地方
emitter.on('core:ready', () => {
  // 此时所有资源已加载完成
  this.initWithResources()
})

典型模式:World 初始化

// src/js/world/world.js
export default class World {
  constructor() {
    this.experience = new Experience()
    this.resources = this.experience.resources

    // 等待资源加载完成
    emitter.on('core:ready', () => {
      // 初始化需要资源的组件
      this.player = new Player()
      this.environment = new Environment()
      this.chunkManager = new ChunkManager()
    })
  }
}

添加新资源步骤

1. 放置文件

public/
├── models/
│   └── character/
│       └── my-model.glb      ← 新模型
├── textures/
│   └── blocks/
│       └── my-texture.png    ← 新纹理

2. 声明资源

// src/js/sources.js
export default [
  // ... 现有资源
  
  // 添加新资源
  {
    name: 'myModel',
    type: 'gltfModel',
    path: 'models/character/my-model.glb',
  },
  {
    name: 'myTexture',
    type: 'texture',
    path: 'textures/blocks/my-texture.png',
  },
]

3. 使用资源

// 在组件中(确保在 core:ready 后)
const model = this.resources.items['myModel']
const texture = this.resources.items['myTexture']

资源命名规范

类型 命名模式 示例
模型 xxxModel playerModel, steveModel
纹理 xxx_texture 或描述性 grass_block_top_texture, dirt
HDR xxxHDRTexture environmentMapHDRTexture
天空盒 sky_xxxTexture sky_sunriseTexture
植物 xxx_plant_Texture dandelion_plant_Texture
破坏阶段 destroy_stage_N destroy_stage_0 ~ destroy_stage_9

加载进度

// Resources 提供加载进度
this.resources.loadProgress  // 0.0 ~ 1.0
this.resources.isLoaded      // boolean
this.resources.loaded        // 已加载数量
this.resources.toLoad        // 总数量

Common Mistakes

❌ 在 core:ready 之前访问资源

// BAD: 构造函数中直接访问(资源可能未加载)
constructor() {
  this.model = this.resources.items['playerModel']  // ❌ 可能是 undefined
}

// GOOD: 在 core:ready 回调中访问
constructor() {
  emitter.on('core:ready', () => {
    this.model = this.resources.items['playerModel']  // ✅
  })
}

❌ 忘记在 sources.js 声明

// BAD: 直接使用加载器(绕过资源系统)
const loader = new GLTFLoader()
loader.load('models/xxx.glb', (gltf) => { ... })

// GOOD: 在 sources.js 声明
// sources.js
{ name: 'xxx', type: 'gltfModel', path: 'models/xxx.glb' }

// 组件中
const gltf = this.resources.items['xxx']

❌ 资源名称拼写错误

// BAD: 名称不匹配
// sources.js 中是 'playerModel'
const model = this.resources.items['player_model']  // ❌ undefined

// GOOD: 名称完全一致
const model = this.resources.items['playerModel']   // ✅

❌ 路径不以 public/ 为根

// BAD: 使用绝对路径或 src/ 路径
{ path: '/public/models/xxx.glb' }     // ❌
{ path: 'src/assets/models/xxx.glb' }  // ❌

// GOOD: 相对于 public/ 目录
{ path: 'models/xxx.glb' }             // ✅

❌ 忘记配置像素风格纹理

// BAD: 模糊的像素纹理(Minecraft 风格需要锐利边缘)
const texture = this.resources.items['grass']
// 使用默认 filter,导致模糊

// GOOD: 配置 NearestFilter
const texture = this.resources.items['grass']
texture.minFilter = THREE.NearestFilter
texture.magFilter = THREE.NearestFilter
texture.generateMipmaps = false

Quick Reference

操作 代码
声明资源 sources.js: { name, type, path }
访问资源 this.resources.items['name']
等待加载 emitter.on('core:ready', () => {})
检查进度 this.resources.loadProgress
GLTF 场景 gltf.scene
GLTF 动画 gltf.animations
资源类型 type 值
GLB/GLTF gltfModel
普通纹理 texture
HDR hdrTexture
字体 font
音频 audio
Install via CLI
npx skills add https://github.com/hexianWeb/Third-Person-MC --skill vtj-resource-management
Repository Details
star Stars 144
call_split Forks 37
navigation Branch main
article Path SKILL.md
More from Creator