@realsee/five 6.8.0-alpha.7 → 6.8.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/ai_guides/README.md +5 -3
  2. package/ai_guides/api.md +10 -0
  3. package/ai_guides/features/flowing-light-2d-pass.md +278 -58
  4. package/ai_guides/features/flowing-light-3d-pass.md +223 -43
  5. package/ai_guides/features/load-external-model.md +4 -1
  6. package/ai_guides/features/pano-uv.md +131 -0
  7. package/ai_guides/release_notes/6.8.md +24 -15
  8. package/docs/assets/hierarchy.js +1 -1
  9. package/docs/assets/navigation.js +1 -1
  10. package/docs/assets/search.js +1 -1
  11. package/docs/classes/five.AdaptiveLuminancePass.html +1 -1
  12. package/docs/classes/five.BoundingMesh.html +1 -1
  13. package/docs/classes/five.Camera.html +1 -1
  14. package/docs/classes/five.EyeDomeLightingPass.html +1 -1
  15. package/docs/classes/five.Five.html +1 -1
  16. package/docs/classes/five.FivePass.html +1 -1
  17. package/docs/classes/five.InternalWebGLRenderer.html +1 -1
  18. package/docs/classes/five.Model.html +1 -1
  19. package/docs/classes/five.ModelScene.html +1 -1
  20. package/docs/classes/five.NetworkSubscribe.html +1 -1
  21. package/docs/classes/five.PBMContainer.html +1 -1
  22. package/docs/classes/five.PBMGSObject.html +1 -1
  23. package/docs/classes/five.PBMGroup.html +1 -1
  24. package/docs/classes/five.PBMMesh.html +1 -1
  25. package/docs/classes/five.PBMMeshMaterial.html +15 -6
  26. package/docs/classes/five.PBMPointCloud.html +1 -1
  27. package/docs/classes/five.PBMPointCloudMaterial.html +1 -1
  28. package/docs/classes/five.PBMSkinnedMesh.html +1 -1
  29. package/docs/classes/five.PanoCircleMesh.html +1 -1
  30. package/docs/classes/five.PanoCircleMeshCustom.html +1 -1
  31. package/docs/classes/five.PanoCircleMeshSolid.html +1 -1
  32. package/docs/classes/five.Parameter.html +1 -1
  33. package/docs/classes/five.Scene.html +1 -1
  34. package/docs/classes/five.Subscribe.html +1 -1
  35. package/docs/classes/five.Tile3D.html +1 -1
  36. package/docs/classes/five.TileNode.html +1 -1
  37. package/docs/classes/five.TrajectoryNode.html +1 -1
  38. package/docs/classes/five.WorkResolvedObserver.html +1 -1
  39. package/docs/classes/gltf-loader.DDSLoader.html +1 -1
  40. package/docs/classes/gltf-loader.DRACOLoader.html +1 -1
  41. package/docs/classes/gltf-loader.GLTFLoader.html +1 -1
  42. package/docs/classes/gltf-loader.GLTFObject.html +1 -1
  43. package/docs/classes/gltf-loader.THREEGLTFLoader.html +1 -1
  44. package/docs/classes/line.Line.html +1 -1
  45. package/docs/classes/line.LineGeometry.html +1 -1
  46. package/docs/classes/line.LineMaterial.html +1 -1
  47. package/docs/classes/line.LineSegmentsGeometry.html +1 -1
  48. package/docs/classes/line.THREE_Line2.html +1 -1
  49. package/docs/classes/line.THREE_LineSegments2.html +1 -1
  50. package/docs/classes/plugins.BasePlugin.Controller.html +1 -1
  51. package/docs/classes/plugins.RoundedBoxGeometry.html +1 -1
  52. package/docs/classes/sticker.Sticker.html +1 -1
  53. package/docs/classes/vfx.Airflow.html +1 -1
  54. package/docs/classes/vfx.Flame.html +1 -1
  55. package/docs/classes/vfx.Particle.html +1 -1
  56. package/docs/classes/vfx.ParticleGPU.html +1 -1
  57. package/docs/classes/vfx.SpotLight.html +1 -1
  58. package/docs/documents/README.html +4 -3
  59. package/docs/documents/api.html +1 -1
  60. package/docs/documents/{features_coordnate-system.html → features_coordinate-system.html} +1 -1
  61. package/docs/documents/features_flowing-light-2d-pass.html +275 -43
  62. package/docs/documents/features_flowing-light-3d-pass.html +268 -46
  63. package/docs/documents/features_load-external-model.html +4 -1
  64. package/docs/documents/features_pano-uv.html +82 -0
  65. package/docs/documents/release_notes_6.8.html +29 -18
  66. package/docs/functions/five.loadGltf.html +1 -1
  67. package/docs/hierarchy.html +1 -1
  68. package/docs/index.html +4 -3
  69. package/docs/interfaces/five.AddableObject.html +1 -1
  70. package/docs/interfaces/five.AjaxOptions.html +1 -1
  71. package/docs/interfaces/five.BaseEvent.html +1 -1
  72. package/docs/interfaces/five.EventCallback.html +1 -1
  73. package/docs/interfaces/five.GestureEvent.html +1 -1
  74. package/docs/interfaces/five.ImageOptions.html +1 -1
  75. package/docs/interfaces/five.IntersectEvent.html +1 -1
  76. package/docs/interfaces/five.IntersectMesh.html +1 -1
  77. package/docs/interfaces/five.IntersectMeshInterface.html +1 -1
  78. package/docs/interfaces/five.Intersection.html +1 -1
  79. package/docs/interfaces/five.LooseWorkWithExtrinsics.html +1 -1
  80. package/docs/interfaces/five.ModeChangeEvent.html +1 -1
  81. package/docs/interfaces/five.ModelControllerCustomInitArgs.html +1 -1
  82. package/docs/interfaces/five.ModelEvent.html +1 -1
  83. package/docs/interfaces/five.ModelSceneEvent.html +1 -1
  84. package/docs/interfaces/five.ModelTileEvent.html +1 -1
  85. package/docs/interfaces/five.MovePanoOptions.html +1 -1
  86. package/docs/interfaces/five.NetworkAbortError.html +1 -1
  87. package/docs/interfaces/five.NetworkFirbiddenError.html +1 -1
  88. package/docs/interfaces/five.NetworkOptions.html +1 -1
  89. package/docs/interfaces/five.NetworkProxyError.html +1 -1
  90. package/docs/interfaces/five.NetworkResourceEvent.html +1 -1
  91. package/docs/interfaces/five.NetworkResponseError.html +1 -1
  92. package/docs/interfaces/five.NetworkTimeoutError.html +1 -1
  93. package/docs/interfaces/five.ObjectEvent.html +1 -1
  94. package/docs/interfaces/five.PBMMaterial.html +1 -1
  95. package/docs/interfaces/five.PBMMeshMaterialParameters.html +1 -1
  96. package/docs/interfaces/five.PBMPointCloudMaterialParameters.html +1 -1
  97. package/docs/interfaces/five.PanoCircleMeshInterface.html +1 -1
  98. package/docs/interfaces/five.PanoEvent.html +1 -1
  99. package/docs/interfaces/five.PanoTextureEvent.html +1 -1
  100. package/docs/interfaces/five.PanoramaControllerCustomInitArgs.html +1 -1
  101. package/docs/interfaces/five.PanoramaLikeControllerCustomInitArgs.html +1 -1
  102. package/docs/interfaces/five.ParameterMaterialValue.html +1 -1
  103. package/docs/interfaces/five.ParameterTilesetValue.html +1 -1
  104. package/docs/interfaces/five.ParameterValue.html +1 -1
  105. package/docs/interfaces/five.Pose.html +1 -1
  106. package/docs/interfaces/five.RenderEvent.html +1 -1
  107. package/docs/interfaces/five.ResolvedParameterValue.html +1 -1
  108. package/docs/interfaces/five.State.html +1 -1
  109. package/docs/interfaces/five.StateEvent.html +1 -1
  110. package/docs/interfaces/five.TextureOptions.html +1 -1
  111. package/docs/interfaces/five.TopviewControllerCustomInitArgs.html +1 -1
  112. package/docs/interfaces/five.VRPanoramaControllerCustomInitArgs.html +1 -1
  113. package/docs/interfaces/five.ViewLayer.html +1 -1
  114. package/docs/interfaces/five.WorkCubeImage.html +1 -1
  115. package/docs/interfaces/five.WorkImage.html +1 -1
  116. package/docs/interfaces/five.WorkObserver.html +1 -1
  117. package/docs/interfaces/five.WorkTile.html +1 -1
  118. package/docs/interfaces/five.WorksEvent.html +1 -1
  119. package/docs/interfaces/five.XRControllerEvent.html +1 -1
  120. package/docs/interfaces/five.XRGestureEvent.html +1 -1
  121. package/docs/interfaces/five.XRPanoramaControllerCustomInitArgs.html +1 -1
  122. package/docs/interfaces/five.XRSessionEvent.html +1 -1
  123. package/docs/interfaces/plugins.BackgroundPluginController.html +1 -1
  124. package/docs/interfaces/plugins.BackgroundPluginType.EventMap.html +1 -1
  125. package/docs/interfaces/plugins.BasePlugin.State.html +1 -1
  126. package/docs/interfaces/plugins.DynamicPathLinePluginController.html +1 -1
  127. package/docs/interfaces/plugins.DynamicPathLinePluginType.EventMap.html +1 -1
  128. package/docs/interfaces/plugins.DynamicPathLinePluginType.State.html +1 -1
  129. package/docs/interfaces/plugins.ItemMaskController.html +1 -1
  130. package/docs/interfaces/plugins.ItemMaskPluginType.EventMap.html +1 -1
  131. package/docs/interfaces/plugins.ItemMaskPluginType.State.html +1 -1
  132. package/docs/interfaces/plugins.OrientationPluginController.html +1 -1
  133. package/docs/interfaces/plugins.OrientationPluginType.EventMap.html +1 -1
  134. package/docs/interfaces/plugins.OrientationPluginType.State.html +1 -1
  135. package/docs/interfaces/plugins.PanoAnimeController.html +1 -1
  136. package/docs/interfaces/plugins.PanoAnimePluginType.EventMap.html +1 -1
  137. package/docs/interfaces/plugins.PanoAnimePluginType.State.html +1 -1
  138. package/docs/interfaces/plugins.PluginTemplateType.EventMap.html +1 -1
  139. package/docs/interfaces/plugins.PluginTemplateType.State.html +1 -1
  140. package/docs/interfaces/plugins.TrajectoryController.html +1 -1
  141. package/docs/interfaces/react.FiveInjectionTypes.html +1 -1
  142. package/docs/modules.html +1 -1
  143. package/docs/types/five.ParseOptions.html +1 -1
  144. package/docs/types/plugins.BasePlugin.EventMap.html +1 -1
  145. package/five/index.js +417 -383
  146. package/five/index.mjs +4465 -4322
  147. package/five/model/loaders/glTF-helpers/extensions/CESIUM_RTC.d.ts +1 -1
  148. package/five/model/loaders/glTF-helpers/extensions/EXT_meshopt_compression.d.ts +1 -1
  149. package/five/model/loaders/glTF-helpers/extensions/EXT_texture_webp.d.ts +1 -1
  150. package/five/model/loaders/glTF-helpers/extensions/KHR_binary_glTF.d.ts +1 -1
  151. package/five/model/loaders/glTF-helpers/extensions/KHR_draco_mesh_compression.d.ts +1 -1
  152. package/five/model/loaders/glTF-helpers/extensions/KHR_gaussian_splatting_compression_spz.d.ts +1 -1
  153. package/five/model/loaders/glTF-helpers/extensions/KHR_materials_clearcoat.d.ts +10 -0
  154. package/five/model/loaders/glTF-helpers/extensions/KHR_materials_emissive_strength.d.ts +10 -0
  155. package/five/model/loaders/glTF-helpers/extensions/KHR_materials_sheen.d.ts +10 -0
  156. package/five/model/loaders/glTF-helpers/extensions/KHR_materials_transmission.d.ts +10 -0
  157. package/five/model/loaders/glTF-helpers/extensions/KHR_materials_unlit.d.ts +4 -0
  158. package/five/model/loaders/glTF-helpers/extensions/KHR_node_visibility.d.ts +4 -0
  159. package/five/model/loaders/glTF-helpers/extensions/KHR_texture_basisu.d.ts +1 -1
  160. package/five/model/loaders/glTF-helpers/extensions/KHR_texture_transform.d.ts +1 -1
  161. package/five/model/loaders/glTF-helpers/extensions/REALSEE_materials_lightmap.d.ts +1 -1
  162. package/five/model/loaders/glTF-helpers/extensions/base.d.ts +2 -1
  163. package/five/model/loaders/glTF-helpers/glTF.d.ts +20 -1
  164. package/five/model/loaders/glTF-helpers/index.d.ts +8 -2
  165. package/five/model/loaders/glTF-helpers/parser.d.ts +14 -13
  166. package/five/model/loaders/gltf.d.ts +1 -0
  167. package/five/model/materials/pbmMeshMaterial.d.ts +9 -0
  168. package/five/renderer/postprocessing/passes/flowing-light-2d-pass.d.ts +16 -2
  169. package/five/renderer/postprocessing/passes/flowing-light-3d-pass.d.ts +16 -2
  170. package/five/renderer/postprocessing/passes/gaussian-blur-pass.d.ts +1 -1
  171. package/gltf-loader/index.js +3 -3
  172. package/gltf-loader/index.mjs +3 -3
  173. package/line/index.js +3 -3
  174. package/line/index.mjs +3 -3
  175. package/llms.txt +5 -3
  176. package/package.json +1 -1
  177. package/plugins/index.js +2 -2
  178. package/plugins/index.mjs +2 -2
  179. package/react/index.js +2 -2
  180. package/react/index.mjs +2 -2
  181. package/shader-lib/index.js +2 -2
  182. package/shader-lib/index.mjs +2 -2
  183. package/sticker/index.js +3 -3
  184. package/sticker/index.mjs +3 -3
  185. package/umd/five-gltf-loader.js +3 -3
  186. package/umd/five-line.js +3 -3
  187. package/umd/five-plugins.js +2 -2
  188. package/umd/five-react.js +2 -2
  189. package/umd/five-shader-lib.js +2 -2
  190. package/umd/five-sticker.js +3 -3
  191. package/umd/five-vfx.js +2 -2
  192. package/umd/five-vue.js +2 -2
  193. package/umd/five.js +417 -383
  194. package/vfx/index.js +2 -2
  195. package/vfx/index.mjs +2 -2
  196. package/vue/index.js +2 -2
  197. package/vue/index.mjs +2 -2
  198. package/work-downloader/index.js +2 -2
  199. package/work-downloader/index.mjs +2 -2
  200. package/five/model/loaders/glTF-helpers/extensions/PBM_mesh.d.ts +0 -11
  201. /package/ai_guides/features/{coordnate-system.md → coordinate-system.md} +0 -0
