@vgai/engine 0.2.0 → 0.4.0-canary.20260715.0
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/README.md +3 -1
- package/package.json +24 -4
- package/schemas/engine-api.json +124 -0
- package/schemas/engine-api.md +53 -0
- package/schemas/engine-capabilities.json +124 -0
- package/schemas/inputmap.schema.json +314 -0
- package/schemas/mat.schema.json +286 -0
- package/schemas/prefab.schema.json +10148 -0
- package/schemas/scn2d.schema.json +475 -0
- package/schemas/vgai-game.schema.json +383 -0
- package/schemas/vscn.schema.json +11007 -0
- package/src/adapter/{world-kind.ts → adapter-surface.ts} +6 -6
- package/src/adapter/authoring.ts +77 -0
- package/src/adapter/first-party-systems.ts +23 -34
- package/src/adapter/game-adapter.ts +8 -8
- package/src/adapter/host-context.ts +2 -4
- package/src/adapter/index.ts +4 -4
- package/src/adapter/system-adapter.ts +88 -22
- package/src/adapter/vgai-scene-game-adapter.ts +244 -194
- package/src/animation/anim-graph-types.ts +12 -43
- package/src/animation/animation-clock.ts +479 -0
- package/src/animation/camera-ownership.ts +467 -0
- package/src/animation/cinematic-cues.ts +451 -0
- package/src/animation/clip-map.ts +41 -0
- package/src/animation/gsap-registration.ts +184 -0
- package/src/animation/theatre-clock-binding.ts +111 -0
- package/src/animation/theatre-director.ts +347 -0
- package/src/animation/theatre-object-binding.ts +661 -0
- package/src/animation/xstate-animation-binding.ts +436 -0
- package/src/animation/xstate-animation-meta.ts +319 -0
- package/src/audio/index.ts +39 -7
- package/src/audio/tone-clock-binding.ts +98 -0
- package/src/audio/tone-context.ts +129 -0
- package/src/audio/tone-offline-render.ts +167 -0
- package/src/audio/wav-encode.ts +119 -0
- package/src/character/cloth-sim.ts +533 -0
- package/src/character/spring-chain.ts +307 -0
- package/src/core/game-loop.ts +57 -2
- package/src/core/seeded-random.ts +161 -0
- package/src/core/system-runner.ts +20 -3
- package/src/core/types.ts +50 -0
- package/src/data/data-asset.ts +167 -0
- package/src/data/data-check-core.ts +242 -0
- package/src/data/data-ref.ts +145 -0
- package/src/data/vite-plugin-data.ts +290 -0
- package/src/dev/performance-profiler.ts +213 -0
- package/src/dev/webgl-gpu-timer.ts +53 -0
- package/src/ecs/component-manager.ts +45 -12
- package/src/ecs/game-component.ts +95 -11
- package/src/humanoid/bake.operation.ts +326 -0
- package/src/humanoid/body.ts +663 -0
- package/src/humanoid/clips.ts +149 -0
- package/src/humanoid/compose.ts +209 -0
- package/src/humanoid/generate.ts +189 -0
- package/src/humanoid/index.ts +36 -0
- package/src/humanoid/schema.ts +108 -0
- package/src/humanoid/skeleton.ts +345 -0
- package/src/index.ts +48 -0
- package/src/input/input-manager.ts +1886 -33
- package/src/input/input-types.ts +158 -3
- package/src/input/prompt-labels.ts +122 -0
- package/src/input/rebind-controller.ts +105 -0
- package/src/input/schema.ts +206 -52
- package/src/manifest/index.ts +5 -5
- package/src/manifest/load.ts +125 -72
- package/src/manifest/schema.ts +362 -255
- package/src/react/game-state.tsx +135 -32
- package/src/react/root-adapter.tsx +49 -0
- package/src/react/unmanaged-root-detector.ts +66 -0
- package/src/react/use-data.ts +124 -0
- package/src/react/use-selection.tsx +135 -0
- package/src/runtime/create-runtime.ts +112 -273
- package/src/runtime/debug-bridge.ts +483 -0
- package/src/runtime/debug-registry.ts +856 -0
- package/src/runtime/game.ts +342 -93
- package/src/runtime/gameplay-rng-trap.ts +134 -0
- package/src/runtime/input-router.ts +7 -7
- package/src/runtime/mount-game.ts +40 -38
- package/src/runtime/mount-manifest.ts +169 -37
- package/src/runtime/render-audio-control.ts +168 -0
- package/src/runtime/render-control.ts +522 -0
- package/src/runtime/render-seed.ts +79 -0
- package/src/runtime/state-bridge.ts +24 -10
- package/src/runtime/types.ts +110 -33
- package/src/scene/asset-loaders.ts +10 -36
- package/src/scene/asset-paths.ts +0 -2
- package/src/scene/asset-ref-check.ts +248 -0
- package/src/scene/asset-registry.ts +22 -0
- package/src/scene/component-registry.ts +14 -3
- package/src/scene/defaults.ts +1 -0
- package/src/scene/light-camera-factory.ts +11 -3
- package/src/scene/parse.ts +133 -0
- package/src/scene/scene-apply.ts +55 -4
- package/src/scene/scene-loader.ts +91 -123
- package/src/scene/scene-types.ts +0 -1
- package/src/scene/schema/animation.ts +30 -79
- package/src/scene/schema/entity.ts +20 -0
- package/src/scene/schema/index.ts +2 -46
- package/src/scene/schema/light.ts +16 -1
- package/src/scene/schema/material.ts +96 -91
- package/src/scene/schema/scene-file.ts +1 -7
- package/src/scene/user-data.ts +22 -10
- package/src/setup/setup-renderer.ts +10 -3
- package/src/tools/define-tool.ts +191 -0
- package/src/world2d/authoring-2d.ts +17 -1
- package/src/world2d/collision-2d.ts +1 -1
- package/src/world2d/pixi-game-adapter.ts +19 -17
- package/src/world2d/scene2d-loader.ts +1 -0
- package/src/world2d/types.ts +8 -2
- package/src/animation/anim-graph.ts +0 -406
- package/src/animation/anim-system.ts +0 -28
- package/src/animation/property-track.ts +0 -178
- package/src/animation/schema.ts +0 -204
- package/src/audio/ambient.ts +0 -300
- package/src/audio/impacts.ts +0 -212
- package/src/audio/movement.ts +0 -140
- package/src/audio/musical.ts +0 -200
- package/src/audio/ui-sounds.ts +0 -171
- package/src/audio/vehicle.ts +0 -235
- package/src/audio/weapons.ts +0 -152
- package/src/runtime/scene-ui-bridge.ts +0 -86
- package/src/runtime/scene-ui-data.ts +0 -119
- package/src/scene/schema/ui.ts +0 -602
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "AUTO-GENERATED by scripts/generate-schema.ts — do not edit manually",
|
|
3
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"version": {
|
|
7
|
+
"type": "number",
|
|
8
|
+
"description": "Input map file format version (RESERVED — no range check yet)"
|
|
9
|
+
},
|
|
10
|
+
"actions": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"propertyNames": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"valueType": {
|
|
19
|
+
"default": "digital",
|
|
20
|
+
"description": "This action's declared value shape (F1, spec §12). 'digital' (boolean, with pressed/justPressed/justReleased edges) is the default when omitted, matching every action authored before F1. 'scalar' is a single deadzone-rescaled float axis. 'vector2' is a radial-deadzoned, unit-circle-normalized {x,y}. 'pointerDelta' is a per-frame {x,y} movement delta, summed across sources. 'pointerPosition' is an absolute {x,y}, last-write-wins across sources. InputManager enforces this at read time: reading an action through the wrong typed getter (e.g. getScalar on a 'digital' action) throws.",
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": [
|
|
23
|
+
"digital",
|
|
24
|
+
"scalar",
|
|
25
|
+
"vector2",
|
|
26
|
+
"pointerDelta",
|
|
27
|
+
"pointerPosition"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"bindings": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"items": {
|
|
33
|
+
"oneOf": [
|
|
34
|
+
{
|
|
35
|
+
"type": "object",
|
|
36
|
+
"properties": {
|
|
37
|
+
"type": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"const": "key",
|
|
40
|
+
"description": "Binding kind: a keyboard key (KeyboardEvent.code)"
|
|
41
|
+
},
|
|
42
|
+
"code": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "KeyboardEvent.code value, e.g. \"KeyW\", \"Space\", \"ArrowUp\""
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": [
|
|
48
|
+
"type",
|
|
49
|
+
"code"
|
|
50
|
+
],
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "object",
|
|
55
|
+
"properties": {
|
|
56
|
+
"type": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"const": "mouse_button",
|
|
59
|
+
"description": "Binding kind: a mouse button"
|
|
60
|
+
},
|
|
61
|
+
"button": {
|
|
62
|
+
"type": "number",
|
|
63
|
+
"description": "MouseEvent.button index (0 = left, 1 = middle, 2 = right)"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"required": [
|
|
67
|
+
"type",
|
|
68
|
+
"button"
|
|
69
|
+
],
|
|
70
|
+
"additionalProperties": false
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"type": "object",
|
|
74
|
+
"properties": {
|
|
75
|
+
"type": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"const": "mouse_move",
|
|
78
|
+
"description": "Binding kind: raw mouse movement (F2, spec §12 \"Complete Device Backends\"). Feeds a 'pointerDelta'-valueType action with the raw accumulated mouse delta (no deadzone), and can also feed a 'vector2'-valueType action (the same delta, radial-deadzoned + unit-circle-clamped via `deadzone`)."
|
|
79
|
+
},
|
|
80
|
+
"deadzone": {
|
|
81
|
+
"description": "Radial deadzone magnitude applied only when this binding feeds a 'vector2'-valueType action (default 0 — no deadzone; ignored for 'pointerDelta' reads, which are never deadzoned).",
|
|
82
|
+
"type": "number"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"required": [
|
|
86
|
+
"type"
|
|
87
|
+
],
|
|
88
|
+
"additionalProperties": false
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"type": "object",
|
|
92
|
+
"properties": {
|
|
93
|
+
"type": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"const": "gamepad_button",
|
|
96
|
+
"description": "Binding kind: a gamepad face/shoulder button"
|
|
97
|
+
},
|
|
98
|
+
"button": {
|
|
99
|
+
"type": "number",
|
|
100
|
+
"description": "Standard Gamepad API button index"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"required": [
|
|
104
|
+
"type",
|
|
105
|
+
"button"
|
|
106
|
+
],
|
|
107
|
+
"additionalProperties": false
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"type": "object",
|
|
111
|
+
"properties": {
|
|
112
|
+
"type": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"const": "gamepad_axis",
|
|
115
|
+
"description": "Binding kind: a single thresholded gamepad axis"
|
|
116
|
+
},
|
|
117
|
+
"axis": {
|
|
118
|
+
"type": "number",
|
|
119
|
+
"description": "Standard Gamepad API axis index"
|
|
120
|
+
},
|
|
121
|
+
"direction": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"enum": [
|
|
124
|
+
"positive",
|
|
125
|
+
"negative"
|
|
126
|
+
],
|
|
127
|
+
"description": "Which side of the deadzone counts as \"pressed\""
|
|
128
|
+
},
|
|
129
|
+
"deadzone": {
|
|
130
|
+
"description": "Deadzone magnitude (default 0.15 if omitted)",
|
|
131
|
+
"type": "number"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"required": [
|
|
135
|
+
"type",
|
|
136
|
+
"axis",
|
|
137
|
+
"direction"
|
|
138
|
+
],
|
|
139
|
+
"additionalProperties": false
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"type": "object",
|
|
143
|
+
"properties": {
|
|
144
|
+
"type": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"const": "gamepad_axis_pair",
|
|
147
|
+
"description": "Binding kind: a coupled (x, y) gamepad axis pair, e.g. a stick used as a 2D vector (look/aim/movement) (F2, spec §12 \"Complete Device Backends\"). Feeds a 'vector2'-valueType action: (xAxis, yAxis) read together, radial-deadzoned + unit-circle-clamped the same way a real analog stick is."
|
|
148
|
+
},
|
|
149
|
+
"xAxis": {
|
|
150
|
+
"type": "number",
|
|
151
|
+
"description": "Standard Gamepad API axis index for the X component"
|
|
152
|
+
},
|
|
153
|
+
"yAxis": {
|
|
154
|
+
"type": "number",
|
|
155
|
+
"description": "Standard Gamepad API axis index for the Y component"
|
|
156
|
+
},
|
|
157
|
+
"deadzone": {
|
|
158
|
+
"description": "Deadzone magnitude (default 0.15 if omitted)",
|
|
159
|
+
"type": "number"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"required": [
|
|
163
|
+
"type",
|
|
164
|
+
"xAxis",
|
|
165
|
+
"yAxis"
|
|
166
|
+
],
|
|
167
|
+
"additionalProperties": false
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"type": "object",
|
|
171
|
+
"properties": {
|
|
172
|
+
"type": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"const": "test_axis",
|
|
175
|
+
"description": "Binding kind: an injected synthetic scalar value for a 'scalar'-valueType action (InputManager.injectAxis/getScalar) — the \"injected test input\" backend named in F2, built in F1 as the typed scalar value model's testable source."
|
|
176
|
+
},
|
|
177
|
+
"sourceId": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"description": "Names the injected test source this binding reads (InputManager.injectAxis)."
|
|
180
|
+
},
|
|
181
|
+
"deadzone": {
|
|
182
|
+
"description": "1D deadzone magnitude applied to the injected raw value before combine (default 0 — no deadzone). Values below it read as 0; values at/above it rescale from 0 (at the deadzone edge) to ±1 (at |raw| = 1), sign preserved.",
|
|
183
|
+
"type": "number"
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"required": [
|
|
187
|
+
"type",
|
|
188
|
+
"sourceId"
|
|
189
|
+
],
|
|
190
|
+
"additionalProperties": false
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"type": "object",
|
|
194
|
+
"properties": {
|
|
195
|
+
"type": {
|
|
196
|
+
"type": "string",
|
|
197
|
+
"const": "test_vector2",
|
|
198
|
+
"description": "Binding kind: an injected synthetic {x,y} value for a 'vector2'-valueType action (InputManager.injectVector2/getVector2) — the \"injected test input\" backend named in F2, built in F1 as the typed Vector2 value model's testable source."
|
|
199
|
+
},
|
|
200
|
+
"sourceId": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"description": "Names the injected test source this binding reads (InputManager.injectVector2)."
|
|
203
|
+
},
|
|
204
|
+
"deadzone": {
|
|
205
|
+
"description": "Radial deadzone magnitude applied to the injected raw {x,y} before combine (default 0 — no deadzone). Vectors whose magnitude is below it read as {0,0}; at/above it, direction is preserved and magnitude rescales the same way the scalar deadzone does, then the result is clamped to the unit circle (magnitude <= 1).",
|
|
206
|
+
"type": "number"
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
"required": [
|
|
210
|
+
"type",
|
|
211
|
+
"sourceId"
|
|
212
|
+
],
|
|
213
|
+
"additionalProperties": false
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"type": "object",
|
|
217
|
+
"properties": {
|
|
218
|
+
"type": {
|
|
219
|
+
"type": "string",
|
|
220
|
+
"const": "test_pointer_delta",
|
|
221
|
+
"description": "Binding kind: an injected synthetic per-frame {x,y} delta for a 'pointerDelta'-valueType action (InputManager.injectPointerDelta/getPointerDelta) — the \"injected test input\" backend named in F2. No deadzone (deltas are not deadzoned)."
|
|
222
|
+
},
|
|
223
|
+
"sourceId": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"description": "Names the injected test source this binding reads (InputManager.injectPointerDelta)."
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"required": [
|
|
229
|
+
"type",
|
|
230
|
+
"sourceId"
|
|
231
|
+
],
|
|
232
|
+
"additionalProperties": false
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"type": "object",
|
|
236
|
+
"properties": {
|
|
237
|
+
"type": {
|
|
238
|
+
"type": "string",
|
|
239
|
+
"const": "test_pointer_position",
|
|
240
|
+
"description": "Binding kind: an injected synthetic absolute {x,y} position for a 'pointerPosition'-valueType action (InputManager.injectPointerPosition/getPointerPosition) — the \"injected test input\" backend named in F2."
|
|
241
|
+
},
|
|
242
|
+
"sourceId": {
|
|
243
|
+
"type": "string",
|
|
244
|
+
"description": "Names the injected test source this binding reads (InputManager.injectPointerPosition)."
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
"required": [
|
|
248
|
+
"type",
|
|
249
|
+
"sourceId"
|
|
250
|
+
],
|
|
251
|
+
"additionalProperties": false
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"type": "object",
|
|
255
|
+
"properties": {
|
|
256
|
+
"type": {
|
|
257
|
+
"type": "string",
|
|
258
|
+
"const": "touch_button",
|
|
259
|
+
"description": "Binding kind: a virtual on-screen button for a 'digital' action (InputManager.setTouchButton/isPressed) — edge-tracked (isJustPressed/isJustReleased) the same way a real mouse/keyboard button is."
|
|
260
|
+
},
|
|
261
|
+
"sourceId": {
|
|
262
|
+
"type": "string",
|
|
263
|
+
"description": "Names the virtual control zone this binding reads (InputManager.setTouchButton) — a touch-UI-chosen id, not a real device index."
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"required": [
|
|
267
|
+
"type",
|
|
268
|
+
"sourceId"
|
|
269
|
+
],
|
|
270
|
+
"additionalProperties": false
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"type": "object",
|
|
274
|
+
"properties": {
|
|
275
|
+
"type": {
|
|
276
|
+
"type": "string",
|
|
277
|
+
"const": "touch_stick",
|
|
278
|
+
"description": "Binding kind: a virtual on-screen analog stick for a 'vector2' action (InputManager.setTouchStick/getVector2) — radial-deadzoned + unit-circle-clamped the same way a real gamepad stick is."
|
|
279
|
+
},
|
|
280
|
+
"sourceId": {
|
|
281
|
+
"type": "string",
|
|
282
|
+
"description": "Names the virtual control zone this binding reads (InputManager.setTouchStick) — a touch-UI-chosen id, not a real device index."
|
|
283
|
+
},
|
|
284
|
+
"deadzone": {
|
|
285
|
+
"description": "Radial deadzone magnitude applied to the raw {x,y} before combine (default 0 — no deadzone).",
|
|
286
|
+
"type": "number"
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"required": [
|
|
290
|
+
"type",
|
|
291
|
+
"sourceId"
|
|
292
|
+
],
|
|
293
|
+
"additionalProperties": false
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
"description": "Bindings that all trigger/feed this action. Digital actions combine via OR (any one binding satisfied is enough). Scalar actions combine via max-magnitude across contributing bindings (ties keep the first-listed binding). Vector2 actions combine by summing contributing {x,y} values then clamping to the unit circle. PointerDelta actions sum contributing deltas. PointerPosition actions use the most-recently-written contributing source (last-write-wins)."
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"required": [
|
|
301
|
+
"valueType",
|
|
302
|
+
"bindings"
|
|
303
|
+
],
|
|
304
|
+
"additionalProperties": false
|
|
305
|
+
},
|
|
306
|
+
"description": "Named actions, each with a list of bindings (InputManager.loadMap)"
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"required": [
|
|
310
|
+
"version",
|
|
311
|
+
"actions"
|
|
312
|
+
],
|
|
313
|
+
"additionalProperties": false
|
|
314
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "AUTO-GENERATED by scripts/generate-schema.ts — do not edit manually",
|
|
3
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"version": {
|
|
7
|
+
"type": "number",
|
|
8
|
+
"description": "File format version"
|
|
9
|
+
},
|
|
10
|
+
"name": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Human-readable material name"
|
|
13
|
+
},
|
|
14
|
+
"material": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"type": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": [
|
|
20
|
+
"standard",
|
|
21
|
+
"physical",
|
|
22
|
+
"basic",
|
|
23
|
+
"toon",
|
|
24
|
+
"custom"
|
|
25
|
+
],
|
|
26
|
+
"description": "Material shading model. \"custom\" resolves `def` against the material registry"
|
|
27
|
+
},
|
|
28
|
+
"def": {
|
|
29
|
+
"description": "Registered custom-material name (required when type is \"custom\")",
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"uniforms": {
|
|
33
|
+
"description": "Authored uniform values for a custom material, keyed by uniform name",
|
|
34
|
+
"type": "object",
|
|
35
|
+
"propertyNames": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"additionalProperties": {
|
|
39
|
+
"anyOf": [
|
|
40
|
+
{
|
|
41
|
+
"type": "number"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "string"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "boolean"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {
|
|
52
|
+
"type": "number"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"color": {
|
|
59
|
+
"description": "Base color as CSS hex string (e.g. \"#ff0000\")",
|
|
60
|
+
"type": "string"
|
|
61
|
+
},
|
|
62
|
+
"metalness": {
|
|
63
|
+
"description": "Metalness factor 0–1 (standard/physical only)",
|
|
64
|
+
"type": "number"
|
|
65
|
+
},
|
|
66
|
+
"roughness": {
|
|
67
|
+
"description": "Roughness factor 0–1 (standard/physical only)",
|
|
68
|
+
"type": "number"
|
|
69
|
+
},
|
|
70
|
+
"map": {
|
|
71
|
+
"description": "Path to albedo/diffuse texture image",
|
|
72
|
+
"type": "string"
|
|
73
|
+
},
|
|
74
|
+
"normalMap": {
|
|
75
|
+
"description": "Path to normal map texture image",
|
|
76
|
+
"type": "string"
|
|
77
|
+
},
|
|
78
|
+
"emissive": {
|
|
79
|
+
"description": "Emissive color as CSS hex string",
|
|
80
|
+
"type": "string"
|
|
81
|
+
},
|
|
82
|
+
"emissiveIntensity": {
|
|
83
|
+
"description": "Emissive light intensity multiplier",
|
|
84
|
+
"type": "number"
|
|
85
|
+
},
|
|
86
|
+
"emissiveMap": {
|
|
87
|
+
"description": "Path to emissive map texture image",
|
|
88
|
+
"type": "string"
|
|
89
|
+
},
|
|
90
|
+
"aoMap": {
|
|
91
|
+
"description": "Path to ambient occlusion map texture image",
|
|
92
|
+
"type": "string"
|
|
93
|
+
},
|
|
94
|
+
"lightMap": {
|
|
95
|
+
"description": "Path to a baked lightmap texture (uses the mesh's second UV set). Applies the pre-baked GI/shadow result on top of the material.",
|
|
96
|
+
"type": "string"
|
|
97
|
+
},
|
|
98
|
+
"lightMapIntensity": {
|
|
99
|
+
"description": "Lightmap intensity multiplier (default 1).",
|
|
100
|
+
"type": "number"
|
|
101
|
+
},
|
|
102
|
+
"roughnessMap": {
|
|
103
|
+
"description": "Path to roughness map texture image",
|
|
104
|
+
"type": "string"
|
|
105
|
+
},
|
|
106
|
+
"metalnessMap": {
|
|
107
|
+
"description": "Path to metalness map texture image",
|
|
108
|
+
"type": "string"
|
|
109
|
+
},
|
|
110
|
+
"opacity": {
|
|
111
|
+
"description": "Opacity 0–1. Set transparent: true to enable",
|
|
112
|
+
"type": "number"
|
|
113
|
+
},
|
|
114
|
+
"transparent": {
|
|
115
|
+
"description": "Enable alpha blending for this material",
|
|
116
|
+
"type": "boolean"
|
|
117
|
+
},
|
|
118
|
+
"side": {
|
|
119
|
+
"description": "Which face sides to render",
|
|
120
|
+
"type": "string",
|
|
121
|
+
"enum": [
|
|
122
|
+
"front",
|
|
123
|
+
"back",
|
|
124
|
+
"double"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"flatShading": {
|
|
128
|
+
"description": "Use flat (faceted) shading instead of smooth",
|
|
129
|
+
"type": "boolean"
|
|
130
|
+
},
|
|
131
|
+
"clearcoat": {
|
|
132
|
+
"description": "Clearcoat layer (physical only)",
|
|
133
|
+
"type": "object",
|
|
134
|
+
"properties": {
|
|
135
|
+
"clearcoat": {
|
|
136
|
+
"type": "number",
|
|
137
|
+
"description": "Clearcoat layer intensity 0–1"
|
|
138
|
+
},
|
|
139
|
+
"clearcoatRoughness": {
|
|
140
|
+
"description": "Clearcoat roughness 0–1",
|
|
141
|
+
"type": "number"
|
|
142
|
+
},
|
|
143
|
+
"clearcoatMap": {
|
|
144
|
+
"description": "Path to clearcoat intensity map",
|
|
145
|
+
"type": "string"
|
|
146
|
+
},
|
|
147
|
+
"clearcoatRoughnessMap": {
|
|
148
|
+
"description": "Path to clearcoat roughness map",
|
|
149
|
+
"type": "string"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"required": [
|
|
153
|
+
"clearcoat"
|
|
154
|
+
],
|
|
155
|
+
"additionalProperties": false
|
|
156
|
+
},
|
|
157
|
+
"transmission": {
|
|
158
|
+
"description": "Light transmission (physical only)",
|
|
159
|
+
"type": "object",
|
|
160
|
+
"properties": {
|
|
161
|
+
"transmission": {
|
|
162
|
+
"type": "number",
|
|
163
|
+
"description": "Transmission intensity 0–1 (glass, liquid)"
|
|
164
|
+
},
|
|
165
|
+
"ior": {
|
|
166
|
+
"description": "Index of refraction (default 1.5)",
|
|
167
|
+
"type": "number"
|
|
168
|
+
},
|
|
169
|
+
"thickness": {
|
|
170
|
+
"description": "Volume thickness for refraction",
|
|
171
|
+
"type": "number"
|
|
172
|
+
},
|
|
173
|
+
"attenuationColor": {
|
|
174
|
+
"description": "Color absorbed over distance",
|
|
175
|
+
"type": "string"
|
|
176
|
+
},
|
|
177
|
+
"attenuationDistance": {
|
|
178
|
+
"description": "Distance at which attenuation color takes full effect",
|
|
179
|
+
"type": "number"
|
|
180
|
+
},
|
|
181
|
+
"transmissionMap": {
|
|
182
|
+
"description": "Path to transmission map",
|
|
183
|
+
"type": "string"
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"required": [
|
|
187
|
+
"transmission"
|
|
188
|
+
],
|
|
189
|
+
"additionalProperties": false
|
|
190
|
+
},
|
|
191
|
+
"sheen": {
|
|
192
|
+
"description": "Sheen layer (physical only)",
|
|
193
|
+
"type": "object",
|
|
194
|
+
"properties": {
|
|
195
|
+
"sheen": {
|
|
196
|
+
"type": "number",
|
|
197
|
+
"description": "Sheen intensity 0–1 (fabric, velvet)"
|
|
198
|
+
},
|
|
199
|
+
"sheenColor": {
|
|
200
|
+
"description": "Sheen tint color",
|
|
201
|
+
"type": "string"
|
|
202
|
+
},
|
|
203
|
+
"sheenRoughness": {
|
|
204
|
+
"description": "Sheen roughness 0–1",
|
|
205
|
+
"type": "number"
|
|
206
|
+
},
|
|
207
|
+
"sheenColorMap": {
|
|
208
|
+
"description": "Path to sheen color map",
|
|
209
|
+
"type": "string"
|
|
210
|
+
},
|
|
211
|
+
"sheenRoughnessMap": {
|
|
212
|
+
"description": "Path to sheen roughness map",
|
|
213
|
+
"type": "string"
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
"required": [
|
|
217
|
+
"sheen"
|
|
218
|
+
],
|
|
219
|
+
"additionalProperties": false
|
|
220
|
+
},
|
|
221
|
+
"iridescence": {
|
|
222
|
+
"description": "Iridescence thin-film (physical only)",
|
|
223
|
+
"type": "object",
|
|
224
|
+
"properties": {
|
|
225
|
+
"iridescence": {
|
|
226
|
+
"type": "number",
|
|
227
|
+
"description": "Iridescence intensity 0–1 (soap bubbles, oil slick)"
|
|
228
|
+
},
|
|
229
|
+
"iridescenceIOR": {
|
|
230
|
+
"description": "Thin-film IOR (default 1.3)",
|
|
231
|
+
"type": "number"
|
|
232
|
+
},
|
|
233
|
+
"iridescenceThicknessRange": {
|
|
234
|
+
"description": "Min/max thin-film thickness in nm",
|
|
235
|
+
"type": "array",
|
|
236
|
+
"prefixItems": [
|
|
237
|
+
{
|
|
238
|
+
"type": "number"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"type": "number"
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
"iridescenceMap": {
|
|
246
|
+
"description": "Path to iridescence intensity map",
|
|
247
|
+
"type": "string"
|
|
248
|
+
},
|
|
249
|
+
"iridescenceThicknessMap": {
|
|
250
|
+
"description": "Path to iridescence thickness map",
|
|
251
|
+
"type": "string"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
"required": [
|
|
255
|
+
"iridescence"
|
|
256
|
+
],
|
|
257
|
+
"additionalProperties": false
|
|
258
|
+
},
|
|
259
|
+
"displacementMap": {
|
|
260
|
+
"description": "Path to displacement/height map",
|
|
261
|
+
"type": "string"
|
|
262
|
+
},
|
|
263
|
+
"displacementScale": {
|
|
264
|
+
"description": "Displacement height multiplier",
|
|
265
|
+
"type": "number"
|
|
266
|
+
},
|
|
267
|
+
"displacementBias": {
|
|
268
|
+
"description": "Displacement offset",
|
|
269
|
+
"type": "number"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"required": [
|
|
273
|
+
"type"
|
|
274
|
+
],
|
|
275
|
+
"additionalProperties": false,
|
|
276
|
+
"description": "Material definition"
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"required": [
|
|
280
|
+
"version",
|
|
281
|
+
"name",
|
|
282
|
+
"material"
|
|
283
|
+
],
|
|
284
|
+
"additionalProperties": false,
|
|
285
|
+
"description": "Shared material asset file (.mat.json)"
|
|
286
|
+
}
|