@vincentt-xr/sdk 2.0.0-alpha.7 → 2.0.0-alpha.8
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/GROUNDING.md +1109 -13
- package/dist/{DebuggerUI-BjOMr8q_.js → DebuggerUI-C-ldiozL.js} +1 -1
- package/dist/{DebuggerUI-B6bP6P9r.cjs → DebuggerUI-CWX5EtQv.cjs} +1 -1
- package/dist/FaceMeshRenderer-BEEXZwS6.cjs +158 -0
- package/dist/FaceMeshRenderer-UuH5sTXG.js +1322 -0
- package/dist/FaceRetouch-C7h7x9kd.js +683 -0
- package/dist/FaceRetouch-DqftT26Y.cjs +134 -0
- package/dist/GLTFLoader-C5q63sKO.js +1633 -0
- package/dist/GLTFLoader-Cb_CRwmG.cjs +1 -0
- package/dist/SegmentationOverlay-DQuW3dsc.js +133 -0
- package/dist/SegmentationOverlay-aWVod8Kl.cjs +1 -0
- package/dist/assets/cache.d.ts +99 -0
- package/dist/assets/estimate.d.ts +11 -0
- package/dist/assets/index.d.ts +7 -0
- package/dist/assets/loaders.d.ts +28 -0
- package/dist/assets/react.d.ts +33 -0
- package/dist/calibration/calibration.d.ts +70 -0
- package/dist/calibration/index.d.ts +6 -0
- package/dist/calibration/storage.d.ts +13 -0
- package/dist/calibration/types.d.ts +53 -0
- package/dist/calibration/useXRCalibration.d.ts +46 -0
- package/dist/camera/CameraPermissionGate.d.ts +26 -0
- package/dist/camera/devices.d.ts +26 -0
- package/dist/camera/index.d.ts +8 -0
- package/dist/camera/permission.d.ts +86 -0
- package/dist/camera/useCameraPermission.d.ts +35 -0
- package/dist/capabilities/detect.d.ts +45 -0
- package/dist/capabilities/index.d.ts +5 -0
- package/dist/capabilities/types.d.ts +120 -0
- package/dist/capabilities/useXRCapabilities.d.ts +18 -0
- package/dist/compat/environment.d.ts +5 -0
- package/dist/compat/index.d.ts +4 -0
- package/dist/compat/run.d.ts +18 -0
- package/dist/compat/scenarios.d.ts +10 -0
- package/dist/compat/types.d.ts +101 -0
- package/dist/components/BodyTracker/index.d.ts +9 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +33 -3
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +12 -0
- package/dist/components/FaceMesh/canonical/shaders.d.ts +1 -1
- package/dist/components/FaceMesh/index.d.ts +1 -1
- package/dist/components/GestureListener/index.d.ts +11 -0
- package/dist/components/HandTracker/index.d.ts +10 -0
- package/dist/components/HolisticTracker/index.d.ts +69 -0
- package/dist/components/HolisticTracker/settings.d.ts +58 -0
- package/dist/components/HolisticTracker/signals.d.ts +49 -0
- package/dist/components/IrisEffect/IrisMaterial.d.ts +73 -0
- package/dist/components/IrisEffect/index.d.ts +51 -0
- package/dist/components/IrisEffect/settings.d.ts +117 -0
- package/dist/components/LipEffect/LipEffect.d.ts +7 -1
- package/dist/components/LipEffect/LipEffectMaterial.d.ts +43 -7
- package/dist/components/LipEffect/LipEffects.d.ts +9 -0
- package/dist/components/LipEffect/defaults.d.ts +27 -4
- package/dist/components/LipEffect/index.d.ts +11 -3
- package/dist/components/LipEffect/settings.d.ts +271 -0
- package/dist/components/LipEffect/types.d.ts +56 -9
- package/dist/components/LipEffect/useLipDesignTextures.d.ts +11 -0
- package/dist/components/LipEffect/uvGuide.d.ts +59 -0
- package/dist/components/PersonCutout/index.d.ts +50 -0
- package/dist/components/PersonCutout/personCutout.d.ts +16 -0
- package/dist/components/ScreenImage/components/ScreenImageBody.d.ts +1 -1
- package/dist/components/ScreenImage/index.d.ts +3 -1
- package/dist/components/ScreenImage/materials/ScreenImageBlendMaterial.d.ts +1 -1
- package/dist/components/ScreenImage/materials/ScreenImageMaskMaterial.d.ts +11 -0
- package/dist/components/ScreenImage/source.d.ts +6 -0
- package/dist/components/ScreenImage/types.d.ts +18 -0
- package/dist/components/SegmentationOverlay/SegmentationOverlay.d.ts +37 -0
- package/dist/components/SegmentationOverlay/SegmentationOverlayMaterial.d.ts +31 -0
- package/dist/components/SegmentationOverlay/index.d.ts +9 -0
- package/dist/components/SegmentationOverlay/maskTexture.d.ts +23 -0
- package/dist/components/SegmentationOverlay/providers.d.ts +72 -0
- package/dist/components/SegmentationOverlay/settings.d.ts +65 -0
- package/dist/components/XRProvider/index.d.ts +16 -2
- package/dist/components/XRViewport/hooks/useViewportExternalFaces.d.ts +1 -1
- package/dist/components/XRViewport/hooks/useViewportMediaSource.d.ts +1 -1
- package/dist/components/XRViewport/hooks/useViewportPipeline.d.ts +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/constants/index.d.ts +4 -1
- package/dist/contexts-CO0sd4JQ.cjs +1 -0
- package/dist/{contexts-ByhzppYl.js → contexts-FzlnnMYD.js} +252 -246
- package/dist/coordinates/feed.d.ts +52 -0
- package/dist/coordinates/index.d.ts +5 -0
- package/dist/coordinates/spaces.d.ts +49 -0
- package/dist/coordinates/viewport.d.ts +22 -0
- package/dist/coordinates/world.d.ts +15 -0
- package/dist/debug-ui/gesture-settings/index.d.ts +14 -0
- package/dist/debug-ui/holistic-tracker-settings/index.d.ts +16 -0
- package/dist/debug-ui/index.d.ts +14 -0
- package/dist/debug-ui/iris-effect-settings/index.d.ts +12 -0
- package/dist/debug-ui/lip-effect-settings/index.d.ts +15 -0
- package/dist/debug-ui/media-source.cjs +1 -1
- package/dist/debug-ui/media-source.js +1 -1
- package/dist/debug-ui/product-hotspots/index.d.ts +24 -0
- package/dist/debug-ui/segmentation-overlay-settings/index.d.ts +12 -0
- package/dist/debug-ui/xr-diagnostics/index.d.ts +25 -0
- package/dist/debug-ui.cjs +3 -3
- package/dist/debug-ui.js +2057 -1687
- package/dist/detector-K8aej4MB.js +59 -0
- package/dist/detector-ijypGtse.cjs +1 -0
- package/dist/entries/core.d.ts +18 -1
- package/dist/entries/face-effects.d.ts +11 -3
- package/dist/entries/low-level.d.ts +22 -3
- package/dist/entries/product.d.ts +11 -0
- package/dist/entries/tracking.d.ts +24 -1
- package/dist/face-effects.cjs +155 -1
- package/dist/face-effects.js +1134 -2197
- package/dist/gestures/definitions.d.ts +85 -0
- package/dist/gestures/detector.d.ts +87 -0
- package/dist/gestures/index.d.ts +8 -0
- package/dist/gestures/measures.d.ts +101 -0
- package/dist/gestures/settings.d.ts +49 -0
- package/dist/{getFaceInfo-C4QpCQIY.js → getFaceInfo-BkZfaQs-.js} +5 -5
- package/dist/{getFaceInfo-fA1bFBub.cjs → getFaceInfo-ahPxQFGu.cjs} +1 -1
- package/dist/hooks/selectors.d.ts +68 -1
- package/dist/hooks/useCalibrationFaceTracker.d.ts +1 -1
- package/dist/hooks/useFaceInfo.d.ts +13 -1
- package/dist/hooks/useFaceInfos.d.ts +1 -1
- package/dist/hooks/useGesture.d.ts +32 -0
- package/dist/hooks/useIrisTracking.d.ts +45 -0
- package/dist/hooks/useXRDiagnostics.d.ts +81 -0
- package/dist/hooks/useXRModel.d.ts +7 -0
- package/dist/hooks/useXRSession/facade.d.ts +42 -2
- package/dist/hooks/useXRSession/index.d.ts +2 -2
- package/dist/hooks/useXRSession/reason.d.ts +3 -1
- package/dist/hooks/useXRSession/registry.d.ts +14 -0
- package/dist/hooks/useXRSession/store.d.ts +52 -3
- package/dist/index--RgGzZ6X.cjs +47 -0
- package/dist/{index-VJ0SJwmG.js → index-CHVbH0hz.js} +4 -4
- package/dist/index-CeVkgsag.cjs +1 -0
- package/dist/index-CnGox6Xr.js +3054 -0
- package/dist/{index-ByoNj0QP.js → index-CsUdQ-pn.js} +113 -111
- package/dist/{index-BjmTe9eM.cjs → index-DKBAh6hV.cjs} +1 -1
- package/dist/index-DsZwTfG0.cjs +1 -0
- package/dist/index-Dw6tj2Mi.js +144 -0
- package/dist/index-OCPjOaeP.cjs +1 -0
- package/dist/{index-DXT3WccE.js → index-s9pF4zkG.js} +1065 -1101
- package/dist/internal-BYza1h8_.cjs +1 -0
- package/dist/{internal-Dmk1cTXq.js → internal-vsfNQycj.js} +15 -16
- package/dist/internal.cjs +1 -1
- package/dist/internal.js +2 -2
- package/dist/iris/compute.d.ts +25 -0
- package/dist/iris/index.d.ts +4 -0
- package/dist/iris/lead.d.ts +19 -0
- package/dist/iris/types.d.ts +87 -0
- package/dist/landmarkMask-CbTFzBYG.js +224 -0
- package/dist/landmarkMask-u7es2k4X.cjs +1 -0
- package/dist/low-level.cjs +1 -1
- package/dist/low-level.js +1085 -634
- package/dist/main.cjs +1 -1
- package/dist/main.js +1519 -465
- package/dist/measures-9dQPdw96.js +154 -0
- package/dist/measures-KfJzpvod.cjs +1 -0
- package/dist/models/Base/index.d.ts +49 -0
- package/dist/models/Body/index.d.ts +1 -1
- package/dist/models/Face/index.d.ts +1 -1
- package/dist/models/Hand/GestureTracking.d.ts +1 -1
- package/dist/models/Hand/HandTracking.d.ts +1 -1
- package/dist/models/Holistic/index.d.ts +49 -0
- package/dist/models/Holistic/result.d.ts +68 -0
- package/dist/models/SemanticSegmentation/index.d.ts +31 -0
- package/dist/models/SemanticSegmentation/presets.d.ts +28 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/product/ProductDimensions.d.ts +16 -0
- package/dist/product/ProductHotspot.d.ts +16 -0
- package/dist/product/ProductViewer.d.ts +9 -0
- package/dist/product/details.d.ts +53 -0
- package/dist/product/index.d.ts +14 -0
- package/dist/product/loadModelViewer.d.ts +4 -0
- package/dist/product/types.d.ts +71 -0
- package/dist/product/useProductAr.d.ts +37 -0
- package/dist/product/useProductDetails.d.ts +60 -0
- package/dist/product.cjs +1 -0
- package/dist/product.js +414 -0
- package/dist/providers-C0Dlhh9Z.js +365 -0
- package/dist/providers-YNwkmNeK.cjs +62 -0
- package/dist/quality/XRQualityController.d.ts +25 -0
- package/dist/quality/controller.d.ts +33 -0
- package/dist/quality/index.d.ts +6 -0
- package/dist/quality/types.d.ts +100 -0
- package/dist/quality/useXRQuality.d.ts +28 -0
- package/dist/{renderGroups-KZk6eRiY.js → renderGroups-CN1cGFUo.js} +1 -1
- package/dist/{renderGroups-80H3DpTl.cjs → renderGroups-O4KmaMl9.cjs} +1 -1
- package/dist/renderPasses-Cg-zqmEz.cjs +21 -0
- package/dist/renderPasses-NnKZVfBy.js +1460 -0
- package/dist/scene-object.cjs +1 -1
- package/dist/scene-object.js +2 -2
- package/dist/screenTransform-BenfCtZt.js +44 -0
- package/dist/screenTransform-BiXdpVf0.cjs +1 -0
- package/dist/segmentation-9PhSvc-R.cjs +1 -0
- package/dist/segmentation-CeOTKemr.js +5 -0
- package/dist/segmentation2d/faceMemory.d.ts +28 -0
- package/dist/segmentation2d/faceRegions.d.ts +24 -0
- package/dist/segmentation2d/index.d.ts +9 -0
- package/dist/segmentation2d/maskUv.d.ts +23 -0
- package/dist/segmentation2d/rasterize.d.ts +14 -0
- package/dist/segmentation2d/types.d.ts +46 -0
- package/dist/selectors-C5G1PMYL.js +195 -0
- package/dist/selectors-Du_PsVnW.cjs +1 -0
- package/dist/{session-CpkiK5YA.cjs → session-BBr0yN8h.cjs} +7 -7
- package/dist/{session-DLFN_VII.js → session-Cy0m7l7-.js} +76 -76
- package/dist/settings-DRR7-snV.cjs +1 -0
- package/dist/settings-aQk845NJ.js +73 -0
- package/dist/subjects/index.d.ts +2 -0
- package/dist/subjects/select.d.ts +62 -0
- package/dist/subjects/types.d.ts +55 -0
- package/dist/tracking-config/apply.d.ts +57 -0
- package/dist/tracking-config/index.d.ts +7 -0
- package/dist/tracking-config/resolve.d.ts +25 -0
- package/dist/tracking-config/storage.d.ts +8 -0
- package/dist/tracking-config/types.d.ts +106 -0
- package/dist/tracking-config/useXRTrackingConfig.d.ts +38 -0
- package/dist/tracking.cjs +1 -1
- package/dist/tracking.js +1056 -383
- package/dist/types/compositor.d.ts +21 -0
- package/dist/types/holistic.d.ts +121 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/model.d.ts +22 -2
- package/dist/types/nodes.d.ts +27 -2
- package/dist/types/segmentation.d.ts +19 -0
- package/dist/types/session.d.ts +41 -3
- package/dist/useFaceInfo-Blf7FCu3.js +303 -0
- package/dist/useFaceInfo-C5mO8NQY.cjs +1 -0
- package/dist/useXRCapabilities-B1R2ghy-.cjs +1 -0
- package/dist/useXRCapabilities-C68v__wB.js +30 -0
- package/dist/utils/fns.d.ts +6 -3
- package/dist/utils/integrity.d.ts +4 -1
- package/dist/utils/updateThrottle.d.ts +2 -0
- package/dist/utils/useStableUniforms.d.ts +18 -0
- package/docs/api/adaptive-quality.mdx +104 -0
- package/docs/api/asset-lifecycle.mdx +78 -0
- package/docs/api/camera-permission.mdx +142 -0
- package/docs/api/coordinate-spaces.mdx +165 -0
- package/docs/api/cross-camera.mdx +88 -0
- package/docs/api/diagnostics-calibration.mdx +97 -0
- package/docs/api/face-effects.mdx +6 -0
- package/docs/api/face-mesh.mdx +4 -2
- package/docs/api/gestures.mdx +173 -0
- package/docs/api/holistic-tracker.mdx +159 -0
- package/docs/api/iris-tracking.mdx +242 -0
- package/docs/api/multi-subject.mdx +95 -0
- package/docs/api/person-cutout.mdx +136 -0
- package/docs/api/product-ar.mdx +111 -0
- package/docs/api/product-details.mdx +78 -0
- package/docs/api/screen-space-coordinates.mdx +4 -1
- package/docs/api/segmentation-overlay.mdx +301 -0
- package/docs/api/session-lifecycle.mdx +136 -0
- package/docs/api/trackers.mdx +5 -0
- package/docs/api/tracking-config.mdx +108 -0
- package/docs/docs.json +23 -1
- package/docs/examples/lip-shaders.mdx +224 -0
- package/docs/guides/lip-effect-textures.mdx +292 -0
- package/docs/guides/lip-uv-template.png +0 -0
- package/docs/guides/lip-uv-template.svg +1 -0
- package/package.json +13 -1
- package/dist/FaceMeshRenderer-C5l6VLdO.cjs +0 -155
- package/dist/FaceMeshRenderer-wjAHrJzP.js +0 -1270
- package/dist/FaceRetouch-BkJzoA79.cjs +0 -134
- package/dist/FaceRetouch-DwbKQJAN.js +0 -551
- package/dist/contexts-Dr62It_K.cjs +0 -1
- package/dist/index-9dlAQAhy.js +0 -1462
- package/dist/index-BpEf2BBb.cjs +0 -1
- package/dist/index-CyUUurQT.cjs +0 -1
- package/dist/index-DCiMbxC3.cjs +0 -1
- package/dist/index-DpI-qo5X.cjs +0 -17
- package/dist/index-DyVF4vEW.js +0 -111
- package/dist/internal-Cq-TEQ5Y.cjs +0 -1
- package/dist/renderLayers-lDtL0_43.cjs +0 -1
- package/dist/renderLayers-zrK2pv5O.js +0 -13
- package/dist/renderPasses-BOoBSr8z.cjs +0 -21
- package/dist/renderPasses-BcquyVtu.js +0 -1500
- package/dist/selectors-B8H97CKA.js +0 -59
- package/dist/selectors-CZLKT2Iv.cjs +0 -1
- package/dist/useFaceInfo-BJ8-_MOs.cjs +0 -1
- package/dist/useFaceInfo-Dk426LTu.js +0 -62
- package/dist/useFaceResults-CtetsO9M.js +0 -19
- package/dist/useFaceResults-wBJF3zyp.cjs +0 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { LipMaskMode } from './types';
|
|
2
|
+
import { LipUvBounds } from './uvGuide';
|
|
3
|
+
import * as THREE from "three";
|
|
4
|
+
export declare const LIP_EFFECT_PRESET_KEYS: readonly ["lipstick", "gloss", "matte", "tint", "metallic", "gradient"];
|
|
5
|
+
export type LipEffectPresetKey = (typeof LIP_EFFECT_PRESET_KEYS)[number];
|
|
6
|
+
export type LipEffectPreset = LipEffectPresetKey | "custom";
|
|
7
|
+
export declare const LIP_EFFECT_COLOR_MODES: readonly ["texture", "solid"];
|
|
8
|
+
/** `texture` samples the design texture when one is given; `solid` ignores it. */
|
|
9
|
+
export type LipEffectColorMode = (typeof LIP_EFFECT_COLOR_MODES)[number];
|
|
10
|
+
export declare const LIP_EFFECT_GRADIENT_DIRECTIONS: readonly ["outward", "vertical", "horizontal"];
|
|
11
|
+
/** `outward` runs from the mouth line to the outer edge; the others span the lip box. */
|
|
12
|
+
export type LipEffectGradientDirection = (typeof LIP_EFFECT_GRADIENT_DIRECTIONS)[number];
|
|
13
|
+
/**
|
|
14
|
+
* Serializable lip effect settings. Every field is a plain value so the set
|
|
15
|
+
* can live in a scene store and drive the `LipEffectSettingsPanel` directly.
|
|
16
|
+
*
|
|
17
|
+
* Texture transform fields act on the design texture around the lip region:
|
|
18
|
+
* scale is a multiplier, offset is a fraction of the lip region's size
|
|
19
|
+
* (`1` = one lip width / height), rotation is degrees counter-clockwise as
|
|
20
|
+
* seen on the face, and the flips mirror the design across the lip centre.
|
|
21
|
+
*/
|
|
22
|
+
export type LipEffectSettings = {
|
|
23
|
+
preset: LipEffectPreset;
|
|
24
|
+
maskMode: LipMaskMode;
|
|
25
|
+
/** `solid` paints procedurally (colour and gradient only), even if a design texture is set. */
|
|
26
|
+
colorMode: LipEffectColorMode;
|
|
27
|
+
/** Tint multiplied into the design (or the fill colour without a design texture). */
|
|
28
|
+
color: string;
|
|
29
|
+
opacity: number;
|
|
30
|
+
/** 0 shows the design as painted, 1 multiplies it fully by `color`. */
|
|
31
|
+
intensity: number;
|
|
32
|
+
/** How much the camera's own lip shading modulates the paint. 0 = flat. */
|
|
33
|
+
shading: number;
|
|
34
|
+
/** Specular highlight amount. */
|
|
35
|
+
gloss: number;
|
|
36
|
+
/** Highlight spread: 0 = tight mirror-like, 1 = broad and soft. */
|
|
37
|
+
roughness: number;
|
|
38
|
+
highlightColor: string;
|
|
39
|
+
/** Second colour blended in towards the outer lip edge by `gradientAmount`. */
|
|
40
|
+
gradientColor: string;
|
|
41
|
+
gradientAmount: number;
|
|
42
|
+
gradientDirection: LipEffectGradientDirection;
|
|
43
|
+
/** Feather width at the outer lip boundary as a fraction of the lip band. 0 = hard edge. */
|
|
44
|
+
edgeSoftness: number;
|
|
45
|
+
/** Separate tint for the inner lip (and the mouth interior in `outer-lips` mode). */
|
|
46
|
+
innerLipColor: string;
|
|
47
|
+
innerLipAmount: number;
|
|
48
|
+
/** How far the inner tint reaches out from the mouth line, as a fraction of the band. */
|
|
49
|
+
innerLipWidth: number;
|
|
50
|
+
/** Give the lower lip its own colour, opacity and (via `lowerDesignTexture`) texture. */
|
|
51
|
+
splitLips: boolean;
|
|
52
|
+
lowerLipColor: string;
|
|
53
|
+
lowerLipOpacity: number;
|
|
54
|
+
textureScaleX: number;
|
|
55
|
+
textureScaleY: number;
|
|
56
|
+
textureOffsetX: number;
|
|
57
|
+
textureOffsetY: number;
|
|
58
|
+
textureRotation: number;
|
|
59
|
+
textureFlipX: boolean;
|
|
60
|
+
textureFlipY: boolean;
|
|
61
|
+
};
|
|
62
|
+
export declare const DEFAULT_LIP_EFFECT_SETTINGS: LipEffectSettings;
|
|
63
|
+
/**
|
|
64
|
+
* Built-in looks. A preset sets the material fields only; it never touches
|
|
65
|
+
* the mask mode or the texture transform, which belong to the design.
|
|
66
|
+
*/
|
|
67
|
+
export declare const LIP_EFFECT_PRESETS: Record<LipEffectPresetKey, Partial<LipEffectSettings>>;
|
|
68
|
+
export declare const isLipEffectPresetKey: (value: unknown) => value is LipEffectPresetKey;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve partial settings to a complete, clamped set. Defaults come first,
|
|
71
|
+
* then the named preset (if any), then every explicitly provided value.
|
|
72
|
+
*/
|
|
73
|
+
export declare const resolveLipEffectSettings: (input?: Partial<LipEffectSettings>) => LipEffectSettings;
|
|
74
|
+
/**
|
|
75
|
+
* Apply an edit. Choosing a different preset re-applies that preset's values,
|
|
76
|
+
* and only the fields the patch actually changes win over it. A panel sends
|
|
77
|
+
* the whole object, so unchanged fields there carry the previous look and
|
|
78
|
+
* must not override the preset; a sparse API patch keeps its explicit values.
|
|
79
|
+
*/
|
|
80
|
+
export declare const patchLipEffectSettings: (current: LipEffectSettings, patch: Partial<LipEffectSettings>) => LipEffectSettings;
|
|
81
|
+
export declare const LIP_EFFECT_SETTINGS_FIELDS: [{
|
|
82
|
+
readonly key: "preset";
|
|
83
|
+
readonly label: "Preset";
|
|
84
|
+
readonly type: "select";
|
|
85
|
+
readonly options: [{
|
|
86
|
+
readonly label: "Custom";
|
|
87
|
+
readonly value: "custom";
|
|
88
|
+
}, ...{
|
|
89
|
+
label: string;
|
|
90
|
+
value: "gradient" | "tint" | "gloss" | "lipstick" | "matte" | "metallic";
|
|
91
|
+
}[]];
|
|
92
|
+
}, {
|
|
93
|
+
readonly key: "maskMode";
|
|
94
|
+
readonly label: "Mask mode";
|
|
95
|
+
readonly type: "select";
|
|
96
|
+
readonly options: [{
|
|
97
|
+
readonly label: "Outer + inner lips (mouth cut out)";
|
|
98
|
+
readonly value: "outer-and-inner-lips";
|
|
99
|
+
}, {
|
|
100
|
+
readonly label: "Outer lips (mouth included)";
|
|
101
|
+
readonly value: "outer-lips";
|
|
102
|
+
}];
|
|
103
|
+
}, {
|
|
104
|
+
readonly key: "colorMode";
|
|
105
|
+
readonly label: "Color mode";
|
|
106
|
+
readonly type: "select";
|
|
107
|
+
readonly options: [{
|
|
108
|
+
readonly label: "Design texture";
|
|
109
|
+
readonly value: "texture";
|
|
110
|
+
}, {
|
|
111
|
+
readonly label: "Procedural (solid / gradient)";
|
|
112
|
+
readonly value: "solid";
|
|
113
|
+
}];
|
|
114
|
+
}, {
|
|
115
|
+
readonly key: "color";
|
|
116
|
+
readonly label: "Tint color";
|
|
117
|
+
readonly type: "color";
|
|
118
|
+
}, {
|
|
119
|
+
readonly min: 0;
|
|
120
|
+
readonly max: 1;
|
|
121
|
+
readonly step: 0.01;
|
|
122
|
+
readonly key: "opacity";
|
|
123
|
+
readonly label: "Opacity";
|
|
124
|
+
readonly type: "number";
|
|
125
|
+
}, {
|
|
126
|
+
readonly min: 0;
|
|
127
|
+
readonly max: 1;
|
|
128
|
+
readonly step: 0.01;
|
|
129
|
+
readonly key: "intensity";
|
|
130
|
+
readonly label: "Tint intensity";
|
|
131
|
+
readonly type: "number";
|
|
132
|
+
}, {
|
|
133
|
+
readonly min: 0;
|
|
134
|
+
readonly max: 1;
|
|
135
|
+
readonly step: 0.01;
|
|
136
|
+
readonly key: "shading";
|
|
137
|
+
readonly label: "Skin shading";
|
|
138
|
+
readonly type: "number";
|
|
139
|
+
}, {
|
|
140
|
+
readonly min: 0;
|
|
141
|
+
readonly max: 1;
|
|
142
|
+
readonly step: 0.01;
|
|
143
|
+
readonly key: "gloss";
|
|
144
|
+
readonly label: "Gloss";
|
|
145
|
+
readonly type: "number";
|
|
146
|
+
}, {
|
|
147
|
+
readonly min: 0;
|
|
148
|
+
readonly max: 1;
|
|
149
|
+
readonly step: 0.01;
|
|
150
|
+
readonly key: "roughness";
|
|
151
|
+
readonly label: "Roughness";
|
|
152
|
+
readonly type: "number";
|
|
153
|
+
}, {
|
|
154
|
+
readonly key: "highlightColor";
|
|
155
|
+
readonly label: "Highlight color";
|
|
156
|
+
readonly type: "color";
|
|
157
|
+
}, {
|
|
158
|
+
readonly key: "gradientColor";
|
|
159
|
+
readonly label: "Gradient color";
|
|
160
|
+
readonly type: "color";
|
|
161
|
+
}, {
|
|
162
|
+
readonly min: 0;
|
|
163
|
+
readonly max: 1;
|
|
164
|
+
readonly step: 0.01;
|
|
165
|
+
readonly key: "gradientAmount";
|
|
166
|
+
readonly label: "Gradient amount";
|
|
167
|
+
readonly type: "number";
|
|
168
|
+
}, {
|
|
169
|
+
readonly key: "gradientDirection";
|
|
170
|
+
readonly label: "Gradient direction";
|
|
171
|
+
readonly type: "select";
|
|
172
|
+
readonly options: [{
|
|
173
|
+
readonly label: "Mouth line → outer edge";
|
|
174
|
+
readonly value: "outward";
|
|
175
|
+
}, {
|
|
176
|
+
readonly label: "Bottom → top";
|
|
177
|
+
readonly value: "vertical";
|
|
178
|
+
}, {
|
|
179
|
+
readonly label: "Left → right";
|
|
180
|
+
readonly value: "horizontal";
|
|
181
|
+
}];
|
|
182
|
+
}, {
|
|
183
|
+
readonly min: 0;
|
|
184
|
+
readonly max: 1;
|
|
185
|
+
readonly step: 0.01;
|
|
186
|
+
readonly key: "edgeSoftness";
|
|
187
|
+
readonly label: "Edge softness";
|
|
188
|
+
readonly type: "number";
|
|
189
|
+
}, {
|
|
190
|
+
readonly key: "innerLipColor";
|
|
191
|
+
readonly label: "Inner lip color";
|
|
192
|
+
readonly type: "color";
|
|
193
|
+
}, {
|
|
194
|
+
readonly min: 0;
|
|
195
|
+
readonly max: 1;
|
|
196
|
+
readonly step: 0.01;
|
|
197
|
+
readonly key: "innerLipAmount";
|
|
198
|
+
readonly label: "Inner lip amount";
|
|
199
|
+
readonly type: "number";
|
|
200
|
+
}, {
|
|
201
|
+
readonly min: 0;
|
|
202
|
+
readonly max: 1;
|
|
203
|
+
readonly step: 0.01;
|
|
204
|
+
readonly key: "innerLipWidth";
|
|
205
|
+
readonly label: "Inner lip width";
|
|
206
|
+
readonly type: "number";
|
|
207
|
+
}, {
|
|
208
|
+
readonly key: "splitLips";
|
|
209
|
+
readonly label: "Separate lower lip";
|
|
210
|
+
readonly type: "boolean";
|
|
211
|
+
}, {
|
|
212
|
+
readonly key: "lowerLipColor";
|
|
213
|
+
readonly label: "Lower lip color";
|
|
214
|
+
readonly type: "color";
|
|
215
|
+
}, {
|
|
216
|
+
readonly min: 0;
|
|
217
|
+
readonly max: 1;
|
|
218
|
+
readonly step: 0.01;
|
|
219
|
+
readonly key: "lowerLipOpacity";
|
|
220
|
+
readonly label: "Lower lip opacity";
|
|
221
|
+
readonly type: "number";
|
|
222
|
+
}, {
|
|
223
|
+
readonly key: "textureScaleX";
|
|
224
|
+
readonly label: "Texture scale X";
|
|
225
|
+
readonly type: "number";
|
|
226
|
+
readonly min: 0.1;
|
|
227
|
+
readonly max: 10;
|
|
228
|
+
readonly step: 0.05;
|
|
229
|
+
}, {
|
|
230
|
+
readonly key: "textureScaleY";
|
|
231
|
+
readonly label: "Texture scale Y";
|
|
232
|
+
readonly type: "number";
|
|
233
|
+
readonly min: 0.1;
|
|
234
|
+
readonly max: 10;
|
|
235
|
+
readonly step: 0.05;
|
|
236
|
+
}, {
|
|
237
|
+
readonly key: "textureOffsetX";
|
|
238
|
+
readonly label: "Texture offset X";
|
|
239
|
+
readonly type: "number";
|
|
240
|
+
readonly min: -1;
|
|
241
|
+
readonly max: 1;
|
|
242
|
+
readonly step: 0.01;
|
|
243
|
+
}, {
|
|
244
|
+
readonly key: "textureOffsetY";
|
|
245
|
+
readonly label: "Texture offset Y";
|
|
246
|
+
readonly type: "number";
|
|
247
|
+
readonly min: -1;
|
|
248
|
+
readonly max: 1;
|
|
249
|
+
readonly step: 0.01;
|
|
250
|
+
}, {
|
|
251
|
+
readonly key: "textureRotation";
|
|
252
|
+
readonly label: "Texture rotation°";
|
|
253
|
+
readonly type: "number";
|
|
254
|
+
readonly min: -180;
|
|
255
|
+
readonly max: 180;
|
|
256
|
+
readonly step: 1;
|
|
257
|
+
}, {
|
|
258
|
+
readonly key: "textureFlipX";
|
|
259
|
+
readonly label: "Flip horizontal";
|
|
260
|
+
readonly type: "boolean";
|
|
261
|
+
}, {
|
|
262
|
+
readonly key: "textureFlipY";
|
|
263
|
+
readonly label: "Flip vertical";
|
|
264
|
+
readonly type: "boolean";
|
|
265
|
+
}];
|
|
266
|
+
/**
|
|
267
|
+
* The UV-space sampling matrix for the design texture: `designUv = M * [u, v, 1]`.
|
|
268
|
+
* It is the inverse of the visual transform (scale, rotate, offset, flip
|
|
269
|
+
* about the lip region centre), so the design moves the way the settings read.
|
|
270
|
+
*/
|
|
271
|
+
export declare const createLipTextureTransform: (settings: Pick<LipEffectSettings, "textureScaleX" | "textureScaleY" | "textureOffsetX" | "textureOffsetY" | "textureRotation" | "textureFlipX" | "textureFlipY">, bounds: LipUvBounds, target?: THREE.Matrix3) => THREE.Matrix3;
|
|
@@ -1,22 +1,69 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import { LipEffectSettings } from './settings';
|
|
3
|
+
import { LipUvBounds } from './uvGuide';
|
|
2
4
|
import type * as THREE from "three";
|
|
3
5
|
export type LipMaskMode = "outer-lips" | "outer-and-inner-lips";
|
|
6
|
+
/**
|
|
7
|
+
* Stable inputs handed to a custom lip material factory. The default
|
|
8
|
+
* `LipEffectMaterial` is built from exactly these.
|
|
9
|
+
*/
|
|
4
10
|
export type LipEffectMaterialContext = {
|
|
11
|
+
/** Live camera frame; sample it with `faceUv` to read the skin under the lips. */
|
|
5
12
|
cameraTexture: THREE.Texture | null;
|
|
13
|
+
/** The creator's design texture in canonical face UV space, or `null` when none was given. */
|
|
6
14
|
designTexture: THREE.Texture | null;
|
|
7
|
-
|
|
8
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Live per-vertex camera-texture UVs. The same attribute is bound to the lip
|
|
17
|
+
* geometry as `attribute vec2 faceUv`, so a custom vertex shader can read it
|
|
18
|
+
* directly; the object is exposed for uniforms, debugging, or readback.
|
|
19
|
+
*/
|
|
20
|
+
faceUv: THREE.BufferAttribute;
|
|
21
|
+
/** Static per-vertex lip band position, bound as `attribute float lipEdge` (0 outer ring, 1 mouth line). */
|
|
22
|
+
lipEdge: THREE.BufferAttribute;
|
|
23
|
+
/** Design texture for the lower lip when `splitLips` is on, or `null`. */
|
|
24
|
+
lowerDesignTexture: THREE.Texture | null;
|
|
9
25
|
faceIndex: number;
|
|
26
|
+
/** The active mask mode, so a custom material can decide whether to honour the mouth stencil. */
|
|
27
|
+
maskMode: LipMaskMode;
|
|
28
|
+
/** Lip region of the canonical UV atlas, for texture transforms and gradients. */
|
|
29
|
+
lipUvBounds: LipUvBounds;
|
|
30
|
+
/** The resolved settings driving the built-in material. */
|
|
31
|
+
settings: LipEffectSettings;
|
|
10
32
|
};
|
|
11
|
-
|
|
12
|
-
export type
|
|
33
|
+
/** A material node, or a three.js material instance (which can be shared across meshes and faces). */
|
|
34
|
+
export type LipEffectMaterialResult = ReactNode | THREE.Material;
|
|
35
|
+
export type LipEffectMaterialSpec = LipEffectMaterialResult | ((context: LipEffectMaterialContext) => LipEffectMaterialResult);
|
|
36
|
+
export type LipEffectProps = Partial<LipEffectSettings> & {
|
|
13
37
|
faceIndex?: number;
|
|
38
|
+
/** Design texture in canonical face UV space. Without one the lips are filled with `color`. */
|
|
14
39
|
designTexture?: THREE.Texture | string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
intensity?: number;
|
|
18
|
-
maskMode?: LipMaskMode;
|
|
19
|
-
shading?: boolean;
|
|
40
|
+
/** Lower-lip design texture, used when `splitLips` is on. Falls back to `designTexture`. */
|
|
41
|
+
lowerDesignTexture?: THREE.Texture | string;
|
|
20
42
|
material?: LipEffectMaterialSpec;
|
|
43
|
+
/**
|
|
44
|
+
* Use this material instead of the built-in one (and instead of `material`),
|
|
45
|
+
* for example one from `useLipEffectMaterial` shared by several faces.
|
|
46
|
+
*/
|
|
47
|
+
sharedMaterial?: THREE.Material;
|
|
48
|
+
/** Cap how often the lip mesh follows the landmarks; omit to update every frame. */
|
|
49
|
+
maxUpdateFps?: number;
|
|
50
|
+
/** Keep the lips on the last landmarks for this long (ms) across tracker dropouts. Default 250. */
|
|
51
|
+
holdMs?: number;
|
|
52
|
+
/** While held, extrapolate the landmarks along their last velocity for up to this long (ms). Default 0. */
|
|
53
|
+
predictMs?: number;
|
|
54
|
+
renderOrder?: number;
|
|
55
|
+
};
|
|
56
|
+
/** Per-face configuration for `LipEffects`: everything but the face index. */
|
|
57
|
+
export type LipEffectFaceConfig = Omit<LipEffectProps, "faceIndex">;
|
|
58
|
+
export type LipEffectsProps = {
|
|
59
|
+
/** How many face slots to render. Match the tracker's `numFaces`. Default 2. */
|
|
60
|
+
maxFaces?: number;
|
|
61
|
+
/** One config for all faces, or a picker per face (`null` skips a face). */
|
|
62
|
+
faces: LipEffectFaceConfig | ((faceIndex: number) => LipEffectFaceConfig | null);
|
|
63
|
+
/** Share one built-in material across faces. Default: on for a single config, off for a picker. */
|
|
64
|
+
shareMaterial?: boolean;
|
|
65
|
+
maxUpdateFps?: number;
|
|
66
|
+
holdMs?: number;
|
|
67
|
+
predictMs?: number;
|
|
21
68
|
renderOrder?: number;
|
|
22
69
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
export type LipDesignTextureSource = THREE.Texture | string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the design texture props (URL or texture object) to textures.
|
|
5
|
+
* URLs load through R3F's loader cache, so faces sharing a URL share one
|
|
6
|
+
* texture; a constant hook count keeps the pair reloadable.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useLipDesignTextures: (designTexture: LipDesignTextureSource, lowerDesignTexture: LipDesignTextureSource) => {
|
|
9
|
+
designTexture: THREE.Texture | null;
|
|
10
|
+
lowerDesignTexture: THREE.Texture | null;
|
|
11
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ParsedCanonicalMesh } from '../FaceMesh/canonical/parseCanonicalFaceModel';
|
|
2
|
+
/** Lip extent in canonical UV space (`v` grows upward, as in the OBJ). */
|
|
3
|
+
export type LipUvBounds = {
|
|
4
|
+
minU: number;
|
|
5
|
+
maxU: number;
|
|
6
|
+
minV: number;
|
|
7
|
+
maxV: number;
|
|
8
|
+
/** `v` of the mouth line (mean of the inner ring); above it is the upper lip. */
|
|
9
|
+
mouthV: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Lip region of the canonical mesh that ships with the SDK, in UV space.
|
|
13
|
+
* Used until the mesh has loaded; `getLipUvBounds(mesh)` is authoritative.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CANONICAL_LIP_UV_BOUNDS: LipUvBounds;
|
|
16
|
+
export type LipUvGuideOptions = {
|
|
17
|
+
/** Pixel size of the square texture canvas the guide represents. Default 1024. */
|
|
18
|
+
size?: number;
|
|
19
|
+
/** Frame the whole canvas (the design contract) or zoom onto the lip region. Default "canvas". */
|
|
20
|
+
region?: "canvas" | "lips";
|
|
21
|
+
/** Draw the lip triangle wireframe. Default true. */
|
|
22
|
+
wireframe?: boolean;
|
|
23
|
+
/** Draw orientation and region labels. Default true. */
|
|
24
|
+
labels?: boolean;
|
|
25
|
+
/** Fill the canvas with a colour. Omit for a transparent background. */
|
|
26
|
+
background?: string;
|
|
27
|
+
};
|
|
28
|
+
export declare const LIP_UV_GUIDE_COLORS: {
|
|
29
|
+
outerRing: string;
|
|
30
|
+
innerRing: string;
|
|
31
|
+
wireframe: string;
|
|
32
|
+
text: string;
|
|
33
|
+
frame: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Convert a canonical UV to texture pixel space. `TextureLoader` textures are
|
|
37
|
+
* `flipY`, so `v = 1` is the top row of the image.
|
|
38
|
+
*/
|
|
39
|
+
export declare const lipUvToPixel: (u: number, v: number, size: number) => {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
};
|
|
43
|
+
/** Bounding box of the outer lip ring in canonical UV space, plus the mouth line. */
|
|
44
|
+
export declare const getLipUvBounds: (mesh: ParsedCanonicalMesh) => LipUvBounds;
|
|
45
|
+
/**
|
|
46
|
+
* Render a creator-facing lip UV template as an SVG string, derived from the
|
|
47
|
+
* mesh's own `uv` attribute. It shows the texture canvas, the outer-lip and
|
|
48
|
+
* inner-mouth rings, the lip triangles that are actually sampled, and which
|
|
49
|
+
* side of the image lands on which side of the subject's mouth.
|
|
50
|
+
*/
|
|
51
|
+
export declare const createLipUvGuideSvg: (mesh: ParsedCanonicalMesh, options?: LipUvGuideOptions) => string;
|
|
52
|
+
/** The guide as an `image/svg+xml` data URL, loadable with `THREE.TextureLoader` or an `<img>`. */
|
|
53
|
+
export declare const createLipUvGuideDataUrl: (mesh: ParsedCanonicalMesh, options?: LipUvGuideOptions) => string;
|
|
54
|
+
/**
|
|
55
|
+
* Rasterize the guide to a PNG `Blob` in the browser (an `<img>` and a 2D
|
|
56
|
+
* canvas), for download or for use as a texture. Transparent unless
|
|
57
|
+
* `options.background` is set.
|
|
58
|
+
*/
|
|
59
|
+
export declare const createLipUvGuidePngBlob: (mesh: ParsedCanonicalMesh, options?: LipUvGuideOptions) => Promise<Blob>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ScreenImageProps } from '../ScreenImage/types';
|
|
2
|
+
import { PersonCutoutFallback, PersonCutoutStatus } from './personCutout';
|
|
3
|
+
import type * as THREE from "three";
|
|
4
|
+
export type { PersonCutoutFallback, PersonCutoutStatus } from './personCutout';
|
|
5
|
+
export { FULL_SCREEN_ANCHORS, resolvePersonCutoutStatus, shouldDrawFallback } from './personCutout';
|
|
6
|
+
export type PersonMaskTextureResult = {
|
|
7
|
+
/**
|
|
8
|
+
* The portrait segmentation mask in feed space. The signal is in RGB:
|
|
9
|
+
* white (255) on the person, black (0) on the background, alpha 255
|
|
10
|
+
* everywhere (measured; three's `alphaMap` reads green, which is how
|
|
11
|
+
* `VideoBackground` consumes it).
|
|
12
|
+
*/
|
|
13
|
+
texture: THREE.Texture | null;
|
|
14
|
+
status: PersonCutoutStatus;
|
|
15
|
+
error: Error | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The portrait segmentation mask as a texture, with the model's lifecycle.
|
|
19
|
+
* Acquires the segmentation model itself. The mask lives in feed space, like
|
|
20
|
+
* the camera texture; read its green channel: 255 on the person, 0 elsewhere.
|
|
21
|
+
*/
|
|
22
|
+
export declare const usePersonMaskTexture: (active?: boolean) => PersonMaskTextureResult;
|
|
23
|
+
export type PersonCutoutProps = Omit<ScreenImageProps, "source" | "src" | "maskTexture" | "maskChannel" | "maskInvert"> & {
|
|
24
|
+
/** Edge softening as a 3×3 blur radius in mask texels. Default 4; 0 = hard edge. */
|
|
25
|
+
maskFeather?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Shrink the kept silhouette into the feathered edge (0..1 of the feather
|
|
28
|
+
* width) so background fringe from the segmenter is trimmed. Default 0.7.
|
|
29
|
+
*/
|
|
30
|
+
maskErode?: number;
|
|
31
|
+
/** Show the background only (cut the person out) instead of the person only. */
|
|
32
|
+
invert?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* What to draw while the segmentation model is loading or has failed:
|
|
35
|
+
* the unmasked camera (default, the experience degrades to a plain feed)
|
|
36
|
+
* or nothing.
|
|
37
|
+
*/
|
|
38
|
+
fallback?: PersonCutoutFallback;
|
|
39
|
+
/** Keep the segmentation model running. Default true. */
|
|
40
|
+
active?: boolean;
|
|
41
|
+
onStatusChange?: (status: PersonCutoutStatus, error: Error | null) => void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The live camera, masked to the person, as a full-screen `ScreenImage`.
|
|
45
|
+
* Place any `ScreenImage` (image, video, GIF) or shader surface behind it
|
|
46
|
+
* with a lower `renderOrder` for background replacement. The camera texture is
|
|
47
|
+
* already cover-cropped and webcam-mirrored by the session, and the mask is in
|
|
48
|
+
* that same space, so no coordinate work is needed.
|
|
49
|
+
*/
|
|
50
|
+
export declare const PersonCutout: ({ invert, fallback, active, onStatusChange, fit, anchors, renderOrder, visible, maskFeather, maskErode, ...screenImageProps }: PersonCutoutProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ScreenAnchorEdges } from '../ScreenSpaceUI';
|
|
2
|
+
/** Anchors that stretch a screen element over the whole viewport. */
|
|
3
|
+
export declare const FULL_SCREEN_ANCHORS: ScreenAnchorEdges;
|
|
4
|
+
export type PersonCutoutStatus = "loading" | "ready" | "error";
|
|
5
|
+
/**
|
|
6
|
+
* Status of a person cut-out from the segmentation model's lifecycle and
|
|
7
|
+
* whether its mask texture exists yet.
|
|
8
|
+
*/
|
|
9
|
+
export declare const resolvePersonCutoutStatus: ({ ready, error, hasMask, }: {
|
|
10
|
+
ready: boolean;
|
|
11
|
+
error: Error | null;
|
|
12
|
+
hasMask: boolean;
|
|
13
|
+
}) => PersonCutoutStatus;
|
|
14
|
+
export type PersonCutoutFallback = "camera" | "hidden";
|
|
15
|
+
/** Whether the camera layer should draw while the mask is not available. */
|
|
16
|
+
export declare const shouldDrawFallback: (status: PersonCutoutStatus, fallback: PersonCutoutFallback) => boolean;
|
|
@@ -5,5 +5,5 @@ type ScreenImageBodyProps = Omit<ScreenImageProps, "anchors" | "coordinateSpace"
|
|
|
5
5
|
height: number;
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
|
-
export declare function ScreenImageBody({ name, source, src, fit, stretchMode, materialType, blendMode, backdropTexture: providedBackdropTexture, rotation, opacity, color, flipX, flipY, renderOrder, transparent, alphaTest, overlay, visible, layoutSize, }: ScreenImageBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function ScreenImageBody({ name, source, src, fit, stretchMode, materialType, blendMode, backdropTexture: providedBackdropTexture, rotation, opacity, color, maskTexture, maskChannel, maskInvert, maskFeather, maskErode, flipX, flipY, renderOrder, transparent, alphaTest, overlay, visible, layoutSize, }: ScreenImageBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { ScreenImage, defaultScreenImageUrl } from './ScreenImage';
|
|
2
2
|
export { screenImageBlendModeOptions } from './utils/ScreenImageConstants';
|
|
3
3
|
export { resolveBlendProps } from './materials/ScreenImageBlendMaterial';
|
|
4
|
+
export { SCREEN_IMAGE_MASK_CHANNELS, resolveMaskChannelIndex, } from './materials/ScreenImageMaskMaterial';
|
|
5
|
+
export type { ScreenImageMaskChannel } from './materials/ScreenImageMaskMaterial';
|
|
4
6
|
export type { ScreenImageBlendMode, ScreenImageMaterialType, ScreenImageProps } from './types';
|
|
5
7
|
export type { ScreenImageSource } from './source';
|
|
6
|
-
export { getScreenImageTextureAspect, getScreenImageTextureSize, resolveScreenImageSource, } from './source';
|
|
8
|
+
export { getScreenImageTextureAspect, getScreenImageTextureSize, isDynamicScreenImageTexture, resolveScreenImageSource, } from './source';
|
|
7
9
|
export { computeScreenImageFitResolution, computeScreenImageFittedRect, resolveScreenImageStretchMode, } from './fit';
|
|
8
10
|
export type { ScreenImageFit, ScreenImageFittedRect, ScreenImageFittedRectInput, ScreenImageStretchMode, } from './fit';
|
|
@@ -6,4 +6,4 @@ export declare const advancedBlendModeIndices: Record<AdvancedBlendMode, number>
|
|
|
6
6
|
export type BlendMaterialProps = Partial<Pick<THREE.Material, "blending" | "blendSrc" | "blendDst" | "blendEquation">>;
|
|
7
7
|
export declare const resolveBlendProps: (mode: ScreenImageBlendMode) => BlendMaterialProps;
|
|
8
8
|
export declare const advancedBlendVertexShader = "\nvarying vec2 vUv;\nvoid main(){vUv=uv;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}";
|
|
9
|
-
export declare const advancedBlendFragmentShader = "\nuniform sampler2D imageMap;uniform sampler2D backdropMap;uniform vec2 resolution;\nuniform vec3 tint;uniform float opacity;uniform float alphaTest;uniform int blendMode;varying vec2 vUv;\nfloat overlayChannel(float b,float s){return b<.5?2.*b*s:1.-2.*(1.-b)*(1.-s);}\nfloat hardLightChannel(float b,float s){return s<.5?2.*b*s:1.-2.*(1.-b)*(1.-s);}\nfloat softLightChannel(float b,float s){return s<.5?b-(1.-2.*s)*b*(1.-b):b+(2.*s-1.)*(sqrt(max(b,0.))-b);}\nvec3 applyAdvancedBlend(vec3 b,vec3 s){\nif(blendMode==0)return vec3(overlayChannel(b.r,s.r),overlayChannel(b.g,s.g),overlayChannel(b.b,s.b));\nif(blendMode==1)return vec3(softLightChannel(b.r,s.r),softLightChannel(b.g,s.g),softLightChannel(b.b,s.b));\nif(blendMode==2)return vec3(hardLightChannel(b.r,s.r),hardLightChannel(b.g,s.g),hardLightChannel(b.b,s.b));\nif(blendMode==3)return abs(b-s);return b+s-2.*b*s;}\nvoid main(){vec4 image=texture2D(imageMap,vUv)*vec4(tint,opacity);if(image.a<=alphaTest)discard;\nvec2 uv=gl_FragCoord.xy/max(resolution,vec2(1.));vec3 base=texture2D(backdropMap,uv).rgb;\nvec3 mixed=applyAdvancedBlend(base,image.rgb);gl_FragColor=vec4(mix(base,mixed,image.a),1.)
|
|
9
|
+
export declare const advancedBlendFragmentShader = "\nuniform sampler2D imageMap;uniform sampler2D backdropMap;uniform vec2 resolution;\nuniform vec3 tint;uniform float opacity;uniform float alphaTest;uniform int blendMode;varying vec2 vUv;\nfloat overlayChannel(float b,float s){return b<.5?2.*b*s:1.-2.*(1.-b)*(1.-s);}\nfloat hardLightChannel(float b,float s){return s<.5?2.*b*s:1.-2.*(1.-b)*(1.-s);}\nfloat softLightChannel(float b,float s){return s<.5?b-(1.-2.*s)*b*(1.-b):b+(2.*s-1.)*(sqrt(max(b,0.))-b);}\nvec3 applyAdvancedBlend(vec3 b,vec3 s){\nif(blendMode==0)return vec3(overlayChannel(b.r,s.r),overlayChannel(b.g,s.g),overlayChannel(b.b,s.b));\nif(blendMode==1)return vec3(softLightChannel(b.r,s.r),softLightChannel(b.g,s.g),softLightChannel(b.b,s.b));\nif(blendMode==2)return vec3(hardLightChannel(b.r,s.r),hardLightChannel(b.g,s.g),hardLightChannel(b.b,s.b));\nif(blendMode==3)return abs(b-s);return b+s-2.*b*s;}\nvoid main(){vec4 image=texture2D(imageMap,vUv)*vec4(tint,opacity);if(image.a<=alphaTest)discard;\nvec2 uv=gl_FragCoord.xy/max(resolution,vec2(1.));vec3 base=texture2D(backdropMap,uv).rgb;\nvec3 mixed=applyAdvancedBlend(base,image.rgb);gl_FragColor=vec4(mix(base,mixed,image.a),1.);\n#include <colorspace_fragment>\n}";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Which channel of a `maskTexture` carries coverage. */
|
|
2
|
+
export declare const SCREEN_IMAGE_MASK_CHANNELS: readonly ["alpha", "red", "green", "luminance"];
|
|
3
|
+
export type ScreenImageMaskChannel = (typeof SCREEN_IMAGE_MASK_CHANNELS)[number];
|
|
4
|
+
export declare const resolveMaskChannelIndex: (channel: ScreenImageMaskChannel | undefined) => number;
|
|
5
|
+
export declare const maskedVertexShader = "\nvarying vec2 vUv;\nvoid main(){vUv=uv;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}";
|
|
6
|
+
/**
|
|
7
|
+
* Image × mask. Both are sampled through the image's fit transform (repeat /
|
|
8
|
+
* offset / flips), so a mask authored in the image's own space — a camera
|
|
9
|
+
* frame and its segmentation mask — stays aligned under cover-cropping.
|
|
10
|
+
*/
|
|
11
|
+
export declare const maskedFragmentShader = "\nuniform sampler2D imageMap;uniform sampler2D maskMap;uniform mat3 mapTransform;\nuniform vec3 tint;uniform float opacity;uniform float alphaTest;uniform int maskChannel;uniform float maskInvert;\nuniform float maskFeather;uniform float maskErode;uniform vec2 maskTexel;\nvarying vec2 vUv;\nfloat coverageAt(vec2 uv){\nvec4 m=texture2D(maskMap,uv);\nfloat c=maskChannel==0?m.a:maskChannel==1?m.r:maskChannel==2?m.g:dot(m.rgb,vec3(0.299,0.587,0.114));\nreturn mix(c,1.0-c,maskInvert);}\nvoid main(){\nvec2 uv=(mapTransform*vec3(vUv,1.0)).xy;\nvec4 image=texture2D(imageMap,uv);\nfloat coverage;\nif(maskFeather>0.0){\nvec2 step=maskTexel*maskFeather;\ncoverage=0.0;\nfor(int y=-1;y<=1;y++){for(int x=-1;x<=1;x++){coverage+=coverageAt(uv+vec2(float(x),float(y))*step);}}\ncoverage/=9.0;\n// Erode: raise the threshold on the blurred edge so the silhouette shrinks\n// by up to the feather radius (maskErode is a fraction of that width).\ncoverage=smoothstep(clamp(maskErode,0.0,0.95),1.0,coverage);\n}else{coverage=coverageAt(uv);}\nfloat alpha=image.a*opacity*coverage;\nif(alpha<=alphaTest)discard;\ngl_FragColor=vec4(image.rgb*tint,alpha);\n#include <colorspace_fragment>\n}";
|
|
@@ -16,4 +16,10 @@ export declare const getScreenImageTextureSize: (texture: THREE.Texture) => {
|
|
|
16
16
|
width: number;
|
|
17
17
|
height: number;
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Textures whose pixels change after upload: videos and any canvas-backed
|
|
21
|
+
* texture, including `OffscreenCanvas` sources such as the session camera
|
|
22
|
+
* feed. These need `needsUpdate` every frame to stay live.
|
|
23
|
+
*/
|
|
24
|
+
export declare const isDynamicScreenImageTexture: (texture: THREE.Texture) => boolean;
|
|
19
25
|
export declare const getScreenImageTextureAspect: (texture: THREE.Texture) => number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ScreenAnchorEdges, ScreenOffsetEdges, ScreenTransformGuideLayer } from '../ScreenSpaceUI';
|
|
2
2
|
import { ScreenCanvasSize, ScreenCoordinateSpace, ScreenTransform2DSettings } from '../../screen2d';
|
|
3
3
|
import { ScreenImageFit, ScreenImageStretchMode } from './fit';
|
|
4
|
+
import { ScreenImageMaskChannel } from './materials/ScreenImageMaskMaterial';
|
|
4
5
|
import { ScreenImageSource } from './source';
|
|
5
6
|
import type * as THREE from "three";
|
|
6
7
|
export type ScreenImageMaterialType = "unlit" | "standardPBR" | "matcap";
|
|
@@ -27,6 +28,23 @@ export type ScreenImageProps = {
|
|
|
27
28
|
backdropTexture?: THREE.Texture | null;
|
|
28
29
|
opacity?: number;
|
|
29
30
|
color?: THREE.ColorRepresentation;
|
|
31
|
+
/**
|
|
32
|
+
* Alpha mask in the image's own texture space: it is sampled through the
|
|
33
|
+
* same fit / crop / flip transform as the image, so a camera frame and its
|
|
34
|
+
* segmentation mask stay aligned. Takes precedence over advanced blend modes.
|
|
35
|
+
*/
|
|
36
|
+
maskTexture?: THREE.Texture | null;
|
|
37
|
+
/** Channel of `maskTexture` that carries coverage. Default `"alpha"`. */
|
|
38
|
+
maskChannel?: ScreenImageMaskChannel;
|
|
39
|
+
/** Keep where the mask is 0 instead of 1. */
|
|
40
|
+
maskInvert?: boolean;
|
|
41
|
+
/** Soften mask edges: 3×3 blur radius in mask texels. 0 = hard. */
|
|
42
|
+
maskFeather?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Shrink the kept region into the feathered edge, 0..1 of the feather
|
|
45
|
+
* width; removes fringe from the source. Needs `maskFeather` > 0.
|
|
46
|
+
*/
|
|
47
|
+
maskErode?: number;
|
|
30
48
|
flipX?: boolean;
|
|
31
49
|
flipY?: boolean;
|
|
32
50
|
renderOrder?: number;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SemanticMask } from '../../segmentation2d/types';
|
|
3
|
+
import { SegmentationOverlaySettings } from './settings';
|
|
4
|
+
import * as THREE from "three";
|
|
5
|
+
export type SegmentationOverlayMaterialContext = {
|
|
6
|
+
cameraTexture: THREE.Texture | null;
|
|
7
|
+
/**
|
|
8
|
+
* Class-index texture (red channel, 0..255 → index); nearest-filtered.
|
|
9
|
+
* Re-allocated when the mask changes size; the factory is re-run with the
|
|
10
|
+
* new texture, so read it from the context rather than caching it.
|
|
11
|
+
*/
|
|
12
|
+
maskTexture: THREE.Texture;
|
|
13
|
+
/** Feed UV → mask UV, including the row flip, mirror and source cover-fit. */
|
|
14
|
+
maskTransform: THREE.Matrix3;
|
|
15
|
+
/** Class indices the overlay selects, resolved from `label` against the mask; empty until the mask has data. */
|
|
16
|
+
labelIndices: number[];
|
|
17
|
+
mask: SemanticMask | null;
|
|
18
|
+
settings: SegmentationOverlaySettings;
|
|
19
|
+
};
|
|
20
|
+
export type SegmentationOverlayMaterialSpec = ReactNode | THREE.Material | ((context: SegmentationOverlayMaterialContext) => ReactNode | THREE.Material);
|
|
21
|
+
export type SegmentationOverlayProps = Partial<SegmentationOverlaySettings> & {
|
|
22
|
+
/** The mask to draw from: a provider hook's result or your own `SemanticMask`. */
|
|
23
|
+
mask: SemanticMask | null;
|
|
24
|
+
/** Optional image multiplied into the paint, sampled in screen UV (cover of the viewport). */
|
|
25
|
+
texture?: THREE.Texture | string;
|
|
26
|
+
/** Custom material (node, instance, or factory). Replaces the built-in look. */
|
|
27
|
+
material?: SegmentationOverlayMaterialSpec;
|
|
28
|
+
/** Default: just above the video background. */
|
|
29
|
+
renderOrder?: number;
|
|
30
|
+
visible?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Draw one or more semantic regions of a mask as a screen-aligned 2D layer,
|
|
34
|
+
* tinted and composited over the camera feed. Covers the viewport exactly
|
|
35
|
+
* like `VideoBackground`, so feed-space masks need no coordinate work.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SegmentationOverlay: ({ mask, texture, material, renderOrder, visible, ...settingsInput }: SegmentationOverlayProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SemanticMask } from '../../segmentation2d/types';
|
|
2
|
+
import { SegmentationOverlaySettings } from './settings';
|
|
3
|
+
import * as THREE from "three";
|
|
4
|
+
/** Up to this many labels can be selected by one overlay. */
|
|
5
|
+
export declare const MAX_OVERLAY_LABELS = 4;
|
|
6
|
+
export type SegmentationOverlayMaterialInputs = {
|
|
7
|
+
cameraTexture: THREE.Texture | null;
|
|
8
|
+
maskTexture: THREE.Texture;
|
|
9
|
+
mask: SemanticMask | null;
|
|
10
|
+
settings: SegmentationOverlaySettings;
|
|
11
|
+
/** Optional image sampled in screen UV and multiplied into the paint. */
|
|
12
|
+
designTexture?: THREE.Texture | null;
|
|
13
|
+
/** Feed (camera texture) size, for cover-fitting source-space masks. */
|
|
14
|
+
feedWidth?: number;
|
|
15
|
+
feedHeight?: number;
|
|
16
|
+
};
|
|
17
|
+
export declare const SEGMENTATION_OVERLAY_VERTEX_SHADER = "\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}";
|
|
18
|
+
export declare const SEGMENTATION_OVERLAY_FRAGMENT_SHADER = "\nuniform sampler2D cameraTexture;\nuniform sampler2D maskTexture;\nuniform sampler2D designTexture;\nuniform float useDesign;\nuniform vec4 labels;\nuniform float labelCount;\nuniform float invert;\nuniform vec3 tint;\nuniform float opacity;\nuniform float blendMode;\nuniform float feather;\nuniform vec2 maskTexel;\nuniform mat3 maskTransform;\nvarying vec2 vUv;\n\nfloat member(vec2 uv) {\n if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 0.0;\n float index = floor(texture2D(maskTexture, uv).r * 255.0 + 0.5);\n float m = 0.0;\n if (labelCount > 0.5 && abs(index - labels.x) < 0.5) m = 1.0;\n if (labelCount > 1.5 && abs(index - labels.y) < 0.5) m = 1.0;\n if (labelCount > 2.5 && abs(index - labels.z) < 0.5) m = 1.0;\n if (labelCount > 3.5 && abs(index - labels.w) < 0.5) m = 1.0;\n return invert > 0.5 ? 1.0 - m : m;\n}\n\nvoid main() {\n vec2 maskUv = (maskTransform * vec3(vUv, 1.0)).xy;\n float coverage;\n if (feather > 0.0) {\n vec2 step = maskTexel * feather;\n coverage = 0.0;\n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n coverage += member(maskUv + vec2(float(x), float(y)) * step);\n }\n }\n coverage /= 9.0;\n } else {\n coverage = member(maskUv);\n }\n\n vec3 base = texture2D(cameraTexture, vUv).rgb;\n vec4 design = useDesign > 0.5 ? texture2D(designTexture, vUv) : vec4(1.0);\n vec3 paint = tint * design.rgb;\n vec3 blended = blendMode < 0.5\n ? paint\n : blendMode < 1.5\n ? base * paint\n : blendMode < 2.5\n ? 1.0 - (1.0 - base) * (1.0 - paint)\n : mix(2.0 * base * paint, 1.0 - 2.0 * (1.0 - base) * (1.0 - paint), step(0.5, base));\n\n gl_FragColor = vec4(blended, coverage * opacity * design.a);\n #include <colorspace_fragment>\n}";
|
|
19
|
+
/** The built-in overlay material as a plain three.js object (shareable across meshes). */
|
|
20
|
+
export declare const createSegmentationOverlayMaterial: () => THREE.ShaderMaterial;
|
|
21
|
+
/** Resolve the selected labels to class indices for a mask (unknown labels are skipped). */
|
|
22
|
+
export declare const resolveOverlayLabelIndices: (mask: Pick<SemanticMask, "labels"> | null, label: string | readonly string[]) => number[];
|
|
23
|
+
/**
|
|
24
|
+
* The class indices an overlay should draw right now: the resolved labels,
|
|
25
|
+
* or none while the mask is still at `version` 0 (no data yet). Shared by
|
|
26
|
+
* the built-in material and the custom-material context so both agree.
|
|
27
|
+
*/
|
|
28
|
+
export declare const resolveActiveOverlayLabelIndices: (mask: SemanticMask | null, label: string | readonly string[]) => number[];
|
|
29
|
+
export declare const updateSegmentationOverlayMaterial: (material: THREE.ShaderMaterial, { cameraTexture, maskTexture, mask, settings, designTexture, feedWidth, feedHeight, }: SegmentationOverlayMaterialInputs) => THREE.ShaderMaterial;
|
|
30
|
+
/** Own one overlay material and keep it in sync with the inputs on every render. */
|
|
31
|
+
export declare const useSegmentationOverlayMaterial: (inputs: SegmentationOverlayMaterialInputs) => THREE.ShaderMaterial;
|