@@ -1,16 +1,16 @@
1
1
  # Flowing Light 3D Pass (流光 3D 通道)
2
2
 
3
- - **Summary**: `FlowingLight3DPass` 基于 3D 世界坐标绘制流光效果,自动投影到屏幕空间,适合沿模型表面、路径或空间轨迹演示动态流动光带。
3
+ - **Summary**: `FlowingLight3DPass` 基于 3D 世界坐标绘制流光效果,使用 InstancedMesh 实例化渲染优化性能,自动投影到屏幕空间,适合沿模型表面、路径或空间轨迹演示动态流动光带。
4
4
  - **Schema**: `FlowingLight3DPass` 类及 Line 数据结构。
5
- - **Concepts**: 基于相机投影的 3D 光带、世界坐标到屏幕坐标映射、动画驱动。
6
- - **Configuration**: 3D 路径点、颜色、不透明度、动画周期。
7
- - **Examples**: 空间轨迹演示、结合相机动画、多条 3D 路径。
5
+ - **Concepts**: 基于相机投影的 3D 光带、InstancedMesh 实例化渲染、世界坐标到屏幕坐标映射、头尾追逐动画。
6
+ - **Configuration**: 3D 路径点、颜色、不透明度、线宽、动画周期、延迟。
7
+ - **Examples**: 空间轨迹演示、结合相机动画、多条 3D 路径、高 DPR 场景优化。
8
8
 
