@laplace.live/persona-sdk 0.11.0 → 0.14.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/dist/values/effect-schema.js +3 -0
- package/dist/values/limits.d.ts +59 -1
- package/dist/values/limits.js +115 -2
- package/dist/wire/methods.d.ts +6 -2
- package/dist/wire/types.d.ts +78 -6
- package/dist/wire/types.js +7 -1
- package/package.json +1 -1
|
@@ -21,6 +21,9 @@ export const EFFECT_SPECS = {
|
|
|
21
21
|
saturation: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
22
22
|
brightness: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
23
23
|
contrast: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
24
|
+
// Unity PPv2's white-balance range, so a Unity-authored grade arrives as-is.
|
|
25
|
+
temperature: { default: 0, min: -100, max: 100, step: 1 },
|
|
26
|
+
tint: { default: 0, min: -100, max: 100, step: 1 },
|
|
24
27
|
},
|
|
25
28
|
bloom: {
|
|
26
29
|
// Past ×3 the halo overwhelms the source pixels and everything reads as haze.
|
package/dist/values/limits.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Attach, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneLight, SceneLightType, ScreenPlacement, VrmPlacement } from '../wire/types.ts';
|
|
1
|
+
import type { AssetRef, Attach, EnvironmentLook, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneEnvironment, SceneLight, SceneLightType, ScreenPlacement, VrmPlacement } from '../wire/types.ts';
|
|
2
2
|
export declare function clamp(v: number, min: number, max: number): number;
|
|
3
3
|
/** Clamp to the unit interval. */
|
|
4
4
|
export declare function clamp01(v: number): number;
|
|
@@ -37,21 +37,77 @@ export declare function sceneLightShadowRadiusMax(type: SceneLightType): number;
|
|
|
37
37
|
export declare const SCENE_FOG_DENSITY_MAX = 0.5;
|
|
38
38
|
/** ×4 is +2 stops — enough to rescue an AgX-dimmed avatar without turning the slider to mush. */
|
|
39
39
|
export declare const SCENE_EXPOSURE_MAX = 4;
|
|
40
|
+
export declare const MTOON_NORMAL_SCALE_MAX = 2;
|
|
40
41
|
export declare const MTOON_RIM_MAX = 2;
|
|
42
|
+
/** ×0 flattens the Fresnel to a flood fill, ×4 tightens a default power-5 rim to a hairline. */
|
|
43
|
+
export declare const MTOON_RIM_FRESNEL_POWER_MAX = 4;
|
|
44
|
+
/** ×4 carries a quarter-strength authored `matcapFactor` back to the spec's full 1.0. */
|
|
45
|
+
export declare const MTOON_MATCAP_MAX = 4;
|
|
41
46
|
export declare const MTOON_OUTLINE_WIDTH_MAX = 2;
|
|
42
47
|
/** HDR headroom: past ×1 the point is pushing emissive parts over the bloom threshold. */
|
|
43
48
|
export declare const MTOON_EMISSIVE_MAX = 4;
|
|
49
|
+
export declare const MTOON_UV_ANIMATION_MAX = 4;
|
|
44
50
|
export declare function defaultMToonTuning(): MToonTuning;
|
|
45
51
|
export declare const DEFAULT_LIGHT_AZIMUTH_DEG = 45;
|
|
46
52
|
export declare const DEFAULT_LIGHT_ELEVATION_DEG: number;
|
|
47
53
|
/** A fresh light of `type`, at the defaults that read sensibly for that type. */
|
|
48
54
|
export declare function defaultSceneLightOf(type: SceneLightType): SceneLight;
|
|
55
|
+
/**
|
|
56
|
+
* Where a scene's own lights drop once a set lights the stage — Warudo's
|
|
57
|
+
* `CalculateIdealDirectionalLightIntensity`; past it the two light sets clip MToon to white.
|
|
58
|
+
*/
|
|
59
|
+
export declare const ENVIRONMENT_IDEAL_LIGHT_INTENSITY = 0.25;
|
|
60
|
+
/**
|
|
61
|
+
* Warudo's Apply Environment Lighting: route the set's lights at everything and cap each
|
|
62
|
+
* shading light at {@link ENVIRONMENT_IDEAL_LIGHT_INTENSITY}; ambient, a flat floor, stays.
|
|
63
|
+
* @returns New `environment` and `lights` values; the inputs are untouched.
|
|
64
|
+
*/
|
|
65
|
+
export declare function applyEnvironmentLighting(env: SceneEnvironment, lights: readonly SceneLight[]): {
|
|
66
|
+
environment: SceneEnvironment;
|
|
67
|
+
lights: SceneLight[];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Fold a set's {@link EnvironmentLook} into a scene's environment: its fog, its
|
|
71
|
+
* ambient level and the four post settings it names, leaving every other effect —
|
|
72
|
+
* and the user's lights, map and placement — untouched.
|
|
73
|
+
*
|
|
74
|
+
* Enabling an effect here is enough for it to render: `effectLayers` is re-derived
|
|
75
|
+
* from what the result switches on, so a look lands on the live stage rather than
|
|
76
|
+
* waiting for main's healing pass to come back around.
|
|
77
|
+
* @returns A new environment; the input is untouched.
|
|
78
|
+
*/
|
|
79
|
+
export declare function applyEnvironmentLook(env: SceneEnvironment, look: EnvironmentLook): SceneEnvironment;
|
|
80
|
+
/**
|
|
81
|
+
* Whether `env` still holds `reference`'s values in every field an
|
|
82
|
+
* {@link EnvironmentLook} would overwrite — so applying one takes nothing away.
|
|
83
|
+
*
|
|
84
|
+
* The guard on adopting a set's look unasked. Applying it is otherwise deliberate
|
|
85
|
+
* because it overwrites fog and post the user may have tuned; when none of it has
|
|
86
|
+
* been touched, there is nothing to protect and a room that ships a look should
|
|
87
|
+
* simply arrive wearing it.
|
|
88
|
+
*/
|
|
89
|
+
export declare function environmentLookIsUntouched(env: SceneEnvironment, reference: SceneEnvironment): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Point an environment at one asset, or at none.
|
|
92
|
+
*
|
|
93
|
+
* {@link SceneEnvironment.iblAssetId} and {@link SceneEnvironment.modelAssetId} are a
|
|
94
|
+
* single slot — a scene wears an equirect map or a 3D set — so this clears whichever
|
|
95
|
+
* the pick is not. `bakeFromModel` goes with the set: it outlives the id it names, and
|
|
96
|
+
* it wins over a picked map, so a stale one would leave a fresh map lighting nothing.
|
|
97
|
+
* Light overrides index the set's own lamps, so a different set — or none — drops them.
|
|
98
|
+
* `modelLook` stays put: the stage replaces it as the next set parses, and the desktop
|
|
99
|
+
* reads the outgoing one as what the scene wears now when deciding to adopt the next.
|
|
100
|
+
* @returns A new environment; the input is untouched.
|
|
101
|
+
*/
|
|
102
|
+
export declare function environmentWithAsset(env: SceneEnvironment, asset: Pick<AssetRef, 'id' | 'kind'> | null): SceneEnvironment;
|
|
49
103
|
export declare const PLACE_2D_SCALE_MIN = 0.01;
|
|
50
104
|
export declare const PLACE_2D_SCALE_MAX = 50;
|
|
51
105
|
export declare const PLACE_3D_SCALE_MIN = 0.01;
|
|
52
106
|
export declare const PLACE_3D_SCALE_MAX = 100;
|
|
53
107
|
/** A prop is a mesh, so it only exists in the three.js scene; every other kind renders in both. */
|
|
54
108
|
export declare function objectSupportsSpace(kind: ObjectContent['kind'], space: ObjectSpace): boolean;
|
|
109
|
+
/** The asset an object streams from, or null for kinds that carry their source inline (web, capture). */
|
|
110
|
+
export declare function contentAssetId(content: ObjectContent): string | null;
|
|
55
111
|
/**
|
|
56
112
|
* The one model format a space's objects can ride: the renderers never mix, and
|
|
57
113
|
* the three canvas always composites over the Pixi one, so a cross-space pin
|
|
@@ -61,6 +117,8 @@ export declare function attachableParentFormat(space: ObjectSpace): ModelFormat;
|
|
|
61
117
|
export declare const DEFAULT_HEAD_ANGLE: NonNullable<Attach['headAngle']>;
|
|
62
118
|
export declare const ATTACH_MULTIPLIER_MIN = -2;
|
|
63
119
|
export declare const ATTACH_MULTIPLIER_MAX = 2;
|
|
120
|
+
/** Parallax slider ceiling, symmetric: stage px at a full head turn. */
|
|
121
|
+
export declare const ATTACH_PARALLAX_MAX = 300;
|
|
64
122
|
export declare const ATTACH_SMOOTHING_MAX = 50;
|
|
65
123
|
export declare const DEFAULT_ELASTICITY: NonNullable<Attach['elasticity']>;
|
|
66
124
|
export declare const ELASTICITY_STIFFNESS_MAX = 100;
|
package/dist/values/limits.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { effectLayerKeys } from "./effect-schema.js";
|
|
1
2
|
export function clamp(v, min, max) {
|
|
2
3
|
return Math.min(max, Math.max(min, v));
|
|
3
4
|
}
|
|
@@ -51,12 +52,33 @@ export function sceneLightShadowRadiusMax(type) {
|
|
|
51
52
|
export const SCENE_FOG_DENSITY_MAX = 0.5;
|
|
52
53
|
/** ×4 is +2 stops — enough to rescue an AgX-dimmed avatar without turning the slider to mush. */
|
|
53
54
|
export const SCENE_EXPOSURE_MAX = 4;
|
|
55
|
+
export const MTOON_NORMAL_SCALE_MAX = 2;
|
|
54
56
|
export const MTOON_RIM_MAX = 2;
|
|
57
|
+
/** ×0 flattens the Fresnel to a flood fill, ×4 tightens a default power-5 rim to a hairline. */
|
|
58
|
+
export const MTOON_RIM_FRESNEL_POWER_MAX = 4;
|
|
59
|
+
/** ×4 carries a quarter-strength authored `matcapFactor` back to the spec's full 1.0. */
|
|
60
|
+
export const MTOON_MATCAP_MAX = 4;
|
|
55
61
|
export const MTOON_OUTLINE_WIDTH_MAX = 2;
|
|
56
62
|
/** HDR headroom: past ×1 the point is pushing emissive parts over the bloom threshold. */
|
|
57
63
|
export const MTOON_EMISSIVE_MAX = 4;
|
|
64
|
+
export const MTOON_UV_ANIMATION_MAX = 4;
|
|
58
65
|
export function defaultMToonTuning() {
|
|
59
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
shade: 1,
|
|
68
|
+
shadingShift: 0,
|
|
69
|
+
shadingToony: 0,
|
|
70
|
+
giEqualization: 0,
|
|
71
|
+
normalScale: 1,
|
|
72
|
+
rim: 1,
|
|
73
|
+
rimLift: 0,
|
|
74
|
+
rimFresnelPower: 1,
|
|
75
|
+
rimLightingMix: 0,
|
|
76
|
+
matcap: 1,
|
|
77
|
+
outlineWidth: 1,
|
|
78
|
+
outlineLightingMix: 0,
|
|
79
|
+
emissive: 1,
|
|
80
|
+
uvAnimation: 1,
|
|
81
|
+
};
|
|
60
82
|
}
|
|
61
83
|
// Ranges for toggle-style effect params live in effect-schema.ts (EFFECT_SPECS).
|
|
62
84
|
// Angles at which lightDirection reproduces (1,1,1).normalize() — the app's original hardcoded light.
|
|
@@ -82,6 +104,86 @@ export function defaultSceneLightOf(type) {
|
|
|
82
104
|
shadowRadius: 6,
|
|
83
105
|
};
|
|
84
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Where a scene's own lights drop once a set lights the stage — Warudo's
|
|
109
|
+
* `CalculateIdealDirectionalLightIntensity`; past it the two light sets clip MToon to white.
|
|
110
|
+
*/
|
|
111
|
+
export const ENVIRONMENT_IDEAL_LIGHT_INTENSITY = 0.25;
|
|
112
|
+
/**
|
|
113
|
+
* Warudo's Apply Environment Lighting: route the set's lights at everything and cap each
|
|
114
|
+
* shading light at {@link ENVIRONMENT_IDEAL_LIGHT_INTENSITY}; ambient, a flat floor, stays.
|
|
115
|
+
* @returns New `environment` and `lights` values; the inputs are untouched.
|
|
116
|
+
*/
|
|
117
|
+
export function applyEnvironmentLighting(env, lights) {
|
|
118
|
+
return {
|
|
119
|
+
environment: { ...env, modelLightsEnabled: true, lightsAffectCharacters: true, lightsAffectProps: true },
|
|
120
|
+
lights: lights.map(l => l.type === 'ambient' ? { ...l } : { ...l, intensity: Math.min(l.intensity, ENVIRONMENT_IDEAL_LIGHT_INTENSITY) }),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Fold a set's {@link EnvironmentLook} into a scene's environment: its fog, its
|
|
125
|
+
* ambient level and the four post settings it names, leaving every other effect —
|
|
126
|
+
* and the user's lights, map and placement — untouched.
|
|
127
|
+
*
|
|
128
|
+
* Enabling an effect here is enough for it to render: `effectLayers` is re-derived
|
|
129
|
+
* from what the result switches on, so a look lands on the live stage rather than
|
|
130
|
+
* waiting for main's healing pass to come back around.
|
|
131
|
+
* @returns A new environment; the input is untouched.
|
|
132
|
+
*/
|
|
133
|
+
export function applyEnvironmentLook(env, look) {
|
|
134
|
+
const effects = {
|
|
135
|
+
...env.effects,
|
|
136
|
+
toneMapping: look.toneMapping,
|
|
137
|
+
exposure: look.exposure,
|
|
138
|
+
bloom: { ...look.bloom },
|
|
139
|
+
color: { ...look.color },
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
...env,
|
|
143
|
+
iblIntensity: look.iblIntensity,
|
|
144
|
+
fog: { ...look.fog },
|
|
145
|
+
effects,
|
|
146
|
+
effectLayers: effectLayerKeys(env.effectLayers, effects),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Whether `env` still holds `reference`'s values in every field an
|
|
151
|
+
* {@link EnvironmentLook} would overwrite — so applying one takes nothing away.
|
|
152
|
+
*
|
|
153
|
+
* The guard on adopting a set's look unasked. Applying it is otherwise deliberate
|
|
154
|
+
* because it overwrites fog and post the user may have tuned; when none of it has
|
|
155
|
+
* been touched, there is nothing to protect and a room that ships a look should
|
|
156
|
+
* simply arrive wearing it.
|
|
157
|
+
*/
|
|
158
|
+
export function environmentLookIsUntouched(env, reference) {
|
|
159
|
+
// Compared through the same shape `applyEnvironmentLook` writes, so a field
|
|
160
|
+
// added to the look is covered here without a second edit.
|
|
161
|
+
const looked = (e) => JSON.stringify([e.fog, e.iblIntensity, e.effects.toneMapping, e.effects.exposure, e.effects.bloom, e.effects.color]);
|
|
162
|
+
return looked(env) === looked(reference);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Point an environment at one asset, or at none.
|
|
166
|
+
*
|
|
167
|
+
* {@link SceneEnvironment.iblAssetId} and {@link SceneEnvironment.modelAssetId} are a
|
|
168
|
+
* single slot — a scene wears an equirect map or a 3D set — so this clears whichever
|
|
169
|
+
* the pick is not. `bakeFromModel` goes with the set: it outlives the id it names, and
|
|
170
|
+
* it wins over a picked map, so a stale one would leave a fresh map lighting nothing.
|
|
171
|
+
* Light overrides index the set's own lamps, so a different set — or none — drops them.
|
|
172
|
+
* `modelLook` stays put: the stage replaces it as the next set parses, and the desktop
|
|
173
|
+
* reads the outgoing one as what the scene wears now when deciding to adopt the next.
|
|
174
|
+
* @returns A new environment; the input is untouched.
|
|
175
|
+
*/
|
|
176
|
+
export function environmentWithAsset(env, asset) {
|
|
177
|
+
const isSet = asset?.kind === 'prop';
|
|
178
|
+
const modelAssetId = isSet ? asset.id : null;
|
|
179
|
+
return {
|
|
180
|
+
...env,
|
|
181
|
+
iblAssetId: asset !== null && !isSet ? asset.id : null,
|
|
182
|
+
modelAssetId,
|
|
183
|
+
bakeFromModel: isSet && env.bakeFromModel,
|
|
184
|
+
modelLightOverrides: modelAssetId === env.modelAssetId ? env.modelLightOverrides : {},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
85
187
|
export const PLACE_2D_SCALE_MIN = 0.01;
|
|
86
188
|
export const PLACE_2D_SCALE_MAX = 50;
|
|
87
189
|
export const PLACE_3D_SCALE_MIN = 0.01;
|
|
@@ -90,6 +192,10 @@ export const PLACE_3D_SCALE_MAX = 100;
|
|
|
90
192
|
export function objectSupportsSpace(kind, space) {
|
|
91
193
|
return kind === 'prop' ? space === '3d' : true;
|
|
92
194
|
}
|
|
195
|
+
/** The asset an object streams from, or null for kinds that carry their source inline (web, capture). */
|
|
196
|
+
export function contentAssetId(content) {
|
|
197
|
+
return content.kind === 'image' || content.kind === 'video' || content.kind === 'prop' ? content.assetId : null;
|
|
198
|
+
}
|
|
93
199
|
/**
|
|
94
200
|
* The one model format a space's objects can ride: the renderers never mix, and
|
|
95
201
|
* the three canvas always composites over the Pixi one, so a cross-space pin
|
|
@@ -98,9 +204,16 @@ export function objectSupportsSpace(kind, space) {
|
|
|
98
204
|
export function attachableParentFormat(space) {
|
|
99
205
|
return space === '2d' ? 'live2d' : 'vrm';
|
|
100
206
|
}
|
|
101
|
-
export const DEFAULT_HEAD_ANGLE = {
|
|
207
|
+
export const DEFAULT_HEAD_ANGLE = {
|
|
208
|
+
multiplier: 1,
|
|
209
|
+
parallaxX: 0,
|
|
210
|
+
parallaxY: 0,
|
|
211
|
+
smoothing: 15,
|
|
212
|
+
};
|
|
102
213
|
export const ATTACH_MULTIPLIER_MIN = -2;
|
|
103
214
|
export const ATTACH_MULTIPLIER_MAX = 2;
|
|
215
|
+
/** Parallax slider ceiling, symmetric: stage px at a full head turn. */
|
|
216
|
+
export const ATTACH_PARALLAX_MAX = 300;
|
|
104
217
|
export const ATTACH_SMOOTHING_MAX = 50;
|
|
105
218
|
// Warudo Attachable defaults and slider ceilings, verbatim.
|
|
106
219
|
export const DEFAULT_ELASTICITY = { stiffness: 2, damping: 3, maxSpeed: 2 };
|
package/dist/wire/methods.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EventName } from './events.ts';
|
|
2
|
-
import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, Expression, ExpressionPersistence, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch, ShortcutInfo, TrackingSourceConfig, TrackingSourceId, TrackingSourceKind, TrackingStatus, VrmPlacement } from './types.ts';
|
|
2
|
+
import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, AttachHeadAngle, Expression, ExpressionPersistence, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch, ShortcutInfo, TrackingSourceConfig, TrackingSourceId, TrackingSourceKind, TrackingStatus, VrmPlacement } from './types.ts';
|
|
3
3
|
/** Marker for methods that take no parameters; the client lets you omit the argument. */
|
|
4
4
|
export type EmptyRequest = Record<never, never>;
|
|
5
5
|
/** Marker for methods whose success response carries no data. */
|
|
@@ -149,10 +149,14 @@ export interface ObjectSetPlacementRequest {
|
|
|
149
149
|
place3d?: Partial<Place3D>;
|
|
150
150
|
}
|
|
151
151
|
export type ObjectSetPlacementResponse = EmptyResponse;
|
|
152
|
+
/** {@link Attach} as `object.attach` accepts it: head-angle fields may be omitted and heal to their defaults. */
|
|
153
|
+
export type AttachInput = Omit<Attach, 'headAngle'> & {
|
|
154
|
+
headAngle: Partial<AttachHeadAngle> | null;
|
|
155
|
+
};
|
|
152
156
|
export interface ObjectAttachRequest {
|
|
153
157
|
instanceId: string;
|
|
154
158
|
/** Null detaches. */
|
|
155
|
-
attach:
|
|
159
|
+
attach: AttachInput | null;
|
|
156
160
|
}
|
|
157
161
|
export type ObjectAttachResponse = EmptyResponse;
|
|
158
162
|
export interface ObjectSetLightOverridesRequest {
|
package/dist/wire/types.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ export type ModelFormat = 'live2d' | 'vrm';
|
|
|
2
2
|
/** Where an item came from: shipped with the app, or added by the user. */
|
|
3
3
|
export type ContentOrigin = 'bundled' | 'user';
|
|
4
4
|
/** How a registered file is labelled. Wider than an object's content kinds: `.hdr` is only ever an environment map. */
|
|
5
|
-
export
|
|
5
|
+
export declare const ASSET_KINDS: readonly ["image", "video", "prop", "ibl", "lut", "animation"];
|
|
6
|
+
export type AssetKind = (typeof ASSET_KINDS)[number];
|
|
7
|
+
/** Narrow a kind string to the set the asset registry owns — models and effects have their own. */
|
|
8
|
+
export declare function isAssetKind(v: unknown): v is AssetKind;
|
|
6
9
|
/**
|
|
7
10
|
* Every content kind the Inventory can list. `pngtuber` is schema-ready before any
|
|
8
11
|
* producer exists; `effect` rows are post-processing effects (built-in or installed), not files.
|
|
@@ -89,7 +92,8 @@ export interface Place3D extends VrmPlacement {
|
|
|
89
92
|
/**
|
|
90
93
|
* Per-instance MToon fine-tuning, layered over each material's authored values —
|
|
91
94
|
* offsets add, multipliers scale, so materials keep their relative differences.
|
|
92
|
-
*
|
|
95
|
+
* Neutral values — every multiplier 1, every offset 0 — render the model exactly
|
|
96
|
+
* as authored; `defaultMToonTuning()` is that neutral set.
|
|
93
97
|
*/
|
|
94
98
|
export interface MToonTuning {
|
|
95
99
|
/** 0..1 strength of the authored shading: 1 keeps it, 0 lifts every shade color to its lit color. */
|
|
@@ -100,12 +104,26 @@ export interface MToonTuning {
|
|
|
100
104
|
shadingToony: number;
|
|
101
105
|
/** -1..1 added to authored GI equalization: how evenly ambient/IBL light wraps the model. */
|
|
102
106
|
giEqualization: number;
|
|
107
|
+
/** Multiplier on normal-map strength; 0 flattens the surface detail away. */
|
|
108
|
+
normalScale: number;
|
|
103
109
|
/** Multiplier on the parametric rim color. */
|
|
104
110
|
rim: number;
|
|
111
|
+
/** -1..1 added to authored rim lift: how far the rim wraps in off the silhouette. */
|
|
112
|
+
rimLift: number;
|
|
113
|
+
/** Multiplier on the rim's Fresnel power; higher pulls the band tighter to the edge. */
|
|
114
|
+
rimFresnelPower: number;
|
|
115
|
+
/** -1..1 added to authored rim lighting mix: 0 renders rim and matcap flat, 1 ties them to the scene lights. */
|
|
116
|
+
rimLightingMix: number;
|
|
117
|
+
/** Multiplier on the matcap factor — the sphere-add reflection. No-op on materials without a matcap. */
|
|
118
|
+
matcap: number;
|
|
105
119
|
/** Multiplier on outline width. */
|
|
106
120
|
outlineWidth: number;
|
|
121
|
+
/** -1..1 added to authored outline lighting mix: 0 keeps the outline its own color, 1 tints it with lighting. */
|
|
122
|
+
outlineLightingMix: number;
|
|
107
123
|
/** Multiplier on emissive intensity; >1 pairs with bloom. */
|
|
108
124
|
emissive: number;
|
|
125
|
+
/** Multiplier on UV scroll and rotation speeds; 0 freezes an animated texture. */
|
|
126
|
+
uvAnimation: number;
|
|
109
127
|
}
|
|
110
128
|
export interface SceneModelItem {
|
|
111
129
|
kind: 'model';
|
|
@@ -174,9 +192,12 @@ export type AttachAnchor = {
|
|
|
174
192
|
verts: [number, number, number];
|
|
175
193
|
weights: [number, number, number];
|
|
176
194
|
};
|
|
177
|
-
/** Live2D only:
|
|
195
|
+
/** Live2D only: ParamAngleZ × multiplier turns the pinned item; ParamAngleX/Y × parallax shift it (smoothed). */
|
|
178
196
|
export interface AttachHeadAngle {
|
|
179
197
|
multiplier: number;
|
|
198
|
+
/** Stage px at a full head turn (model at scale 1); positive = in front of the mesh, negative = behind. */
|
|
199
|
+
parallaxX: number;
|
|
200
|
+
parallaxY: number;
|
|
180
201
|
/** VTS-style 0..50; ~frames of lag at 60 fps (0 = instant). */
|
|
181
202
|
smoothing: number;
|
|
182
203
|
}
|
|
@@ -236,8 +257,10 @@ export interface OrbitTransform {
|
|
|
236
257
|
azimuth: number;
|
|
237
258
|
elevation: number;
|
|
238
259
|
distance: number;
|
|
260
|
+
/** Pivot the camera orbits and looks at. Panning moves it along the camera's own axes, so it leaves the XY plane. */
|
|
239
261
|
targetX: number;
|
|
240
262
|
targetY: number;
|
|
263
|
+
targetZ: number;
|
|
241
264
|
}
|
|
242
265
|
/** Scene-level VRM camera. `orbit: null` = never framed — the first VRM load frames it from model height. */
|
|
243
266
|
export interface SceneCamera {
|
|
@@ -250,7 +273,7 @@ export type SceneLightType = 'directional' | 'point' | 'ambient';
|
|
|
250
273
|
* shadow-map resolution. A point light pays 6 cube faces for the same tier a
|
|
251
274
|
* directional light covers with one map, so it gets the smaller of the pair.
|
|
252
275
|
*/
|
|
253
|
-
export declare const SHADOW_QUALITY_LEVELS: readonly ["off", "low", "medium", "high", "
|
|
276
|
+
export declare const SHADOW_QUALITY_LEVELS: readonly ["off", "low", "medium", "high", "ultra"];
|
|
254
277
|
export type ShadowQuality = (typeof SHADOW_QUALITY_LEVELS)[number];
|
|
255
278
|
/**
|
|
256
279
|
* One scene light. Angles are degrees. Directional lights aim with
|
|
@@ -333,6 +356,10 @@ export interface SceneColorGrade {
|
|
|
333
356
|
saturation: number;
|
|
334
357
|
brightness: number;
|
|
335
358
|
contrast: number;
|
|
359
|
+
/** White balance along blue↔amber, −100..100. Positive is warmer. */
|
|
360
|
+
temperature: number;
|
|
361
|
+
/** White balance along green↔magenta, −100..100 — the axis `temperature` leaves alone. */
|
|
362
|
+
tint: number;
|
|
336
363
|
}
|
|
337
364
|
/** Lens fringing that grows toward frame edges (Unity PPv2's curve, the one VTube Studio wraps). */
|
|
338
365
|
export interface SceneChromaticAberration {
|
|
@@ -567,14 +594,59 @@ export interface SceneCustomEffect {
|
|
|
567
594
|
params: Record<string, number | boolean | string>;
|
|
568
595
|
}
|
|
569
596
|
/**
|
|
570
|
-
*
|
|
571
|
-
*
|
|
597
|
+
* A 3D set's own suggested look — the fog and post settings it was authored against,
|
|
598
|
+
* read from its root `LAPLACE_environment` extension and held on the scene for every client.
|
|
599
|
+
*/
|
|
600
|
+
export interface EnvironmentLook {
|
|
601
|
+
fog: SceneFog;
|
|
602
|
+
/**
|
|
603
|
+
* How strong the room's own ambient should be, in {@link SceneEnvironment.iblIntensity}'s
|
|
604
|
+
* units — the magnitude its environment map was calibrated against.
|
|
605
|
+
*/
|
|
606
|
+
iblIntensity: number;
|
|
607
|
+
toneMapping: SceneToneMapping;
|
|
608
|
+
/** Scene exposure, in {@link SceneEffects.exposure}'s units. */
|
|
609
|
+
exposure: number;
|
|
610
|
+
bloom: SceneBloom;
|
|
611
|
+
color: SceneColorGrade;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* The world the 3D stage sits in: one environment — a map, or a 3D set the avatar
|
|
615
|
+
* stands inside — the scene-global fog, and post-processing.
|
|
616
|
+
*
|
|
617
|
+
* The two asset ids are a single slot the editors write through
|
|
618
|
+
* {@link environmentWithAsset}: at most one is ever set.
|
|
572
619
|
*/
|
|
573
620
|
export interface SceneEnvironment {
|
|
574
621
|
/** Equirectangular `.hdr` or image driving the environment lighting, or null. */
|
|
575
622
|
iblAssetId: string | null;
|
|
576
623
|
iblIntensity: number;
|
|
624
|
+
/**
|
|
625
|
+
* How much of the environment's diffuse light reaches MToon avatars, 0..1. PBR
|
|
626
|
+
* meshes always take it in full; this is the toon-side dial, since MToon 1.0
|
|
627
|
+
* has no IBL term of its own and the app adds one.
|
|
628
|
+
*/
|
|
629
|
+
iblAvatarAmount: number;
|
|
577
630
|
showSkybox: boolean;
|
|
631
|
+
/** A `prop` asset (glb/gltf) rendered as the set the scene sits in, or null. */
|
|
632
|
+
modelAssetId: string | null;
|
|
633
|
+
/** Where that set sits, in the same units as an object's `place3d`. */
|
|
634
|
+
modelPlace: Place3D;
|
|
635
|
+
/**
|
|
636
|
+
* Bake the set's geometry into the environment lighting. It wins over
|
|
637
|
+
* {@link SceneEnvironment.iblAssetId}, so it only means anything with a set.
|
|
638
|
+
*/
|
|
639
|
+
bakeFromModel: boolean;
|
|
640
|
+
/** Whether lights baked into the set render at all. */
|
|
641
|
+
modelLightsEnabled: boolean;
|
|
642
|
+
/** Whether the set's own lights reach avatars. Off means avatars keep only the scene's lights. */
|
|
643
|
+
lightsAffectCharacters: boolean;
|
|
644
|
+
/** Whether the set's own lights reach props. */
|
|
645
|
+
lightsAffectProps: boolean;
|
|
646
|
+
/** Overrides for the set's baked lights, keyed by traversal index — same shape as an object's. */
|
|
647
|
+
modelLightOverrides: Record<string, ObjectLightOverride>;
|
|
648
|
+
/** The set's suggested look, captured when the model was picked; null when it carries none. */
|
|
649
|
+
modelLook: EnvironmentLook | null;
|
|
578
650
|
fog: SceneFog;
|
|
579
651
|
effects: SceneEffects;
|
|
580
652
|
/**
|
package/dist/wire/types.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
// The API's data model: the entity shapes that requests, responses, and events
|
|
2
2
|
// carry. Structural mirrors of the app's scene/settings models, minus anything
|
|
3
3
|
// filesystem-shaped — model refs are sanitized to ids, never directories.
|
|
4
|
+
/** How a registered file is labelled. Wider than an object's content kinds: `.hdr` is only ever an environment map. */
|
|
5
|
+
export const ASSET_KINDS = ['image', 'video', 'prop', 'ibl', 'lut', 'animation'];
|
|
6
|
+
/** Narrow a kind string to the set the asset registry owns — models and effects have their own. */
|
|
7
|
+
export function isAssetKind(v) {
|
|
8
|
+
return typeof v === 'string' && ASSET_KINDS.includes(v);
|
|
9
|
+
}
|
|
4
10
|
/**
|
|
5
11
|
* Per-light shadow tier. `off` is the old `castShadow: false`; the rest raise
|
|
6
12
|
* shadow-map resolution. A point light pays 6 cube faces for the same tier a
|
|
7
13
|
* directional light covers with one map, so it gets the smaller of the pair.
|
|
8
14
|
*/
|
|
9
|
-
export const SHADOW_QUALITY_LEVELS = ['off', 'low', 'medium', 'high', '
|
|
15
|
+
export const SHADOW_QUALITY_LEVELS = ['off', 'low', 'medium', 'high', 'ultra'];
|
|
10
16
|
// ---- Runtime state -------------------------------------------------------------
|
|
11
17
|
/**
|
|
12
18
|
* App-level features a client gates on (never version-sniff): `hello` and
|