@combos-fun/plugin-renderer-3d 0.0.41 → 0.0.44
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.
- package/agent-skill.md +66 -6
- package/combos-plugin.json +11 -2
- package/dist/plugin-renderer-3d.cjs.js +959 -9
- package/dist/plugin-renderer-3d.cjs.js.map +1 -1
- package/dist/plugin-renderer-3d.cjs.prod.js +1 -1
- package/dist/plugin-renderer-3d.d.ts +257 -5
- package/dist/plugin-renderer-3d.esm.js +943 -13
- package/dist/plugin-renderer-3d.esm.js.map +1 -1
- package/package.json +3 -3
package/agent-skill.md
CHANGED
|
@@ -14,6 +14,14 @@ import {
|
|
|
14
14
|
Renderer3D,
|
|
15
15
|
Renderer3DManager,
|
|
16
16
|
ThreeContext,
|
|
17
|
+
Transform3D,
|
|
18
|
+
Transform3DSystem,
|
|
19
|
+
Render3D,
|
|
20
|
+
Render3DSystem,
|
|
21
|
+
Camera3D,
|
|
22
|
+
Camera3DSystem,
|
|
23
|
+
Light3D,
|
|
24
|
+
Light3DSystem,
|
|
17
25
|
tagObject3D,
|
|
18
26
|
requireNamedResource,
|
|
19
27
|
textureFromNamedImage,
|
|
@@ -33,6 +41,13 @@ import {
|
|
|
33
41
|
| `antialias` | `boolean` | `true` |
|
|
34
42
|
| `backgroundColor` | `number` | `0x000000` |
|
|
35
43
|
| `backgroundAlpha` | `number` | `1` |
|
|
44
|
+
| `fog` | `false` or `{ color?, near?, far? }` | off |
|
|
45
|
+
| `hemisphereLight` | `false` or `{ skyColor?, groundColor?, intensity? }` | on (`0xffffff` / `0x444444` / `0.35`) |
|
|
46
|
+
| `shadows` | `boolean` | `false` |
|
|
47
|
+
| `toneMapping` | `'none' \| 'aces' \| 'linear' \| 'reinhard' \| 'cineon'` | `'aces'` |
|
|
48
|
+
| `toneMappingExposure` | `number` | `1` |
|
|
49
|
+
| `ambientIntensity` | `number` | `0.6` |
|
|
50
|
+
| `directionalIntensity` | `number` | `0.8` |
|
|
36
51
|
|
|
37
52
|
Either `canvas` or `container` must be provided.
|
|
38
53
|
|
|
@@ -43,9 +58,32 @@ Either `canvas` or `container` must be provided.
|
|
|
43
58
|
- `PerspectiveCamera` (FOV 75, z=5)
|
|
44
59
|
- `AmbientLight` (`0xffffff`, intensity `0.6`)
|
|
45
60
|
- `DirectionalLight` (`0xffffff`, intensity `0.8`, position `(5, 10, 7.5)`)
|
|
61
|
+
- `HemisphereLight` (disable with `hemisphereLight: false`)
|
|
62
|
+
- `ACESFilmicToneMapping` (set `toneMapping: 'none'` to turn off)
|
|
63
|
+
- Optional `Fog` / shadow maps when those params are set
|
|
46
64
|
- `WebGLRenderer`, `Clock`
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
`Graphics3D` / `Model3D` / `Img3D` meshes receive `castShadow` / `receiveShadow` only when `shadows: true`. `Model3D` traverses the loaded group and stamps every mesh.
|
|
67
|
+
|
|
68
|
+
### Transform3D (pose + empty parents)
|
|
69
|
+
|
|
70
|
+
`Transform3D` is the 3D pose source of truth (`position*` / `rotation*` / `scale*`, plus read-only `worldPosition*` / `worldRotation*`). `Renderer3DSystem` auto-adds `Transform3D` on every `Transform` ADD except the Scene itself, and creates a Three.js `Group` root. Visuals (`Graphics3D`, `Model3D`, …) hang under that Group via `attachVisual` — they no longer replace the root.
|
|
71
|
+
|
|
72
|
+
Empty parents work: `hero → hand → sword` does not need a mesh on `hand`.
|
|
73
|
+
|
|
74
|
+
Child `Transform3D` / visual `position*` are **local**. A `Graphics3D` that is instanced is converted to a `Group` when it gains a parent, children, or a `Transform3D` root.
|
|
75
|
+
|
|
76
|
+
`Physics3D.update()` writes pose back onto sibling `Transform3D` (and other `position*` components).
|
|
77
|
+
|
|
78
|
+
### Render3D / Camera3D / Light3D
|
|
79
|
+
|
|
80
|
+
| Component | System | Role |
|
|
81
|
+
|-----------|--------|------|
|
|
82
|
+
| `Render3D` | `Render3DSystem` | `visible`, `opacity` (2D `alpha`), `renderOrder` (2D `zIndex`), `sortableChildren` |
|
|
83
|
+
| `Camera3D` | `Camera3DSystem` | `fov` / `near` / `far` / `active` / optional `lookAt`. Pose is `Transform3D`. First camera without a pose is placed at `z=5`. No `Camera3D` → keep the default `PerspectiveCamera`. |
|
|
84
|
+
| `Light3D` | `Light3DSystem` | `ambient` / `directional` / `hemisphere` / `point` / `spot`. **The first `Light3D` removes the built-in default lights.** |
|
|
85
|
+
|
|
86
|
+
Register those systems after `Renderer3DSystem`. `Transform3DSystem` is optional (the renderer already creates roots) but recommended so pose stays in the Transform3D system.
|
|
49
87
|
|
|
50
88
|
### `Renderer3D` base class
|
|
51
89
|
|
|
@@ -68,7 +106,7 @@ class MyRenderer3D extends Renderer3D {
|
|
|
68
106
|
}
|
|
69
107
|
```
|
|
70
108
|
|
|
71
|
-
Always call `tagObject3D(object, gameObject.id)` so `plugin-renderer-3d-event` can raycast the mesh.
|
|
109
|
+
Always call `tagObject3D(object, gameObject.id)` so `plugin-renderer-3d-event` can raycast the mesh. Attach visuals with `this.threeContext.attachVisual(id, object, gameObject)` so they parent under the `Transform3D` Group.
|
|
72
110
|
|
|
73
111
|
### Named resources (same as 2D)
|
|
74
112
|
|
|
@@ -96,11 +134,15 @@ This prevents memory leaks and double-add bugs when the same `GameObject` is re-
|
|
|
96
134
|
```ts
|
|
97
135
|
new Game({
|
|
98
136
|
systems: [
|
|
99
|
-
new Renderer3DSystem({ canvas, width: 750, height: 1334 }),
|
|
137
|
+
new Renderer3DSystem({ canvas, width: 750, height: 1334, shadows: true }),
|
|
138
|
+
new Transform3DSystem(),
|
|
139
|
+
new Render3DSystem(),
|
|
140
|
+
new Camera3DSystem(),
|
|
141
|
+
new Light3DSystem(),
|
|
100
142
|
new Graphics3DSystem(),
|
|
101
143
|
new Img3DSystem(),
|
|
102
144
|
new Event3DSystem(),
|
|
103
|
-
//
|
|
145
|
+
// Physics3DSystem + Physics3DConstraintSystem from @combos-fun/plugin-cannon
|
|
104
146
|
],
|
|
105
147
|
});
|
|
106
148
|
```
|
|
@@ -108,7 +150,7 @@ new Game({
|
|
|
108
150
|
## Runtime behaviour
|
|
109
151
|
|
|
110
152
|
- `ThreeContext` owns the render loop. `Renderer3D` subclasses register with `rendererManager` and are driven each frame.
|
|
111
|
-
- Three.js `Object3D`s should
|
|
153
|
+
- Three.js `Object3D`s should be attached with `attachVisual` / `attachObject3D`, not by calling `scene.add` in a plugin.
|
|
112
154
|
|
|
113
155
|
## Common pitfalls
|
|
114
156
|
|
|
@@ -116,11 +158,15 @@ new Game({
|
|
|
116
158
|
|---------|-----|
|
|
117
159
|
| Blank canvas | Add `Renderer3DSystem`; ensure `autoStart: true` or call `game.start()` |
|
|
118
160
|
| Nothing draws | Add the matching 3D sub-system (`Graphics3DSystem`, `Model3DSystem`, etc.) before adding components |
|
|
119
|
-
| Object loaded but not visible | Object likely loaded at origin —
|
|
161
|
+
| Object loaded but not visible | Object likely loaded at origin — set `Transform3D.position*` (or sibling visual `position*`, which seeds `Transform3D`), or check camera distance (default `z=5`) |
|
|
162
|
+
| Empty parent / hand slot has no child | Add `Transform3DSystem` or rely on `Renderer3DSystem` auto-`Transform3D`; `addChild` the slot then the item |
|
|
163
|
+
| Custom lights + still have default sun | First `Light3D` removes defaults — add `Light3DSystem` |
|
|
164
|
+
| Want 2D-like hide / fade / draw order | `Render3D` + `Render3DSystem` (`visible` / `opacity` / `renderOrder`) |
|
|
120
165
|
| `getSystem` undefined | Use class reference `game.getSystem(Renderer3DSystem)` |
|
|
121
166
|
| Memory leak after fast remove | Use `increaseAsyncId` / `validateAsyncId` to drop stale async work |
|
|
122
167
|
| CORS errors loading 3D assets | Host on same origin or CORS-enabled CDN; URLs live in `addResource` `src` |
|
|
123
168
|
| `tap` never fires | Use `Event3D` + `Event3DSystem`, not 2D `Event` |
|
|
169
|
+
| Instanced primitives not pickable | `gameObjectIdFromIntersection` reads `instanceId`; official `Graphics3DSystem` fills `userData.combosInstanceGameObjectIds` |
|
|
124
170
|
|
|
125
171
|
## Minimal example
|
|
126
172
|
|
|
@@ -141,6 +187,20 @@ new Game({
|
|
|
141
187
|
|
|
142
188
|
This alone shows an empty 3D scene with default lighting. Add `Graphics3DSystem` etc. and matching components to render anything.
|
|
143
189
|
|
|
190
|
+
Empty parent / equipment slot:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const hero = new GameObject('hero');
|
|
194
|
+
hero.addComponent(new Transform3D({ positionY: 1 }));
|
|
195
|
+
hero.addComponent(new Graphics3D({ shape: 'box', width: 0.6, height: 1.2, depth: 0.4 }));
|
|
196
|
+
const hand = new GameObject('hand');
|
|
197
|
+
hand.addComponent(new Transform3D({ positionX: 0.4, positionY: 0.3 }));
|
|
198
|
+
const sword = new GameObject('sword');
|
|
199
|
+
sword.addComponent(new Graphics3D({ shape: 'box', width: 0.1, height: 0.8, depth: 0.1, color: 0xcccccc }));
|
|
200
|
+
hero.addChild(hand);
|
|
201
|
+
hand.addChild(sword);
|
|
202
|
+
```
|
|
203
|
+
|
|
144
204
|
## Verification
|
|
145
205
|
|
|
146
206
|
- `pnpm --filter @combos-fun/plugin-renderer-3d run build`
|
package/combos-plugin.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"category": "rendering",
|
|
5
5
|
"dimension": "3d",
|
|
6
6
|
"isCore": false,
|
|
7
|
-
"keywords": ["three.js", "3d", "rendering", "webgl", "renderer-base", "scene"],
|
|
7
|
+
"keywords": ["three.js", "3d", "rendering", "webgl", "renderer-base", "scene", "transform3d", "camera", "light"],
|
|
8
8
|
"agentSkill": "./agent-skill.md",
|
|
9
9
|
"requires": ["@combos-fun/engine", "@combos-fun/inspector-decorator"],
|
|
10
10
|
"exports": [
|
|
@@ -12,8 +12,17 @@
|
|
|
12
12
|
"Renderer3D",
|
|
13
13
|
"Renderer3DManager",
|
|
14
14
|
"ThreeContext",
|
|
15
|
+
"Transform3D",
|
|
16
|
+
"Transform3DSystem",
|
|
17
|
+
"Render3D",
|
|
18
|
+
"Render3DSystem",
|
|
19
|
+
"Camera3D",
|
|
20
|
+
"Camera3DSystem",
|
|
21
|
+
"Light3D",
|
|
22
|
+
"Light3DSystem",
|
|
15
23
|
"tagObject3D",
|
|
16
24
|
"requireNamedResource",
|
|
17
|
-
"textureFromNamedImage"
|
|
25
|
+
"textureFromNamedImage",
|
|
26
|
+
"gameObjectIdFromIntersection"
|
|
18
27
|
]
|
|
19
28
|
}
|