9
9
  ## Schema
10
10
 
11
11
  > **Definition**: [FlowingLight3DPass](../../five/renderer/postprocessing/passes/flowing-light-3d-pass.d.ts)
12
12
 
13
- `FlowingLight3DPass` 继承自 `FivePass`,支持投影到当前相机视锥。核心接口如下:
13
+ `FlowingLight3DPass` 继承自 `FivePass`,支持投影到当前相机视锥。核心接口如下:
14
14
 
15
15
  ```ts
16
16
  import * as THREE from 'three';
@@ -18,11 +18,15 @@ import { FivePass } from './pass';
18
18
  import { type Camera } from '../../../core/camera';
19
19
 
20
20
  type Line = {
21
+ id?: string; // 可选的唯一标识符,不传则自动生成 UUID
21
22
  points: THREE.Vector3[]; // 世界坐标系路径点
22
- totalLength: number; // 路径总长度(世界单位)
23
+ totalLength: number; // 路径总长度(世界单位)
23
24
  color: THREE.Color; // 光带颜色
24
- opacity?: number; // 光带不透明度(0-1
25
- duration?: number; // 动画周期(毫秒)
25
+ opacity?: number; // 光带不透明度(0-1)
26
+ duration?: number; // 动画周期(毫秒)
27
+ delay?: number; // 动画延迟(毫秒)
28
+ lineWidth?: number; // 线宽(像素)
29
+ tailLengthRatio?: number; // 尾巴长度比例(0-1),默认 0.2
26
30
  };
27
31
 
28
32
  export class FlowingLight3DPass extends FivePass {
@@ -31,6 +35,9 @@ export class FlowingLight3DPass extends FivePass {
31
35
  // 设置要渲染的路径列表
32
36
  public setLines(lines: Line[]): void;
33
37
 
38
+ // 修改单条线的参数(通过 id)
39
+ public setLine(params: { id: string } & Partial<Omit<Line, 'id'>>): void;
40
+
34
41
  public render(
35
42
  renderer: THREE.WebGLRenderer,
36
43
  writeBuffer: THREE.WebGLRenderTarget,
@@ -42,17 +49,28 @@ export class FlowingLight3DPass extends FivePass {
42
49
  public dispose(): void;
43
50
  }
44
51
  ```
45
-
46
52
  ## Concepts
