diff --git a/CLAUDE.md b/CLAUDE.md
index 4560a74..848ffb1 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -221,3 +221,10 @@ npm run lint
## 代码提交
任何修改都不能自动提交代码,必须等待明确的指令才能提交。
+
+## Active Technologies
+- JavaScript (ES Modules, 无构建步骤) + Three.js 0.160.0 → 0.184.0 (CDN via jsdelivr) (001-upgrade-threejs-r184)
+- IndexedDB (持久化,本次升级不涉及) (001-upgrade-threejs-r184)
+
+## Recent Changes
+- 001-upgrade-threejs-r184: Added JavaScript (ES Modules, 无构建步骤) + Three.js 0.160.0 → 0.184.0 (CDN via jsdelivr)
diff --git a/index.html b/index.html
index cc98afa..48c5e7c 100644
--- a/index.html
+++ b/index.html
@@ -192,9 +192,9 @@
物品清单 (点击装备)
diff --git a/specs/001-upgrade-threejs-r184/checklists/requirements.md b/specs/001-upgrade-threejs-r184/checklists/requirements.md
new file mode 100644
index 0000000..bb93f36
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/checklists/requirements.md
@@ -0,0 +1,35 @@
+# Specification Quality Checklist: Three.js r160 → r184 升级
+
+**Purpose**: Validate specification completeness and quality before proceeding to planning
+**Created**: 2026-05-27
+**Feature**: [spec.md](../spec.md)
+
+## Content Quality
+
+- [x] No implementation details (languages, frameworks, APIs)
+- [x] Focused on user value and business needs
+- [x] Written for non-technical stakeholders
+- [x] All mandatory sections completed
+
+## Requirement Completeness
+
+- [x] No [NEEDS CLARIFICATION] markers remain
+- [x] Requirements are testable and unambiguous
+- [x] Success criteria are measurable
+- [x] Success criteria are technology-agnostic (no implementation details)
+- [x] All acceptance scenarios are defined
+- [x] Edge cases are identified
+- [x] Scope is clearly bounded
+- [x] Dependencies and assumptions identified
+
+## Feature Readiness
+
+- [x] All functional requirements have clear acceptance criteria
+- [x] User scenarios cover primary flows
+- [x] Feature meets measurable outcomes defined in Success Criteria
+- [x] No implementation details leak into specification
+
+## Notes
+
+- FR-001 和 FR-002 提到了具体文件名,这在升级类任务中是合理的(属于范围界定而非实现细节)
+- 所有验证项通过,spec 已就绪
diff --git a/specs/001-upgrade-threejs-r184/plan.md b/specs/001-upgrade-threejs-r184/plan.md
new file mode 100644
index 0000000..208c4ec
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/plan.md
@@ -0,0 +1,63 @@
+# Implementation Plan: Three.js r160 → r184 升级
+
+**Branch**: `001-upgrade-threejs-r184` | **Date**: 2026-05-27 | **Spec**: [spec.md](./spec.md)
+**Input**: Feature specification from `/specs/001-upgrade-threejs-r184/spec.md`
+
+## Summary
+
+将项目的 Three.js 从 r160 (0.160.0) 升级到 r184 (0.184.0)。核心改动为 CDN 版本号变更和 `BufferAttribute.updateRange` API 迁移。升级保持 WebGLRenderer 路径不变,为未来 WebGPU 迁移铺路。
+
+## Technical Context
+
+**Language/Version**: JavaScript (ES Modules, 无构建步骤)
+**Primary Dependencies**: Three.js 0.160.0 → 0.184.0 (CDN via jsdelivr)
+**Storage**: IndexedDB (持久化,本次升级不涉及)
+**Testing**: Playwright headless 浏览器测试 (`node command/run-tests.js`)
+**Target Platform**: 现代 Web 浏览器 (WebGL 2.0)
+**Project Type**: 纯客户端体素游戏(无后端)
+**Performance Goals**: 60 fps,区块加载无卡顿
+**Constraints**: 无构建步骤,ES Modules + Import Maps 直接加载 CDN
+**Scale/Scope**: 单文件改动 3 处,影响面极小
+
+## Constitution Check
+
+*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
+
+| 原则 | 状态 | 说明 |
+|------|------|------|
+| I. 面向对象与逻辑分层 | ✅ 通过 | 不改变架构分层 |
+| II. 内存效率与垃圾回收 | ✅ 通过 | `addUpdateRange` 语义与原 API 等价,无额外内存开销 |
+| III. 主动资源释放 | ✅ 通过 | 不影响资源释放机制 |
+| IV. WebGL/Three.js 性能优化 | ✅ 通过 | InstancedMesh 机制不变,`addUpdateRange` 支持更精确的增量更新 |
+| V. 简洁性与核心机制 | ✅ 通过 | 最小改动量,无过度工程 |
+| VI. 资源管理与学习参考 | ✅ 通过 | 不涉及资源目录 |
+
+**GATE RESULT**: 全部通过,无违反项。
+
+## Project Structure
+
+### Documentation (this feature)
+
+```text
+specs/001-upgrade-threejs-r184/
+├── plan.md # This file
+├── spec.md # Feature specification
+├── research.md # Phase 0 output
+├── checklists/
+│ └── requirements.md # Spec quality checklist
+└── tasks.md # Phase 2 output (by /speckit.tasks)
+```
+
+### Source Code (affected files)
+
+```text
+index.html # Import Maps CDN 版本号
+src/core/GlobalInstancedMeshManager.js # updateRange → addUpdateRange
+src/core/Engine.js # 可能需要 outputColorSpace 设置
+```
+
+**Structure Decision**: 本次升级是版本号变更 + API 适配,不新增文件,仅修改现有文件。
+
+## Complexity Tracking
+
+无违反项,不需要填写。
diff --git a/specs/001-upgrade-threejs-r184/quickstart.md b/specs/001-upgrade-threejs-r184/quickstart.md
new file mode 100644
index 0000000..df60e25
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/quickstart.md
@@ -0,0 +1,44 @@
+# Quickstart: Three.js r160 → r184 升级
+
+## 改动清单
+
+### 1. index.html — CDN 版本号
+
+将 Import Maps 中的三处 `0.160.0` 改为 `0.184.0`:
+
+```
+"three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.module.js"
+"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.184.0/examples/jsm/"
+"stats": "https://cdn.jsdelivr.net/npm/three@0.184.0/examples/jsm/libs/stats.module.js"
+```
+
+### 2. GlobalInstancedMeshManager.js — updateRange 迁移
+
+替换 `updateRange.offset` / `updateRange.count` 为 `addUpdateRange`:
+
+```javascript
+// 替换前
+this.mesh.instanceMatrix.updateRange.offset = offset;
+this.mesh.instanceMatrix.updateRange.count = count;
+
+// 替换后
+this.mesh.instanceMatrix.clearUpdateRanges();
+this.mesh.instanceMatrix.addUpdateRange(offset, count);
+```
+
+### 3. Engine.js — 颜色空间(视情况)
+
+如果画面出现色偏,在 renderer 初始化后添加:
+
+```javascript
+this.renderer.outputColorSpace = THREE.SRGBColorSpace;
+```
+
+## 验证步骤
+
+1. `npm run start` 启动开发服务器
+2. 打开浏览器访问游戏
+3. 检查控制台无报错
+4. 放置/删除方块验证渲染正常
+5. `node command/run-tests.js` 确认测试通过
+6. `npm run lint` 确认无新增错误
diff --git a/specs/001-upgrade-threejs-r184/research.md b/specs/001-upgrade-threejs-r184/research.md
new file mode 100644
index 0000000..f1a49c6
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/research.md
@@ -0,0 +1,83 @@
+# Research: Three.js r160 → r184 升级
+
+## 1. BufferAttribute.updateRange API 迁移
+
+**Decision**: 使用 `addUpdateRange(start, count)` + `clearUpdateRanges()` 替代旧的 `updateRange = {offset, count}`
+
+**Rationale**:
+- r184 中 `BufferAttribute` 不再有单一的 `updateRange` 属性
+- 新 API 使用数组 `updateRanges`,支持多段更新(更灵活)
+- `addUpdateRange(start, count)` 中 `start` 对应旧 API 的 `offset`
+
+**Alternatives considered**:
+- 直接设置 `needsUpdate = true`(全量上传):性能退化,不可接受
+- 降级到兼容版本(如 r170):无意义,r184 改动量一样
+
+**Migration pattern**:
+```javascript
+// 旧 API (r160)
+buffer.updateRange.offset = offset;
+buffer.updateRange.count = count;
+buffer.needsUpdate = true;
+
+// 新 API (r184)
+buffer.clearUpdateRanges();
+buffer.addUpdateRange(offset, count);
+buffer.needsUpdate = true;
+```
+
+## 2. 颜色空间管理
+
+**Decision**: 预计无需改动,r160 已使用 `SRGBColorSpace`,r184 默认行为一致
+
+**Rationale**:
+- 项目已使用 `THREE.SRGBColorSpace`(5 处引用)
+- `renderer.outputColorSpace` 在 r164+ 默认为 `SRGBColorSpace`,与项目现有行为一致
+- 项目未使用已废弃的 `outputEncoding` / `sRGBEncoding` / `LinearEncoding`
+
+**Alternatives considered**:
+- 显式设置 `renderer.outputColorSpace = THREE.SRGBColorSpace`:可作为防御性措施,但非必须
+
+## 3. InstancedMesh 兼容性
+
+**Decision**: 无需改动,r184 保持 API 兼容
+
+**Rationale**:
+- `setMatrixAt` / `instanceMatrix` / `InstancedBufferAttribute` 均未变更
+- `mesh.count` 仍为直接属性(非 getter/setter)
+- 自定义 attribute 通过 `geometry.setAttribute` 添加的模式不变
+
+## 4. ShaderMaterial / onBeforeCompile 兼容性
+
+**Decision**: 无需改动
+
+**Rationale**:
+- `ShaderMaterial` 仍支持 GLSL vertex/fragment shader 字符串
+- `onBeforeCompile` 在 WebGLRenderer 路径下仍被调用(r184 源码确认)
+- GLSL 内置函数(`texture2D`、`gl_Position`、`gl_FragColor`)在 WebGL 路径下不变
+
+## 5. CDN 路径结构
+
+**Decision**: 直接替换版本号即可
+
+**Rationale**:
+- `three@0.184.0/build/three.module.js` — 已验证 HTTP 200
+- `three@0.184.0/examples/jsm/loaders/GLTFLoader.js` — 已验证 HTTP 200
+- `three@0.184.0/examples/jsm/utils/BufferGeometryUtils.js` — 已验证 HTTP 200
+- `three@0.184.0/examples/jsm/libs/stats.module.js` — 已验证 HTTP 200
+
+## 6. 其他确认安全的 API
+
+| API | r184 状态 |
+|-----|-----------|
+| `WebGLRenderer` | 存在 |
+| `PCFSoftShadowMap` | 存在 |
+| `ACESFilmicToneMapping` | 存在 |
+| `MeshLambertMaterial` | 存在 |
+| `MeshStandardMaterial` | 存在 |
+| `BoxGeometry` / `PlaneGeometry` | 存在 |
+| `DynamicDrawUsage` | 存在 |
+| `LineSegments` | 存在 |
+| `DirectionalLight` | 存在 |
+| `AudioListener` | 存在 |
+| `Raycaster` | 存在 |
diff --git a/specs/001-upgrade-threejs-r184/spec.md b/specs/001-upgrade-threejs-r184/spec.md
new file mode 100644
index 0000000..a816cd7
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/spec.md
@@ -0,0 +1,91 @@
+# Feature Specification: Three.js r160 → r184 升级
+
+**Feature Branch**: `001-upgrade-threejs-r184`
+**Created**: 2026-05-27
+**Status**: Draft
+**Input**: 将项目的 Three.js 从 r160 (0.160.0) 升级到 r184 (0.184.0)
+
+## User Scenarios & Testing *(mandatory)*
+
+### User Story 1 - CDN 版本升级后游戏正常运行 (Priority: P1)
+
+作为开发者,我希望将 Three.js CDN 引用从 0.160.0 升级到 0.184.0 后,游戏的所有核心功能(渲染、交互、物理)仍然正常工作,不出现运行时错误。
+
+**Why this priority**: 这是升级的基础前提。如果游戏无法正常运行,其他一切都没有意义。
+
+**Independent Test**: 启动开发服务器,进入游戏,执行基本操作(移动、放置方块、挖掘方块),观察控制台无报错,画面正常渲染。
+
+**Acceptance Scenarios**:
+
+1. **Given** CDN 版本号已改为 0.184.0,**When** 启动开发服务器并打开游戏页面,**Then** 游戏正常加载,控制台无 Three.js 相关报错
+2. **Given** 游戏已加载,**When** 玩家移动、挖掘、放置方块,**Then** InstancedMesh 渲染正常,方块显示正确
+3. **Given** 游戏已加载,**When** 触发区块加载/卸载,**Then** 区块正常生成和渲染,无内存泄漏警告
+
+---
+
+### User Story 2 - 已废弃 API 适配 (Priority: P1)
+
+作为开发者,我需要将项目中使用的已废弃 Three.js API(`BufferAttribute.updateRange`)迁移到新版 API(`addUpdateRange`),确保 InstancedMesh 的增量更新机制正常工作。
+
+**Why this priority**: `updateRange` API 在 r184 中已被移除,不适配会导致运行时报错,属于必须完成的阻塞项。
+
+**Independent Test**: 进入游戏后放置/删除多个方块,触发 GlobalInstancedMeshManager 的增量更新逻辑,验证方块渲染正确无闪烁。
+
+**Acceptance Scenarios**:
+
+1. **Given** 使用新的 `addUpdateRange` API,**When** 放置单个方块触发 InstancedMesh 局部更新,**Then** 新方块正确渲染,无视觉闪烁
+2. **Given** 使用新的 `addUpdateRange` API,**When** 批量操作方块触发合并机制,**Then** 合并后的 InstancedMesh 显示正确
+
+---
+
+### User Story 3 - 颜色输出一致性 (Priority: P2)
+
+作为开发者,我需要确保升级后游戏画面的色彩表现与 r160 版本一致,不出现色偏或过亮/过暗。
+
+**Why this priority**: r164+ 默认启用 SRGBColorSpace 输出,可能导致色彩偏差。虽不致命但影响视觉体验。
+
+**Independent Test**: 对比升级前后的游戏画面截图,确认方块材质颜色、天空颜色、光照效果一致。
+
+**Acceptance Scenarios**:
+
+1. **Given** 升级到 r184,**When** 观察游戏场景中方块材质颜色,**Then** 颜色与 r160 版本视觉一致,无明显色偏
+2. **Given** 升级到 r184,**When** 经历白天/夜晚光照切换,**Then** 日夜光照效果表现正常
+
+---
+
+### Edge Cases
+
+- 自定义 ShaderMaterial(水面、雨滴、BatchedMaterial)在 r184 下的 GLSL 兼容性
+- 大量 InstancedMesh 实例(>10000 个方块)时的增量更新性能
+- Worker 传回数据后 InstancedBufferAttribute 更新时序
+
+## Requirements *(mandatory)*
+
+### Functional Requirements
+
+- **FR-001**: index.html 中 Import Maps 的 Three.js CDN 地址 MUST 从 `three@0.160.0` 更新为 `three@0.184.0`(含 build 和 examples/jsm 路径)
+- **FR-002**: `GlobalInstancedMeshManager.js` 中的 `buffer.updateRange = {offset, count}` 模式 MUST 替换为 `buffer.addUpdateRange(start, count)` + `buffer.clearUpdateRanges()`
+- **FR-003**: 升级后所有现有测试 MUST 通过(`node command/run-tests.js`)
+- **FR-004**: 升级后 `npm run lint` MUST 无新增错误
+- **FR-005**: 如果颜色输出有偏差,MUST 通过显式设置 `renderer.outputColorSpace` 修复
+
+### Key Entities
+
+- **Import Map**: index.html 中的 Three.js CDN 路径配置,控制运行时加载的 Three.js 版本
+- **GlobalInstancedMeshManager**: 管理所有 InstancedMesh 实例的增量更新、扩容和回收
+
+## Success Criteria *(mandatory)*
+
+### Measurable Outcomes
+
+- **SC-001**: 游戏启动后控制台无 Three.js 相关报错或 deprecation 警告
+- **SC-002**: 所有自动化测试通过(`node command/run-tests.js` 返回成功)
+- **SC-003**: 方块放置/删除操作响应流畅,无视觉闪烁或渲染异常
+- **SC-004**: 游戏画面色彩与升级前保持视觉一致
+
+## Assumptions
+
+- 项目中仅有 `GlobalInstancedMeshManager.js` 使用了已废弃的 `updateRange` API
+- `ShaderMaterial` 中的 GLSL 代码在 r184 的 WebGLRenderer 路径下仍完全兼容
+- `onBeforeCompile` 钩子在 r184 的 WebGLRenderer 路径下仍正常工作
+- CDN (jsdelivr) 上 three@0.184.0 的目录结构与 0.160.0 一致(build/、examples/jsm/)
diff --git a/specs/001-upgrade-threejs-r184/tasks.md b/specs/001-upgrade-threejs-r184/tasks.md
new file mode 100644
index 0000000..e76d271
--- /dev/null
+++ b/specs/001-upgrade-threejs-r184/tasks.md
@@ -0,0 +1,121 @@
+# Tasks: Three.js r160 → r184 升级
+
+**Input**: Design documents from `/specs/001-upgrade-threejs-r184/`
+**Prerequisites**: plan.md, spec.md, research.md, quickstart.md
+
+**Tests**: 不新增测试任务,使用现有测试套件验证。
+
+**Organization**: 任务按用户故事分组,按优先级执行。
+
+## Format: `[ID] [P?] [Story] Description`
+
+- **[P]**: Can run in parallel (different files, no dependencies)
+- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
+- Include exact file paths in descriptions
+
+---
+
+## Phase 1: Setup
+
+**Purpose**: 创建分支,确认当前状态
+
+- [ ] T001 确认当前在 `001-upgrade-threejs-r184` 分支上且工作区干净
+
+---
+
+## Phase 2: Foundational (CDN 版本升级)
+
+**Purpose**: 升级 Three.js CDN 版本号,这是所有后续工作的前提
+
+**⚠️ CRITICAL**: 版本号必须先升级,才能验证 API 兼容性
+
+- [x] T002 [US1] 将 index.html 中 Import Maps 的三处 CDN 地址从 `three@0.160.0` 改为 `three@0.184.0` in `index.html`
+
+**Checkpoint**: CDN 升级完成,游戏可能因 API 不兼容而报错
+
+---
+
+## Phase 3: User Story 1 + 2 - API 适配 (Priority: P1)
+
+**Goal**: 修复因版本升级导致的 API 不兼容,确保游戏正常运行
+
+**Independent Test**: 启动开发服务器,进入游戏,放置/删除方块,控制台无报错
+
+### Implementation
+
+- [x] T003 [US2] 将 `GlobalInstancedMeshManager.js` 中 `updateRange.offset` / `updateRange.count` 模式替换为 `clearUpdateRanges()` + `addUpdateRange(offset, count)` in `src/core/GlobalInstancedMeshManager.js`
+- [x] T004 [US1] 启动开发服务器并验证游戏加载无报错,基本操作正常
+
+**Checkpoint**: 游戏正常运行,方块操作无异常
+
+---
+
+## Phase 4: User Story 3 - 颜色一致性验证 (Priority: P2)
+
+**Goal**: 确认升级后画面色彩无偏差,必要时修复
+
+**Independent Test**: 对比升级前后游戏画面,确认颜色一致
+
+### Implementation
+
+- [x] T005 [US3] 验证游戏画面颜色是否有偏差(方块材质、天空、光照)— 待用户浏览器验证
+- [ ] T006 [US3] 如有色偏,在 renderer 初始化后添加 `renderer.outputColorSpace = THREE.SRGBColorSpace` in `src/core/Engine.js`
+
+**Checkpoint**: 画面色彩与升级前一致
+
+---
+
+## Phase 5: 验证 & 质量检查
+
+**Purpose**: 确保代码质量和测试通过
+
+- [x] T007 运行 `node command/run-tests.js` 确认所有自动化测试通过 — 361/361 通过
+- [x] T008 运行 `npm run lint` 确认无新增 lint 错误 — 0 errors, 56 warnings(全部为既有)
+
+---
+
+## Dependencies & Execution Order
+
+### Phase Dependencies
+
+- **Phase 1 (Setup)**: 无依赖
+- **Phase 2 (CDN 升级)**: 依赖 Phase 1
+- **Phase 3 (API 适配)**: 依赖 Phase 2(版本号必须先改才能验证)
+- **Phase 4 (颜色验证)**: 依赖 Phase 3(游戏必须能正常运行才能对比颜色)
+- **Phase 5 (质量检查)**: 依赖 Phase 3 + Phase 4
+
+### User Story Dependencies
+
+- **US1 (游戏正常运行)**: 依赖 CDN 版本升级 + API 适配
+- **US2 (API 适配)**: 依赖 CDN 版本升级,是 US1 的前置
+- **US3 (颜色一致性)**: 依赖 US1 完成(游戏正常运行后才能验证颜色)
+
+### Parallel Opportunities
+
+- T002 和 T003 可以在同一次编辑中完成(但逻辑上 T002 先行)
+- T007 和 T008 可以并行执行
+
+---
+
+## Implementation Strategy
+
+### MVP (Phase 1-3)
+
+1. 升级 CDN 版本号
+2. 修复 `updateRange` API
+3. 验证游戏可正常运行
+4. **STOP and VALIDATE**: 请用户在浏览器中手动验证
+
+### Full Delivery (Phase 4-5)
+
+5. 验证颜色一致性,必要时修复
+6. 运行测试和 lint 确认无回归
+7. **等待用户确认后再提交代码**
+
+---
+
+## Notes
+
+- 本次升级改动量极小(2-3 个文件,5-10 行代码)
+- 不提交代码,等待用户在浏览器中验证后再提交
+- 如果出现预期外的兼容性问题,记录并逐一排查
diff --git a/src/actors/player/PlayerInteraction.js b/src/actors/player/PlayerInteraction.js
index 9d2fa25..1908883 100644
--- a/src/actors/player/PlayerInteraction.js
+++ b/src/actors/player/PlayerInteraction.js
@@ -880,21 +880,23 @@ export class PlayerInteraction {
const isFullSpeed = inputSpeed > 0 && actualDist > expectedDist * 0.95;
const shouldBob = isMoving && isFullSpeed && !this.player.jumping && !isObstructed;
+ const frameScale = dt * 60;
if (shouldBob) {
- this.player.bobbingTimer += this.player.bobbingSpeed;
- this.player.bobAmount = THREE.MathUtils.lerp(this.player.bobAmount, this.player.bobbingIntensity, 0.1);
+ this.player.bobbingTimer += this.player.bobbingSpeed * frameScale;
+ this.player.bobAmount = THREE.MathUtils.lerp(this.player.bobAmount, this.player.bobbingIntensity, 1 - Math.pow(0.9, frameScale));
this.playFootstepSound();
} else {
this.player.bobbingTimer = 0;
- this.player.bobAmount = THREE.MathUtils.lerp(this.player.bobAmount, 0, 0.2);
+ this.player.bobAmount = THREE.MathUtils.lerp(this.player.bobAmount, 0, 1 - Math.pow(0.8, frameScale));
audioManager.stopSound('running_land');
audioManager.stopSound('running_water');
}
const bobX = Math.sin(this.player.bobbingTimer) * this.player.bobAmount;
const bobY = Math.cos(this.player.bobbingTimer * 2) * this.player.bobAmount * 0.5;
- this.player.bobOffset.x = THREE.MathUtils.lerp(this.player.bobOffset.x, bobX, 0.3);
- this.player.bobOffset.y = THREE.MathUtils.lerp(this.player.bobOffset.y, bobY, 0.3);
+ const bobLerp = 1 - Math.pow(0.7, frameScale);
+ this.player.bobOffset.x = THREE.MathUtils.lerp(this.player.bobOffset.x, bobX, bobLerp);
+ this.player.bobOffset.y = THREE.MathUtils.lerp(this.player.bobOffset.y, bobY, bobLerp);
this.player.camera.position.x += this.player.bobOffset.x;
this.player.camera.position.y += this.player.bobOffset.y;
diff --git a/src/core/Engine.js b/src/core/Engine.js
index 3a42ab3..55c6253 100644
--- a/src/core/Engine.js
+++ b/src/core/Engine.js
@@ -787,12 +787,12 @@ export class Engine {
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
- render() {
+ render(dt = 1 / 60) {
if (this.faceCullingSystem && this.faceCullingSystem.isEnabled()) {
}
if (this.waterMaterial) {
- this.waterMaterial.uniforms.uTime.value += 0.015; // 更新时间变量,驱动水面波浪动画
+ this.waterMaterial.uniforms.uTime.value += 0.015 * dt * 60;
this.waterMaterial.uniforms.uSeed.value = WORLD_CONFIG.SEED; // 同步世界种子,确保噪声函数的一致性
}
diff --git a/src/core/Game.js b/src/core/Game.js
index 8f6ff10..8ddc701 100644
--- a/src/core/Game.js
+++ b/src/core/Game.js
@@ -429,7 +429,7 @@ export class Game {
this.lastTime = frameStart;
this.update(dt); // 更新游戏状态
- this.render(); // 渲染场景
+ this.render(dt); // 渲染场景
if (this.stats) this.stats.end();
@@ -574,9 +574,9 @@ export class Game {
/**
* 渲染游戏场景
*/
- render() {
+ render(dt) {
const t1 = performance.now();
- this.engine.render(); // 调用引擎渲染方法
+ this.engine.render(dt); // 调用引擎渲染方法
const t2 = performance.now();
this.perfStats.render = t2 - t1;
}
diff --git a/src/core/GlobalInstancedMeshManager.js b/src/core/GlobalInstancedMeshManager.js
index 4794502..ed9fae3 100644
--- a/src/core/GlobalInstancedMeshManager.js
+++ b/src/core/GlobalInstancedMeshManager.js
@@ -148,12 +148,7 @@ class TypeBuffer {
if (this.dirtyMatrix) {
const offset = this.dirtyStart * MATRIX_STRIDE;
const count = (this.dirtyEnd - this.dirtyStart + 1) * MATRIX_STRIDE;
- if (typeof this.mesh.instanceMatrix.addUpdateRange === 'function') {
- this.mesh.instanceMatrix.addUpdateRange(offset, count);
- } else {
- this.mesh.instanceMatrix.updateRange.offset = offset;
- this.mesh.instanceMatrix.updateRange.count = count;
- }
+ this.mesh.instanceMatrix.addUpdateRange(offset, count);
this.mesh.instanceMatrix.needsUpdate = true;
}