47
53
 
54
+ ### InstancedMesh 实例化渲染 (Instanced Rendering)
55
+ 为了优化高 DPR(Device Pixel Ratio)场景下的性能,该 Pass 使用 InstancedMesh 代替全屏着色器。每个线段作为一个实例,只渲染线段覆盖的区域,避免了对每个像素的全屏检查,显著提升了渲染效率。
56
+
48
57
  ### 世界空间路径与投影 (World-space Projection)
49
- 路径点定义在 3D 世界坐标系中。Pass 内部自动根据当前相机投影矩阵将 3D 点映射到屏幕空间,从而实现"随相机变化"的动态光带效果。
58
+ 路径点定义在 3D 世界坐标系中。Pass 内部自动根据当前相机投影矩阵将 3D 点映射到屏幕空间,从而实现"随相机变化"的动态光带效果。
50
59
 
51
- ### 循环流动 (Looping Flow)
52
- 默认使用循环模式(`LOOP = true`),光头在路径上循环流动,无起点/终点的区分。尾部长度为路径总长的 1/4。
60
+ ### 头尾追逐动画 (Head-Tail Chase Animation)
61
+ 流光效果采用"头尾追逐"模式:
62
+ - **头部(Head)**: 光流的前端,沿路径循环移动
63
+ - **尾部(Tail)**: 光流的后端,跟随头部移动
64
+ - **渐变**: 从尾部(透明度 0)到头部(透明度 1)线性渐变
65
+ - **尾长**: 尾部长度由 `tailLengthRatio` 参数控制(默认 0.2,即路径总长的 20%)
66
+
67
+ 光头在路径上循环流动,通过 `gl_FragCoord` 投影到线段上计算每个像素的渐变位置,确保渐变效果准确。尾巴长度会在动画开始时逐渐增长,直到达到 `tailLengthRatio * totalLength`。
53
68
 
54
69
  ### 相机同步
55
- Pass 自动同步相机的投影矩阵和视图矩阵,无需手动管理。支持相机运动时光带跟随。
70
+ Pass 自动同步相机的投影矩阵和视图矩阵,无需手动管理。支持相机运动时光带跟随。
71
+
72
+ ### DPR 处理
73
+ 自动处理高 DPR 场景,渲染目标尺寸根据 `readBuffer` 自动调整,确保在 Retina 等高分辨率屏幕上位置准确且性能优化。
56
74
 
57
75
  ## Configuration
58
76
 
@@ -60,25 +78,32 @@ Pass 自动同步相机的投影矩阵和视图矩阵,无需手动管理。支
60
78
 
61
79
  | Parameter | Type | Required | Default | Description |
62
80
  | :--- | :--- | :--- | :--- | :--- |
81
+ | `id` | `string` | | 自动生成 UUID | 唯一标识符,用于 `setLine` 方法更新单条线。 |
63
82
  | `points` | `THREE.Vector3[]` | ✓ | - | 世界坐标系路径点数组。至少 2 个点。 |
64
- | `totalLength` | `number` | ✓ | - | 路径总长度(世界单位)。通常为所有相邻点间距离之和。 |
65
- | `color` | `THREE.Color` | ✓ | - | 光带颜色(RGB)。 |
66
- | `opacity` | `number` | | `1` | 光带不透明度(0-1)。控制与背景的混合强度。 |
67
- | `duration` | `number` | | `1000` | 动画周期(毫秒)。光头完成一个循环所需时长。 |
83
+ | `totalLength` | `number` | ✓ | - | 路径总长度(世界单位)。通常为所有相邻点间距离之和。 |
84
+ | `color` | `THREE.Color` | ✓ | - | 光带颜色(RGB)。 |
85
+ | `opacity` | `number` | | `1.0` | 光带不透明度(0-1)。控制与背景的混合强度。 |
86
+ | `duration` | `number` | | `1000` | 动画周期(毫秒)。光头完成一个循环所需时长。 |
87
+ | `delay` | `number` | | `0` | 动画延迟(毫秒)。延迟后才开始播放动画。 |
88
+ | `lineWidth` | `number` | | `3.0` | 线宽(像素)。控制光带在屏幕上的宽度。 |
89
+ | `tailLengthRatio` | `number` | | `0.2` | 尾巴长度比例(0-1)。控制流光尾巴相对于路径总长的比例。 |
68
90
 
69
- > **注意**: `totalLength` 应为世界坐标单位。若不准确,流速会偏差。
91
+ > **注意**: `totalLength` 应为世界坐标单位。若不准确,流速会偏差。
70
92
 
71
93
  ## Instance Methods
72
94
 
73
95
  ### `constructor(camera: Camera)`
74
- 初始化 Pass,需传入相机以获取投影矩阵和视图矩阵。
96
+ 初始化 Pass,需传入相机以获取投影矩阵和视图矩阵。
75
97
 
76
98
  ### `setLines(lines: Line[])`
77
99
  更新要渲染的路径列表。支持运行时动态更改。
78
100
 
79
- **示例**:
101
+ **自动生成 ID**: 如果 line 没有提供 `id`,会自动生成 UUID。
102
+
103
+ **示例**:
80
104
  ```ts
81
105
  const pathLine: Line = {
106
+ id: 'my-3d-line', // 可选,不传则自动生成
82
107
  points: [
83
108
  new THREE.Vector3(0, 0, 0),
84
109
  new THREE.Vector3(5, 2, 3),
@@ -88,21 +113,74 @@ const pathLine: Line = {
88
113
  color: new THREE.Color(0xff6600),
89
114
  opacity: 0.85,
90
115
  duration: 3000,
116
+ delay: 500,
117
+ lineWidth: 4.0,
91
118
  };
92
119
  pass.setLines([pathLine]);
93
120
  ```
94
121
 
122
+ ### `setLine(params: { id: string } & Partial<Omit<Line, 'id'>>)`
123
+ 通过 `id` 修改单条线的参数。支持部分更新,只更新传入的字段。
124
+
125
+ **性能优化**:
126
+ - 如果 `points` 数量不变,只更新 GPU 的 instance attributes,性能极高
127
+ - 如果 `points` 数量改变,会重建整个 mesh,性能开销较大
128
+
129
+ **示例**:
130
+ ```ts
131
+ // 只修改颜色 - 高性能
132
+ pass.setLine({
133
+ id: 'my-3d-line',
134
+ color: new THREE.Color(0xff0000),
135
+ });
136
+
137
+ // 修改多个属性 - 高性能
138
+ pass.setLine({
139
+ id: 'my-3d-line',
140
+ color: new THREE.Color(0x00ff00),
141
+ opacity: 0.5,
142
+ duration: 3000,
143
+ lineWidth: 5.0,
144
+ });
145
+
146
+ // 修改 points (相同数量) - 高性能
147
+ pass.setLine({
148
+ id: 'my-3d-line',
149
+ points: [
150
+ new THREE.Vector3(0, 0, 0),
151
+ new THREE.Vector3(6, 3, 4),
152
+ new THREE.Vector3(12, 2, 8),
153
+ ], // 仍是 3 个点
154
+ totalLength: 15,
155
+ });
156
+
157
+ // 修改 points (不同数量) - 会重建 mesh
158
+ pass.setLine({
159
+ id: 'my-3d-line',
160
+ points: [
161
+ new THREE.Vector3(0, 0, 0),
162
+ new THREE.Vector3(10, 5, 5),
163
+ ], // 从 3 个点变为 2 个点
164
+ totalLength: 12,
165
+ });
166
+ ```
167
+
168
+ **注意事项**:
169
+ - 如果 `id` 不存在,会在控制台输出警告
170
+ - 动画时间(`uTime`)不会被重置,流光继续从当前位置播放
171
+ - 建议修改 `points` 时同时更新 `totalLength`
172
+
95
173
  ### `render(...)`
96
- 由 EffectComposer 自动调用,无需手动调用。自动同步相机矩阵。
174
+ 由 EffectComposer 自动调用,无需手动调用。自动同步相机矩阵和渲染目标尺寸。
97
175
 
98
176
  ### `dispose()`
99
- 释放着色材质和数据纹理资源,销毁 Pass 时必须调用。
177
+ 释放 InstancedMesh、着色材质和渲染目标资源,销毁 Pass 时必须调用。
100
178
 
101
179
  ## Examples
102
180
 
103
181
  ### 快速上手 (Quick Example)
104
182
 
105
- ```ts
183
+
106
184
  import { Five } from '@realsee/five';
107
185
  import { FlowingLight3DPass } from '../../lib/five/renderer/postprocessing';
108
186
  import * as THREE from 'three';
@@ -112,7 +190,7 @@ const five = new Five();
112
190
  // 创建 3D 流光通道
113
191
  const flowing3D = new FlowingLight3DPass(five.camera);
114
192
 
115
- // 定义一条 3D 路径(世界坐标)
193
+ // 定义一条 3D 路径(世界坐标)
116
194
  const path = [
117
195
  new THREE.Vector3(-5, 0, 0),
118
196
  new THREE.Vector3(-2, 3, 2),
@@ -127,6 +205,7 @@ flowing3D.setLines([{
127
205
  color: new THREE.Color(0x00ff88),
128
206
  opacity: 0.8,
129
207
  duration: 4000,
208
+ lineWidth: 3.0,
130
209
  }]);
131
210
 
132
211
  five.addPass(flowing3D);
@@ -136,11 +215,11 @@ function animate() {
136
215
  five.render();
137
216
  }
138
217
  animate();
139
- ```
218
+
140
219
 
141
220
  ### 多条 3D 路径
142
221
 
143
- ```ts
222
+
144
223
  const pass = new FlowingLight3DPass(camera);
145
224
 
146
225
  const paths = [
@@ -152,6 +231,7 @@ const paths = [
152
231
  totalLength: 11,
153
232
  color: new THREE.Color(0xff0000),
154
233
  duration: 2000,
234
+ lineWidth: 3.0,
155
235
  },
156
236
  {
157
237
  points: [
@@ -161,6 +241,8 @@ const paths = [
161
241
  totalLength: 12,
162
242
  color: new THREE.Color(0x00ff00),
163
243
  duration: 2500,
244
+ delay: 500,
245
+ lineWidth: 4.0,
164
246
  },
165
247
  {
166
248
  points: [
@@ -170,15 +252,17 @@ const paths = [
170
252
  totalLength: 11,
171
253
  color: new THREE.Color(0x0000ff),
172
254
  duration: 2200,
255
+ delay: 1000,
256
+ lineWidth: 2.5,
173
257
  },
174
258
  ];
175
259
 
176
260
  pass.setLines(paths);
177
- ```
261
+
178
262
 
179
263
  ### 计算 3D 路径长度
180
264
 
181
- ```ts
265
+
182
266
  function calculatePath3DLength(points: THREE.Vector3[]): number {
183
267
  let length = 0;
184
268
  for (let i = 1; i < points.length; i++) {
@@ -187,25 +271,37 @@ function calculatePath3DLength(points: THREE.Vector3[]): number {
187
271
  return length;
188
272
  }
189
273
 
274
+ const points = [
275
+ new THREE.Vector3(0, 0, 0),
276
+ new THREE.Vector3(5, 2, 3),
277
+ new THREE.Vector3(10, 1, 6),
278
+ ];
279
+
190
280
  const pathLine = {
191
- points: [...],
281
+ points: points,
192
282
  totalLength: calculatePath3DLength(points),
193
283
  color: new THREE.Color(0x00ccff),
194
284
  duration: 3000,
285
+ lineWidth: 3.0,
195
286
  };
196
- ```
287
+
197
288
 
198
289
  ### 结合相机动画
199
290
 
200
- ```ts
291
+
201
292
  // 光带路径随相机移动自动投影
202
293
  const pass = new FlowingLight3DPass(camera);
203
294
 
204
295
  pass.setLines([{
205
- points: [...],
296
+ points: [
297
+ new THREE.Vector3(-10, 0, 0),
298
+ new THREE.Vector3(0, 5, 0),
299
+ new THREE.Vector3(10, 0, 0),
300
+ ],
206
301
  totalLength: 20,
207
302
  color: new THREE.Color(0xffff00),
208
303
  duration: 3000,
304
+ lineWidth: 4.0,
209
305
  }]);
210
306
 
211
307
  // 相机动画过程中光带自动跟随投影
@@ -213,20 +309,105 @@ five.setState({
213
309
  mode: Five.Mode.Model,
214
310
  // ... 其他参数
215
311
  });
216
- ```
312
+
313
+
314
+ ### 高 DPR 场景优化
315
+
316
+
317
+ // InstancedMesh 实现自动优化高 DPR 性能
318
+ // 在 DPR=2 的 Retina 屏幕上,性能显著优于全屏着色器方案
319
+
320
+ const pass = new FlowingLight3DPass(camera);
321
+
322
+ // 多条路径在高 DPR 下仍能保持流畅
323
+ const paths = Array.from({ length: 10 }, (_, i) => ({
324
+ points: [
325
+ new THREE.Vector3(i * 2, 0, 0),
326
+ new THREE.Vector3(i * 2, 5, 5),
327
+ ],
328
+ totalLength: 7,
329
+ color: new THREE.Color(Math.random() * 0xffffff),
330
+ duration: 2000 + i * 100,
331
+ delay: i * 200,
332
+ lineWidth: 3.0,
333
+ }));
334
+
335
+ pass.setLines(paths);
336
+
217
337
 
218
338
  ## Debugging
219
339
 
220
- - **光带不可见**:检查路径点是否在相机视锥内;验证 `color` 和 `opacity` 非全透明。
221
- - **光带抖动或消失**:确认路径在相机背面时自动丢弃(3D 投影的预期行为)。
222
- - **流速不对**:检查 `totalLength` 计算是否为世界单位;调整 `duration` 以改变流速。
340
+ - **光带不可见**: 检查路径点是否在相机视锥内;验证 `color` 和 `opacity` 非全透明。
341
+ - **光带抖动或消失**: 确认路径在相机背面时自动丢弃(3D 投影的预期行为)。
342
+ - **流速不对**: 检查 `totalLength` 计算是否为世界单位;调整 `duration` 以改变流速。
343
+ - **位置偏移**: 确认在高 DPR 场景下渲染目标尺寸正确,Pass 会自动同步 `readBuffer` 尺寸。
344
+ - **性能问题**: InstancedMesh 实现已优化,但过多路径点仍会影响性能。建议单条路径不超过 20 个点。
345
+
346
+ ## Performance
347
+
348
+ ### 与全屏着色器对比
349
+ - **全屏着色器**: 每帧检查所有像素,DPR=2 时像素数增加 4 倍,性能下降明显
350
+ - **InstancedMesh**: 仅渲染线段覆盖区域,DPR=2 时性能影响较小
351
+ - **实测**: 在 DPR=2 场景下,InstancedMesh 方案 FPS 提升约 3-5 倍
352
+
353
+ ### setLine 性能优化
354
+ `setLine` 方法根据修改类型自动选择最优更新策略:
355
+
356
+ | 修改类型 | 性能 | 说明 |
357
+ |---------|------|------|
358
+ | 只修改颜色/透明度 | ⚡️ 极快 (~100x) | 只更新 instanceColor attribute |
359
+ | 只修改 duration/delay | ⚡️ 极快 (~100x) | 只更新 instanceMeta attribute |
360
+ | 只修改 lineWidth | ⚡️ 极快 (~100x) | 只更新 instanceData attribute |
361
+ | 修改 points (相同数量) | ⚡️ 快 (~50x) | 只更新 instanceStart/End attributes |
362
+ | 修改 points (不同数量) | ⚠️ 慢 | 重建整个 mesh |
363
+
364
+ **最佳实践**:
365
+ ```ts
366
+ // ✅ 高性能 - 频繁修改颜色
367
+ requestAnimationFrame(() => {
368
+ pass.setLine({
369
+ id: lineId,
370
+ color: new THREE.Color(Math.random(), Math.random(), Math.random())
371
+ });
372
+ });
373
+
374
+ // ✅ 高性能 - 动画路径(保持点数)
375
+ function animatePath(t: number) {
376
+ pass.setLine({
377
+ id: lineId,
378
+ points: [
379
+ new THREE.Vector3(0, 0, 0),
380
+ new THREE.Vector3(5 + Math.sin(t) * 2, 2, 3),
381
+ new THREE.Vector3(10, 0, 0),
382
+ ] // 始终 3 个点
383
+ });
384
+ }
385
+
386
+ // ⚠️ 低性能 - 避免频繁改变点数
387
+ setInterval(() => {
388
+ const pointCount = Math.floor(Math.random() * 5) + 2;
389
+ pass.setLine({
390
+ id: lineId,
391
+ points: generateRandomPoints(pointCount) // 点数不固定
392
+ });
393
+ }, 100);
394
+ ```
395
+
396
+ ### 优化建议
397
+ 1. 减少路径点数量,使用更简化的路径
398
+ 2. 降低 `lineWidth`,减少渲染区域
399
+ 3. 控制同时渲染的路径数量
400
+ 4. 使用 `setLine` 而非 `setLines` 来更新单条线
401
+ 5. 保持 points 数量不变,只修改坐标
402
+ 6. 在低端设备上可通过 `pass.enabled = false` 禁用
223
403
 
224
404
  ## Common Pitfalls
225
405
 
226
- 1. **totalLength 单位混淆**:必须使用世界坐标单位,不能混用屏幕像素或其他单位。
227
- 2. **投影失败**:确保相机矩阵有效,相机在构造时已初始化。
228
- 3. **路径在背面**:相机背后的点自动投影到屏幕外,无需手动处理。
229
- 4. **未调用 dispose()**:销毁 Pass 时必须调用 `dispose()`,避免 GPU 资源泄漏。
406
+ 1. **totalLength 单位混淆**: 必须使用世界坐标单位,不能混用屏幕像素或其他单位。
407
+ 2. **投影失败**: 确保相机矩阵有效,相机在构造时已初始化。
408
+ 3. **路径在背面**: 相机背后的点自动投影到屏幕外,无需手动处理。
409
+ 4. **未调用 dispose()**: 销毁 Pass 时必须调用 `dispose()`,避免 GPU 资源泄漏。
410
+ 5. **DPR 不匹配**: 确保渲染目标尺寸与实际屏幕 DPR 匹配,Pass 会自动处理。
230
411
 
231
412
  ## Related
232
413
 
@@ -235,6 +416,5 @@ five.setState({
235
416
 
236
417
  ---
237
418
 
238
- ```yaml
239
- tags: [postprocessing, effect, flowing, light, pass, rendering, worldspace, projection]
240
- ```
419
+
420
+ tags: [postprocessing, effect, flowing, light, pass, rendering, worldspace, projection, instanced, performance]
@@ -71,10 +71,13 @@ Five 使用 **Z-up** (Z 轴向上) 的右手坐标系。
71
71
  * `KHR_node_visibility`
72
72
  * `KHR_animation_pointer`
73
73
  * `EXT_meshopt_compression`
74
+ * `KHR_materials_clearcoat`
75
+ * `KHR_materials_sheen`
76
+ * `KHR_materials_transmission`
77
+ * `KHR_materials_emissive_strength`
74
78
  * `EXT_texture_webp`
75
79
  * `CESIUM_RTC`
76
80
  * `REALSEE_materials_lightmap`
77
- * `PBM_mesh`
78
81
  * `KHR_gaussian_splatting_compression_spz`
79
82
 
80
83
  | 参数 | 类型 | 默认值 | 说明 |
@@ -0,0 +1,131 @@
1
+ # 全景图 UV 与方向转换 (Panorama UV Conversion)
2
+
3
+ - **Summary**: 提供了一组工具方法,用于在**全景图 UV 坐标** (Equirectangular UV / Cubemap UV) 与**三维空间方向向量** (Vector3) 之间进行转换。
4
+ - **Schema**: 依赖 `WorkObserver` 实例,提供四个核心转换方法。
5
+ - **Concepts**: Equirectangular Projection, Cubemap Projection, UV Origin, Coordinate Systems.
6
+ - **Configuration**: `uvOrigin` (UV 原点设置).
7
+ - **Examples**: 向量转全景 UV、UV 转向量、Cubemap 转换。
8
+
9
+ ## Schema
10
+
11
+ > **Definition**: [WorkObserver](../../five/work/work.d.ts)
12
+
13
+ 这些方法挂载在 `WorkObserver` 实例上,依赖当前观察点 (Observer) 的位姿信息 (Position & Quaternion) 以及 `work.transform` 进行计算。
14
+
15
+ ```typescript
16
+ interface WorkObserver {
17
+ /**
18
+ * 将方向向量转化为全景图 uv
19
+ * @param vector - 全局方向向量 (World Space)
20
+ * @param uvOrigin - UV 原点位置,默认为 'top-left'
21
+ */
22
+ vectorToEquirectangularUv(vector: THREE.Vector3, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector2;
23
+
24
+ /**
25
+ * 将全景图 uv 转化为方向向量
26
+ * @param uv - 全景图 UV 坐标 [0, 1]
27
+ * @param uvOrigin - UV 原点位置,默认为 'top-left'
28
+ */
29
+ equirectangularUvToVector(uv: THREE.Vector2, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector3;
30
+
31
+ /**
32
+ * 将方向向量转化为六视图 uv
33
+ * @param vector - 全局方向向量 (World Space)
34
+ * @param uvOrigin - UV 原点位置,默认为 'top-left'
35
+ */
36
+ vectorToCubemapUv(vector: THREE.Vector3, uvOrigin?: 'top-left' | 'bottom-left'): [cubeFace: CubeFace, cubemapUv: THREE.Vector2];
37
+
38
+ /**
39
+ * 将六视图 uv 转化为方向向量
40
+ * @param cubeFace - 立方体面 ('up' | 'down' | 'left' | 'right' | 'front' | 'back')
41
+ * @param uv - 该面上的 UV 坐标 [0, 1]
42
+ * @param uvOrigin - UV 原点位置,默认为 'top-left'
43
+ */
44
+ cubemapUvToVector(cubeFace: CubeFace, uv: THREE.Vector2, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector3;
45
+ }
46
+
47
+ type CubeFace = 'up' | 'down' | 'left' | 'right' | 'front' | 'back';
48
+ ```
49
+
50
+ ## Concepts
51
+
52
+ ### 1. 坐标系转换 (Coordinate Transformation)
53
+ 转换过程会自动处理以下坐标空间的变换:
54
+ 1. **World Space (世界坐标系)**: `vector` 参数所处的坐标系。
55
+ 2. **Work Space (Work 坐标系)**: 考虑 `work.transform` 带来的整体旋转。
56
+ 3. **Observer Space (观察者坐标系)**: 考虑 `observer.quaternion` 带来的观察点旋转。
57
+ 4. **Panorama Space (全景图空间)**: 最终映射到 2D 图片上的 UV 坐标。
58
+
59
+ ### 2. 投影方式 (Projection Types)
60
+ * **Equirectangular (等距柱状投影)**: 将球体展开为 2:1 的矩形图片。常用于全景图预览。
61
+ * **Cubemap (立方体贴图)**: 将球体投影到立方体的六个面上。常用于高清全景浏览。
62
+
63
+ ### 3. UV 原点 (UV Origin)
64
+ * **top-left (默认)**: 原点 `(0, 0)` 在图片**左上角**。U 轴向右,V 轴向下。符合大多数 Web 图片处理习惯 (Canvas, DOM)。
65
+ * **bottom-left**: 原点 `(0, 0)` 在图片**左下角**。U 轴向右,V 轴向上。符合 WebGL / OpenGL 纹理坐标习惯。
66
+
67
+ ## Configuration
68
+
69
+ 所有方法均包含可选参数 `uvOrigin`。
70
+
71
+ ### Common Configuration
72
+
73
+ | Parameter | Type | Default | Description |
74
+ | :--- | :--- | :--- | :--- |
75
+ | `uvOrigin` | `'top-left' \| 'bottom-left'` | `'top-left'` | 指定 UV 坐标系的原点位置。 |
76
+
77
+ ## Examples
78
+
79
+ ### 1. 点击全景图获取空间方向 (Click to Vector)
80
+ 假设你有一个全景图的点击事件,获取到了点击位置的 UV:
81
+
82
+ ```typescript
83
+ const observer = five.work.observers[0];
84
+ // 假设这是用户点击全景图后归一化得到的 UV (0~1)
85
+ const clickUv = new THREE.Vector2(0.5, 0.5);
86
+
87
+ // 转换为世界空间的方向向量
88
+ const direction = observer.equirectangularUvToVector(clickUv);
89
+
90
+ console.log('点击方向:', direction);
91
+ ```
92
+
93
+ ### 2. 将空间点映射到全景图上 (World Point to UV)
94
+ 假设场景中有一个 3D 物体,你想知道它在当前全景图上的位置(例如打标签):
95
+
96
+ ```typescript
97
+ const observer = five.work.observers[0];
98
+ const objectPosition = new THREE.Vector3(10, 2, 5);
99
+
100
+ // 计算物体相对于观察点的方向向量
101
+ const direction = objectPosition.clone().sub(observer.position).normalize();
102
+
103
+ // 获取全景图 UV
104
+ const uv = observer.vectorToEquirectangularUv(direction);
105
+
106
+ console.log(`物体在全景图上的位置: u=${uv.x}, v=${uv.y}`);
107
+ ```
108
+
109
+ ### 3. 处理 Cubemap 坐标 (Cubemap Conversion)
110
+ 如果你使用的是六面体全景图资源:
111
+
112
+ ```typescript
113
+ const observer = five.work.observers[0];
114
+ const direction = new THREE.Vector3(0, 0, -1); // 正前方
115
+
116
+ // 获取对应的面和 UV
117
+ const [face, uv] = observer.vectorToCubemapUv(direction);
118
+
119
+ console.log(`正前方对应 Cubemap 的 ${face} 面,UV 为`, uv);
120
+ ```
121
+
122
+ ## Related
123
+
124
+ * [Work](./work.md): 了解 WorkObserver 的数据结构。
125
+ * [Coordinate System](./coordinate-system.md): 了解 Five 的坐标系定义。
126
+
127
+ ---
128
+
129
+ ```yaml
130
+ tags: [work, observer, uv, projection, math]
131
+ ```
@@ -52,12 +52,24 @@ const five = new Five({
52
52
  * `Intersection` 对象新增了 `tile`, `model`, `viewLayer` 字段,便于在射线检测时获取更详细的上下文信息。
53
53
  * `raycaster.hitFilter` 回调函数的参数类型定义已更新,包含 `model`, `viewLayer`, `tile` 等上下文信息。
54
54
 
55
- ## AI 友好文档 (AI Guides)
56
- > 全面重构了文档结构,使其更适合 AI 辅助编程工具 (如 Cursor, Copilot) 阅读和索引。
55
+ ## glTF 模型支持增强
56
+ > 新增了对更多 glTF 扩展的支持,提升了模型的表现力和动画能力。
57
57
 
58
- * 文档目录迁移至 `ai_guides/`,并在 `package.json` 中新增 `ai` 字段指向该目录。
59
- * 文档内容包含源码链接 (`source` 字段),直接指向对应的 `.ts` 定义文件。
60
- * 提供了更清晰的 API 定义和概念说明,例如新增了 [ViewLayer](../features/view-layer.md) 的详细文档。
58
+ ### 新增扩展支持
59
+ * **KHR_animation_pointer**: 允许动画通道指向 glTF 资产中任何对象的任何属性,而不仅仅是节点的平移、旋转和缩放。
60
+ * **KHR_node_visibility**: 允许设置节点的可见性属性。
61
+ * **KHR_materials_clearcoat** 用于在材质上添加一层透明涂层,模拟车漆、碳纤维、清漆木材等真实世界中的表面效果。
62
+ * **KHR_materials_sheen** 绒面 / 绒毛类表面效果。
63
+ * **KHR_materials_transmission** 物理透光材质扩展,用于实现光线真正穿过物体的透明 / 半透明效果。
64
+
65
+ ## Work 核心能力增强
66
+ > 为 WorkObserver 提供了更多实用的工具函数,便于进行坐标和 UV 转换。
67
+
68
+ ### UV 转换工具函数
69
+ * `vectorToEquirectangularUv`: 将方向向量转化为全景图 uv。
70
+ * `equirectangularUvToVector`: 将全景图 uv 转化为方向向量。
71
+ * `vectorToCubemapUv`: 将方向向量转化为立方体贴图 uv。
72
+ * `cubemapUvToVector`: 将立方体贴图 uv 转化为方向向量。
61
73
 
62
74
  ## 新增后处理效果 (Post-Processing Passes)
63
75
  > 新增了三个可选的内置后处理 Pass,用于增强视觉效果。
@@ -66,16 +78,13 @@ const five = new Five({
66
78
  * **[FlowingLight3DPass](../features/flowing-light-3d-pass.md)**: 3D 流光效果,基于深度缓冲区在三维模型表面绘制流光。
67
79
  * **[GaussianBlurPass](../features/gaussian-blur-pass.md)**: 高斯模糊效果,可用于实现毛玻璃等视觉特效。
68
80
 
81
+ ## AI 友好文档 (AI Guides)
82
+ > 全面重构了文档结构,使其更适合 AI 辅助编程工具 (如 Cursor, Copilot) 阅读和索引。
83
+
84
+ * 文档目录迁移至 `ai_guides/`,并在 `package.json` 中新增 `ai` 字段指向该目录。
85
+ * 文档内容包含源码链接 (`source` 字段),直接指向对应的 `.ts` 定义文件。
86
+ * 提供了更清晰的 API 定义和概念说明,例如新增了 [ViewLayer](../features/view-layer.md) 的详细文档。
87
+
69
88
  ## 其他优化
70
89
  * **点云渲染**: 计算点位透明度时,现在会排除不活跃的点,提升渲染正确性。
71
90
  * **TypeScript 支持**: 优化了 `.d.ts` 打包方式,声明文件现在与源码文件一一对应,提升了 IDE 的跳转体验。
72
-
73
- ## glTF 支持**: 新增 `KHR_animation_pointer` 和 `KHR_node_visibility` 扩展支持
74
- * `KHR_animation_pointer` 扩展 允许动画通道指向 glTF 资产中任何对象的任何属性,而不仅仅是节点的平移、旋转和缩放。
75
- * `KHR_node_visibility` 扩展 允许设置节点的可见性属性。
76
-
77
- ## work 提供 uv 转化函数。
78
- * `vectorToEquirectangularUv` 方法将方向向量转化为全景图 uv。
79
- * `equirectangularUvToVector` 方法将全景图 uv 转化为方向向量。
80
- * `vectorToCubemapUv` 方法将方向向量转化为立方体贴图 uv。
81
- * `cubemapUvToVector` 方法将立方体贴图 uv 转化为方向向量。
@@ -1 +1 @@
1
- window.hierarchyData = "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"
1
+ window.hierarchyData = "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"