react-native-webrtc-kaleidoscope 2.0.0 → 2.1.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/NOTICE.md +8 -8
- package/README.md +185 -56
- package/android/build.gradle +13 -0
- package/android/src/main/java/com/simiancraft/kaleidoscope/CompositeLayers.kt +127 -0
- package/android/src/main/java/com/simiancraft/kaleidoscope/EffectTuning.kt +69 -69
- package/android/src/main/java/com/simiancraft/kaleidoscope/KaleidoscopeModule.kt +86 -33
- package/android/src/main/java/com/simiancraft/kaleidoscope/Registration.kt +23 -64
- package/android/src/main/java/com/simiancraft/kaleidoscope/effects/CompositeFactory.kt +691 -0
- package/android/src/main/java/com/simiancraft/kaleidoscope/effects/LayerShaders.kt +30 -0
- package/android/src/main/java/com/simiancraft/kaleidoscope/effects/TransformFactory.kt +248 -200
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Egl.kt +82 -70
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Fbo.kt +50 -47
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/FramePipeline.kt +106 -105
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GlDebug.kt +23 -23
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GlProgram.kt +76 -57
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Ingest.kt +92 -71
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Orientation.kt +25 -25
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Shaders.kt +57 -76
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/ShadersGenerated.kt +1162 -25
- package/android/src/main/java/com/simiancraft/kaleidoscope/segmentation/Mask.kt +254 -242
- package/android/src/main/java/com/simiancraft/kaleidoscope/segmentation/MaskTuning.kt +28 -25
- package/android/src/main/java/com/simiancraft/kaleidoscope/segmentation/SegmentationEngine.kt +104 -98
- package/android/src/test/java/com/simiancraft/kaleidoscope/CompositeLayersTest.kt +165 -0
- package/app.plugin.js +9 -255
- package/catalog/composites/clouds/clouds.controls.tsx +19 -0
- package/catalog/composites/clouds/clouds.ts +32 -0
- package/catalog/composites/corporate-blobs/corporate-blobs.controls.tsx +24 -0
- package/catalog/composites/corporate-blobs/corporate-blobs.thumb.webp +0 -0
- package/catalog/composites/corporate-blobs/corporate-blobs.ts +51 -0
- package/catalog/composites/corporate-blobs/corporate-blobs.web.ts +42 -0
- package/catalog/composites/fairy-cave/fairy-cave.controls.tsx +33 -0
- package/catalog/composites/fairy-cave/fairy-cave.thumb.webp +0 -0
- package/catalog/composites/fairy-cave/fairy-cave.ts +53 -0
- package/catalog/composites/fairy-cave/fairy-cave.web.ts +47 -0
- package/catalog/composites/fairy-grotto/fairy-grotto.controls.tsx +34 -0
- package/catalog/composites/fairy-grotto/fairy-grotto.thumb.webp +0 -0
- package/catalog/composites/fairy-grotto/fairy-grotto.ts +54 -0
- package/catalog/composites/fairy-grotto/fairy-grotto.web.ts +47 -0
- package/catalog/composites/fairy-hollow/fairy-hollow.controls.tsx +34 -0
- package/catalog/composites/fairy-hollow/fairy-hollow.thumb.webp +0 -0
- package/catalog/composites/fairy-hollow/fairy-hollow.ts +55 -0
- package/catalog/composites/fairy-hollow/fairy-hollow.web.ts +47 -0
- package/catalog/composites/nebula/nebula.controls.tsx +19 -0
- package/catalog/composites/nebula/nebula.thumb.webp +0 -0
- package/catalog/composites/nebula/nebula.ts +37 -0
- package/catalog/composites/nebula/nebula.web.ts +30 -0
- package/catalog/composites/observation-deck/observation-deck.controls.tsx +28 -0
- package/catalog/composites/observation-deck/observation-deck.thumb.webp +0 -0
- package/catalog/composites/observation-deck/observation-deck.ts +59 -0
- package/catalog/composites/observation-deck/observation-deck.web.ts +50 -0
- package/catalog/composites/simianlights/simianlights.controls.tsx +19 -0
- package/catalog/composites/simianlights/simianlights.thumb.webp +0 -0
- package/catalog/composites/simianlights/simianlights.ts +34 -0
- package/catalog/composites/simianlights/simianlights.web.ts +29 -0
- package/catalog/composites/underwater/underwater.controls.tsx +19 -0
- package/catalog/composites/underwater/underwater.thumb.webp +0 -0
- package/catalog/composites/underwater/underwater.ts +42 -0
- package/catalog/composites/underwater/underwater.web.ts +36 -0
- package/catalog/composites/wizard-tower/wizard-tower.controls.tsx +23 -0
- package/catalog/composites/wizard-tower/wizard-tower.thumb.webp +0 -0
- package/catalog/composites/wizard-tower/wizard-tower.ts +44 -0
- package/catalog/composites/wizard-tower/wizard-tower.web.ts +35 -0
- package/catalog/composites/wizard-tower-night/wizard-tower-night.controls.tsx +22 -0
- package/catalog/composites/wizard-tower-night/wizard-tower-night.thumb.webp +0 -0
- package/catalog/composites/wizard-tower-night/wizard-tower-night.ts +43 -0
- package/catalog/composites/wizard-tower-night/wizard-tower-night.web.ts +35 -0
- package/catalog/images/README.md +188 -0
- package/catalog/images/corporate/corporate-logo.thumb.webp +0 -0
- package/catalog/images/corporate/corporate-logo.ts +6 -0
- package/catalog/images/corporate/corporate-logo.web.ts +7 -0
- package/catalog/images/corporate/corporate-logo.webp +0 -0
- package/catalog/images/debug/debug-resolutions.thumb.webp +0 -0
- package/catalog/images/debug/debug-resolutions.ts +6 -0
- package/catalog/images/debug/debug-resolutions.web.ts +7 -0
- package/catalog/images/fairy-caves/grotto.thumb.webp +0 -0
- package/catalog/images/fairy-caves/grotto.ts +6 -0
- package/catalog/images/fairy-caves/grotto.web.ts +7 -0
- package/catalog/images/fairy-caves/grotto.webp +0 -0
- package/catalog/images/fairy-caves/hollow.thumb.webp +0 -0
- package/catalog/images/fairy-caves/hollow.ts +6 -0
- package/catalog/images/fairy-caves/hollow.web.ts +7 -0
- package/catalog/images/fairy-caves/hollow.webp +0 -0
- package/catalog/images/fairy-caves/treehouse-2.thumb.webp +0 -0
- package/catalog/images/fairy-caves/treehouse-2.ts +6 -0
- package/catalog/images/fairy-caves/treehouse-2.web.ts +7 -0
- package/catalog/images/fairy-caves/treehouse-2.webp +0 -0
- package/catalog/images/fairy-caves/treehouse-3.thumb.webp +0 -0
- package/catalog/images/fairy-caves/treehouse-3.ts +6 -0
- package/catalog/images/fairy-caves/treehouse-3.web.ts +7 -0
- package/catalog/images/fairy-caves/treehouse-3.webp +0 -0
- package/catalog/images/fairy-caves/treehouse.thumb.webp +0 -0
- package/catalog/images/fairy-caves/treehouse.ts +6 -0
- package/catalog/images/fairy-caves/treehouse.web.ts +7 -0
- package/catalog/images/fairy-caves/treehouse.webp +0 -0
- package/catalog/images/home/home-dark.thumb.webp +0 -0
- package/catalog/images/home/home-dark.ts +6 -0
- package/catalog/images/home/home-dark.web.ts +7 -0
- package/catalog/images/home/home-light.thumb.webp +0 -0
- package/catalog/images/home/home-light.ts +6 -0
- package/catalog/images/home/home-light.web.ts +7 -0
- package/catalog/images/image-ids.ts +42 -0
- package/catalog/images/image.types.ts +5 -0
- package/catalog/images/index.ts +7 -0
- package/catalog/images/nature/landscape-dark.thumb.webp +0 -0
- package/catalog/images/nature/landscape-dark.ts +6 -0
- package/catalog/images/nature/landscape-dark.web.ts +7 -0
- package/catalog/images/nature/landscape-light.thumb.webp +0 -0
- package/catalog/images/nature/landscape-light.ts +6 -0
- package/catalog/images/nature/landscape-light.web.ts +7 -0
- package/catalog/images/office/office-dark.thumb.webp +0 -0
- package/catalog/images/office/office-dark.ts +6 -0
- package/catalog/images/office/office-dark.web.ts +7 -0
- package/catalog/images/office/office-light.thumb.webp +0 -0
- package/catalog/images/office/office-light.ts +6 -0
- package/catalog/images/office/office-light.web.ts +7 -0
- package/catalog/images/sci-fi/sci-fi-light.thumb.webp +0 -0
- package/catalog/images/sci-fi/sci-fi-light.ts +6 -0
- package/catalog/images/sci-fi/sci-fi-light.web.ts +7 -0
- package/catalog/images/simiancraft/simiancraft-dark-transparency.thumb.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-dark-transparency.ts +6 -0
- package/catalog/images/simiancraft/simiancraft-dark-transparency.web.ts +9 -0
- package/catalog/images/simiancraft/simiancraft-dark-transparency.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-dark.thumb.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-dark.ts +6 -0
- package/catalog/images/simiancraft/simiancraft-dark.web.ts +7 -0
- package/catalog/images/simiancraft/simiancraft-light-transparency.thumb.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-light-transparency.ts +6 -0
- package/catalog/images/simiancraft/simiancraft-light-transparency.web.ts +9 -0
- package/catalog/images/simiancraft/simiancraft-light-transparency.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-light.thumb.webp +0 -0
- package/catalog/images/simiancraft/simiancraft-light.ts +6 -0
- package/catalog/images/simiancraft/simiancraft-light.web.ts +7 -0
- package/catalog/images/spaceship/observation-deck.thumb.webp +0 -0
- package/catalog/images/spaceship/observation-deck.ts +6 -0
- package/catalog/images/spaceship/observation-deck.web.ts +7 -0
- package/catalog/images/spaceship/observation-deck.webp +0 -0
- package/catalog/images/underwater/oceanscape-dark.thumb.webp +0 -0
- package/catalog/images/underwater/oceanscape-dark.ts +6 -0
- package/catalog/images/underwater/oceanscape-dark.web.ts +7 -0
- package/catalog/images/underwater/oceanscape-dark.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-1.thumb.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-1.ts +6 -0
- package/catalog/images/wizard-tower/wizard-tower-1.web.ts +7 -0
- package/catalog/images/wizard-tower/wizard-tower-1.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-2.thumb.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-2.ts +6 -0
- package/catalog/images/wizard-tower/wizard-tower-2.web.ts +7 -0
- package/catalog/images/wizard-tower/wizard-tower-2.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-night.thumb.webp +0 -0
- package/catalog/images/wizard-tower/wizard-tower-night.ts +6 -0
- package/catalog/images/wizard-tower/wizard-tower-night.web.ts +7 -0
- package/catalog/images/wizard-tower/wizard-tower-night.webp +0 -0
- package/catalog/shaders/README.md +114 -0
- package/catalog/shaders/_shared/composite-blit.frag +26 -0
- package/catalog/shaders/_shared/composite-camera.frag +17 -0
- package/catalog/shaders/_shared/composite-image.frag +23 -0
- package/catalog/shaders/_shared/composite-masked.frag +26 -0
- package/catalog/shaders/_shared/composite-subject.frag +27 -0
- package/catalog/shaders/_shared/passthrough.vert +27 -0
- package/catalog/shaders/_shared/transform.frag +27 -0
- package/catalog/shaders/_shared/types.ts +63 -0
- package/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.form.tsx +37 -0
- package/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.frag +123 -0
- package/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.ts +106 -0
- package/catalog/shaders/blur/blur.form.tsx +29 -0
- package/catalog/shaders/blur/blur.ts +32 -0
- package/catalog/shaders/blur/composite-blur.frag +42 -0
- package/catalog/shaders/clouds/clouds.form.tsx +39 -0
- package/catalog/shaders/clouds/clouds.frag +128 -0
- package/catalog/shaders/clouds/clouds.presets.md +37 -0
- package/catalog/shaders/clouds/clouds.ts +124 -0
- package/catalog/shaders/corporate-blobs/corporate-blobs.form.tsx +44 -0
- package/catalog/shaders/corporate-blobs/corporate-blobs.frag +224 -0
- package/catalog/shaders/corporate-blobs/corporate-blobs.ts +136 -0
- package/catalog/shaders/fireflies/fireflies.form.tsx +33 -0
- package/catalog/shaders/fireflies/fireflies.frag +68 -0
- package/catalog/shaders/fireflies/fireflies.ts +61 -0
- package/catalog/shaders/godrays/godrays.form.tsx +37 -0
- package/catalog/shaders/godrays/godrays.frag +85 -0
- package/catalog/shaders/godrays/godrays.ts +105 -0
- package/catalog/shaders/index.ts +78 -0
- package/catalog/shaders/light-beams-and-motes/light-beams-and-motes.form.tsx +55 -0
- package/catalog/shaders/light-beams-and-motes/light-beams-and-motes.frag +262 -0
- package/catalog/shaders/light-beams-and-motes/light-beams-and-motes.ts +137 -0
- package/catalog/shaders/nebula/nebula.form.tsx +34 -0
- package/catalog/shaders/nebula/nebula.frag +151 -0
- package/catalog/shaders/nebula/nebula.ts +74 -0
- package/catalog/shaders/plasma/plasma.form.tsx +32 -0
- package/catalog/shaders/plasma/plasma.frag +55 -0
- package/catalog/shaders/plasma/plasma.ts +44 -0
- package/catalog/shaders/simianlights/simianlights.form.tsx +34 -0
- package/catalog/shaders/simianlights/simianlights.frag +151 -0
- package/catalog/shaders/simianlights/simianlights.ts +73 -0
- package/dist/catalog/composites/clouds/clouds.controls.d.ts +3 -0
- package/dist/catalog/composites/clouds/clouds.controls.d.ts.map +1 -0
- package/dist/catalog/composites/clouds/clouds.controls.js +11 -0
- package/dist/catalog/composites/clouds/clouds.controls.js.map +1 -0
- package/dist/catalog/composites/clouds/clouds.d.ts +26 -0
- package/dist/catalog/composites/clouds/clouds.d.ts.map +1 -0
- package/dist/catalog/composites/clouds/clouds.js +33 -0
- package/dist/catalog/composites/clouds/clouds.js.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.controls.d.ts +3 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.controls.d.ts.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.controls.js +13 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.controls.js.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.d.ts +37 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.d.ts.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.js +52 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.js.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.thumb.webp +0 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.web.d.ts +37 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.web.d.ts.map +1 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.web.js +46 -0
- package/dist/catalog/composites/corporate-blobs/corporate-blobs.web.js.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.controls.d.ts +3 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.controls.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.controls.js +13 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.controls.js.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.d.ts +42 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.js +54 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.js.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.thumb.webp +0 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.web.d.ts +42 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.web.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.web.js +51 -0
- package/dist/catalog/composites/fairy-cave/fairy-cave.web.js.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.controls.d.ts +3 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.controls.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.controls.js +14 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.controls.js.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.d.ts +42 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.js +55 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.js.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.thumb.webp +0 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.web.d.ts +42 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.web.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.web.js +51 -0
- package/dist/catalog/composites/fairy-grotto/fairy-grotto.web.js.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.controls.d.ts +3 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.controls.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.controls.js +14 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.controls.js.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.d.ts +42 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.js +56 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.js.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.thumb.webp +0 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.web.d.ts +42 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.web.d.ts.map +1 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.web.js +51 -0
- package/dist/catalog/composites/fairy-hollow/fairy-hollow.web.js.map +1 -0
- package/dist/catalog/composites/nebula/nebula.controls.d.ts +3 -0
- package/dist/catalog/composites/nebula/nebula.controls.d.ts.map +1 -0
- package/dist/catalog/composites/nebula/nebula.controls.js +11 -0
- package/dist/catalog/composites/nebula/nebula.controls.js.map +1 -0
- package/dist/catalog/composites/nebula/nebula.d.ts +22 -0
- package/dist/catalog/composites/nebula/nebula.d.ts.map +1 -0
- package/dist/catalog/composites/nebula/nebula.js +38 -0
- package/dist/catalog/composites/nebula/nebula.js.map +1 -0
- package/dist/catalog/composites/nebula/nebula.thumb.webp +0 -0
- package/dist/catalog/composites/nebula/nebula.web.d.ts +22 -0
- package/dist/catalog/composites/nebula/nebula.web.d.ts.map +1 -0
- package/dist/catalog/composites/nebula/nebula.web.js +34 -0
- package/dist/catalog/composites/nebula/nebula.web.js.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.controls.d.ts +3 -0
- package/dist/catalog/composites/observation-deck/observation-deck.controls.d.ts.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.controls.js +13 -0
- package/dist/catalog/composites/observation-deck/observation-deck.controls.js.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.d.ts +41 -0
- package/dist/catalog/composites/observation-deck/observation-deck.d.ts.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.js +60 -0
- package/dist/catalog/composites/observation-deck/observation-deck.js.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.thumb.webp +0 -0
- package/dist/catalog/composites/observation-deck/observation-deck.web.d.ts +41 -0
- package/dist/catalog/composites/observation-deck/observation-deck.web.d.ts.map +1 -0
- package/dist/catalog/composites/observation-deck/observation-deck.web.js +54 -0
- package/dist/catalog/composites/observation-deck/observation-deck.web.js.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.controls.d.ts +3 -0
- package/dist/catalog/composites/simianlights/simianlights.controls.d.ts.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.controls.js +11 -0
- package/dist/catalog/composites/simianlights/simianlights.controls.js.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.d.ts +22 -0
- package/dist/catalog/composites/simianlights/simianlights.d.ts.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.js +30 -0
- package/dist/catalog/composites/simianlights/simianlights.js.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.thumb.webp +0 -0
- package/dist/catalog/composites/simianlights/simianlights.web.d.ts +22 -0
- package/dist/catalog/composites/simianlights/simianlights.web.d.ts.map +1 -0
- package/dist/catalog/composites/simianlights/simianlights.web.js +33 -0
- package/dist/catalog/composites/simianlights/simianlights.web.js.map +1 -0
- package/dist/catalog/composites/underwater/underwater.controls.d.ts +3 -0
- package/dist/catalog/composites/underwater/underwater.controls.d.ts.map +1 -0
- package/dist/catalog/composites/underwater/underwater.controls.js +11 -0
- package/dist/catalog/composites/underwater/underwater.controls.js.map +1 -0
- package/dist/catalog/composites/underwater/underwater.d.ts +30 -0
- package/dist/catalog/composites/underwater/underwater.d.ts.map +1 -0
- package/dist/catalog/composites/underwater/underwater.js +43 -0
- package/dist/catalog/composites/underwater/underwater.js.map +1 -0
- package/dist/catalog/composites/underwater/underwater.thumb.webp +0 -0
- package/dist/catalog/composites/underwater/underwater.web.d.ts +30 -0
- package/dist/catalog/composites/underwater/underwater.web.d.ts.map +1 -0
- package/dist/catalog/composites/underwater/underwater.web.js +40 -0
- package/dist/catalog/composites/underwater/underwater.web.js.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.controls.d.ts +3 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.controls.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.controls.js +15 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.controls.js.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.d.ts +31 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.js +45 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.js.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.thumb.webp +0 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.web.d.ts +31 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.web.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.web.js +39 -0
- package/dist/catalog/composites/wizard-tower/wizard-tower.web.js.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.controls.d.ts +3 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.controls.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.controls.js +14 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.controls.js.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.d.ts +31 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.js +44 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.js.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.thumb.webp +0 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.web.d.ts +31 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.web.d.ts.map +1 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.web.js +39 -0
- package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.web.js.map +1 -0
- package/dist/catalog/images/corporate/corporate-logo.d.ts +3 -0
- package/dist/catalog/images/corporate/corporate-logo.d.ts.map +1 -0
- package/dist/catalog/images/corporate/corporate-logo.js +8 -0
- package/dist/catalog/images/corporate/corporate-logo.js.map +1 -0
- package/dist/catalog/images/corporate/corporate-logo.thumb.webp +0 -0
- package/dist/catalog/images/corporate/corporate-logo.web.d.ts +3 -0
- package/dist/catalog/images/corporate/corporate-logo.web.d.ts.map +1 -0
- package/dist/catalog/images/corporate/corporate-logo.web.js +12 -0
- package/dist/catalog/images/corporate/corporate-logo.web.js.map +1 -0
- package/dist/catalog/images/corporate/corporate-logo.webp +0 -0
- package/dist/catalog/images/debug/debug-resolutions.d.ts +3 -0
- package/dist/catalog/images/debug/debug-resolutions.d.ts.map +1 -0
- package/dist/catalog/images/debug/debug-resolutions.js +8 -0
- package/dist/catalog/images/debug/debug-resolutions.js.map +1 -0
- package/dist/catalog/images/debug/debug-resolutions.thumb.webp +0 -0
- package/dist/catalog/images/debug/debug-resolutions.web.d.ts +3 -0
- package/dist/catalog/images/debug/debug-resolutions.web.d.ts.map +1 -0
- package/dist/catalog/images/debug/debug-resolutions.web.js +12 -0
- package/dist/catalog/images/debug/debug-resolutions.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/grotto.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/grotto.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/grotto.js +8 -0
- package/dist/catalog/images/fairy-caves/grotto.js.map +1 -0
- package/dist/catalog/images/fairy-caves/grotto.thumb.webp +0 -0
- package/dist/catalog/images/fairy-caves/grotto.web.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/grotto.web.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/grotto.web.js +12 -0
- package/dist/catalog/images/fairy-caves/grotto.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/grotto.webp +0 -0
- package/dist/catalog/images/fairy-caves/hollow.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/hollow.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/hollow.js +8 -0
- package/dist/catalog/images/fairy-caves/hollow.js.map +1 -0
- package/dist/catalog/images/fairy-caves/hollow.thumb.webp +0 -0
- package/dist/catalog/images/fairy-caves/hollow.web.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/hollow.web.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/hollow.web.js +12 -0
- package/dist/catalog/images/fairy-caves/hollow.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/hollow.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.js +8 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.thumb.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.web.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.web.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.web.js +12 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-2.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.js +8 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.thumb.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.web.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.web.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.web.js +12 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse-3.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse.js +8 -0
- package/dist/catalog/images/fairy-caves/treehouse.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse.thumb.webp +0 -0
- package/dist/catalog/images/fairy-caves/treehouse.web.d.ts +3 -0
- package/dist/catalog/images/fairy-caves/treehouse.web.d.ts.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse.web.js +12 -0
- package/dist/catalog/images/fairy-caves/treehouse.web.js.map +1 -0
- package/dist/catalog/images/fairy-caves/treehouse.webp +0 -0
- package/dist/catalog/images/home/home-dark.d.ts +3 -0
- package/dist/catalog/images/home/home-dark.d.ts.map +1 -0
- package/dist/catalog/images/home/home-dark.js +8 -0
- package/dist/catalog/images/home/home-dark.js.map +1 -0
- package/dist/catalog/images/home/home-dark.thumb.webp +0 -0
- package/dist/catalog/images/home/home-dark.web.d.ts +3 -0
- package/dist/catalog/images/home/home-dark.web.d.ts.map +1 -0
- package/dist/catalog/images/home/home-dark.web.js +12 -0
- package/dist/catalog/images/home/home-dark.web.js.map +1 -0
- package/dist/catalog/images/home/home-light.d.ts +3 -0
- package/dist/catalog/images/home/home-light.d.ts.map +1 -0
- package/dist/catalog/images/home/home-light.js +8 -0
- package/dist/catalog/images/home/home-light.js.map +1 -0
- package/dist/catalog/images/home/home-light.thumb.webp +0 -0
- package/dist/catalog/images/home/home-light.web.d.ts +3 -0
- package/dist/catalog/images/home/home-light.web.d.ts.map +1 -0
- package/dist/catalog/images/home/home-light.web.js +12 -0
- package/dist/catalog/images/home/home-light.web.js.map +1 -0
- package/dist/catalog/images/image-ids.d.ts +3 -0
- package/dist/catalog/images/image-ids.d.ts.map +1 -0
- package/dist/catalog/images/image-ids.js +43 -0
- package/dist/catalog/images/image-ids.js.map +1 -0
- package/dist/catalog/images/image.types.d.ts +2 -0
- package/dist/catalog/images/image.types.d.ts.map +1 -0
- package/dist/catalog/images/image.types.js +3 -0
- package/dist/catalog/images/image.types.js.map +1 -0
- package/dist/catalog/images/index.d.ts +3 -0
- package/dist/catalog/images/index.d.ts.map +1 -0
- package/dist/catalog/images/index.js +10 -0
- package/dist/catalog/images/index.js.map +1 -0
- package/dist/catalog/images/nature/landscape-dark.d.ts +3 -0
- package/dist/catalog/images/nature/landscape-dark.d.ts.map +1 -0
- package/dist/catalog/images/nature/landscape-dark.js +8 -0
- package/dist/catalog/images/nature/landscape-dark.js.map +1 -0
- package/dist/catalog/images/nature/landscape-dark.thumb.webp +0 -0
- package/dist/catalog/images/nature/landscape-dark.web.d.ts +3 -0
- package/dist/catalog/images/nature/landscape-dark.web.d.ts.map +1 -0
- package/dist/catalog/images/nature/landscape-dark.web.js +12 -0
- package/dist/catalog/images/nature/landscape-dark.web.js.map +1 -0
- package/dist/catalog/images/nature/landscape-light.d.ts +3 -0
- package/dist/catalog/images/nature/landscape-light.d.ts.map +1 -0
- package/dist/catalog/images/nature/landscape-light.js +8 -0
- package/dist/catalog/images/nature/landscape-light.js.map +1 -0
- package/dist/catalog/images/nature/landscape-light.thumb.webp +0 -0
- package/dist/catalog/images/nature/landscape-light.web.d.ts +3 -0
- package/dist/catalog/images/nature/landscape-light.web.d.ts.map +1 -0
- package/dist/catalog/images/nature/landscape-light.web.js +12 -0
- package/dist/catalog/images/nature/landscape-light.web.js.map +1 -0
- package/dist/catalog/images/office/office-dark.d.ts +3 -0
- package/dist/catalog/images/office/office-dark.d.ts.map +1 -0
- package/dist/catalog/images/office/office-dark.js +8 -0
- package/dist/catalog/images/office/office-dark.js.map +1 -0
- package/dist/catalog/images/office/office-dark.thumb.webp +0 -0
- package/dist/catalog/images/office/office-dark.web.d.ts +3 -0
- package/dist/catalog/images/office/office-dark.web.d.ts.map +1 -0
- package/dist/catalog/images/office/office-dark.web.js +12 -0
- package/dist/catalog/images/office/office-dark.web.js.map +1 -0
- package/dist/catalog/images/office/office-light.d.ts +3 -0
- package/dist/catalog/images/office/office-light.d.ts.map +1 -0
- package/dist/catalog/images/office/office-light.js +8 -0
- package/dist/catalog/images/office/office-light.js.map +1 -0
- package/dist/catalog/images/office/office-light.thumb.webp +0 -0
- package/dist/catalog/images/office/office-light.web.d.ts +3 -0
- package/dist/catalog/images/office/office-light.web.d.ts.map +1 -0
- package/dist/catalog/images/office/office-light.web.js +12 -0
- package/dist/catalog/images/office/office-light.web.js.map +1 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.d.ts +3 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.d.ts.map +1 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.js +8 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.js.map +1 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.thumb.webp +0 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.web.d.ts +3 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.web.d.ts.map +1 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.web.js +12 -0
- package/dist/catalog/images/sci-fi/sci-fi-light.web.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.js +8 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.thumb.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.web.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.web.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.web.js +12 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.web.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark-transparency.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.js +8 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.thumb.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.web.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.web.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.web.js +12 -0
- package/dist/catalog/images/simiancraft/simiancraft-dark.web.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.js +8 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.thumb.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.web.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.web.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.web.js +12 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.web.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light-transparency.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.js +8 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.js.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.thumb.webp +0 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.web.d.ts +3 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.web.d.ts.map +1 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.web.js +12 -0
- package/dist/catalog/images/simiancraft/simiancraft-light.web.js.map +1 -0
- package/dist/catalog/images/spaceship/observation-deck.d.ts +3 -0
- package/dist/catalog/images/spaceship/observation-deck.d.ts.map +1 -0
- package/dist/catalog/images/spaceship/observation-deck.js +8 -0
- package/dist/catalog/images/spaceship/observation-deck.js.map +1 -0
- package/dist/catalog/images/spaceship/observation-deck.thumb.webp +0 -0
- package/dist/catalog/images/spaceship/observation-deck.web.d.ts +3 -0
- package/dist/catalog/images/spaceship/observation-deck.web.d.ts.map +1 -0
- package/dist/catalog/images/spaceship/observation-deck.web.js +12 -0
- package/dist/catalog/images/spaceship/observation-deck.web.js.map +1 -0
- package/dist/catalog/images/spaceship/observation-deck.webp +0 -0
- package/dist/catalog/images/underwater/oceanscape-dark.d.ts +3 -0
- package/dist/catalog/images/underwater/oceanscape-dark.d.ts.map +1 -0
- package/dist/catalog/images/underwater/oceanscape-dark.js +8 -0
- package/dist/catalog/images/underwater/oceanscape-dark.js.map +1 -0
- package/dist/catalog/images/underwater/oceanscape-dark.thumb.webp +0 -0
- package/dist/catalog/images/underwater/oceanscape-dark.web.d.ts +3 -0
- package/dist/catalog/images/underwater/oceanscape-dark.web.d.ts.map +1 -0
- package/dist/catalog/images/underwater/oceanscape-dark.web.js +12 -0
- package/dist/catalog/images/underwater/oceanscape-dark.web.js.map +1 -0
- package/dist/catalog/images/underwater/oceanscape-dark.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.js +8 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.thumb.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.web.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.web.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.web.js +12 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.web.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-1.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.js +8 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.thumb.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.web.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.web.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.web.js +12 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.web.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-2.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.js +8 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.thumb.webp +0 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.web.d.ts +3 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.web.d.ts.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.web.js +12 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.web.js.map +1 -0
- package/dist/catalog/images/wizard-tower/wizard-tower-night.webp +0 -0
- package/dist/catalog/shaders/_shared/types.d.ts +38 -0
- package/dist/catalog/shaders/_shared/types.d.ts.map +1 -0
- package/dist/catalog/shaders/_shared/types.js +15 -0
- package/dist/catalog/shaders/_shared/types.js.map +1 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.d.ts +26 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.d.ts.map +1 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.form.d.ts +3 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.form.d.ts.map +1 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.form.js +15 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.form.js.map +1 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.js +84 -0
- package/dist/catalog/shaders/anamorphic-lensflare/anamorphic-lensflare.js.map +1 -0
- package/dist/catalog/shaders/blur/blur.d.ts +15 -0
- package/dist/catalog/shaders/blur/blur.d.ts.map +1 -0
- package/dist/catalog/shaders/blur/blur.form.d.ts +3 -0
- package/dist/catalog/shaders/blur/blur.form.d.ts.map +1 -0
- package/dist/catalog/shaders/blur/blur.form.js +15 -0
- package/dist/catalog/shaders/blur/blur.form.js.map +1 -0
- package/dist/catalog/shaders/blur/blur.js +27 -0
- package/dist/catalog/shaders/blur/blur.js.map +1 -0
- package/dist/catalog/shaders/clouds/clouds.d.ts +34 -0
- package/dist/catalog/shaders/clouds/clouds.d.ts.map +1 -0
- package/dist/catalog/shaders/clouds/clouds.form.d.ts +3 -0
- package/dist/catalog/shaders/clouds/clouds.form.d.ts.map +1 -0
- package/dist/catalog/shaders/clouds/clouds.form.js +15 -0
- package/dist/catalog/shaders/clouds/clouds.form.js.map +1 -0
- package/dist/catalog/shaders/clouds/clouds.js +98 -0
- package/dist/catalog/shaders/clouds/clouds.js.map +1 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.d.ts +40 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.d.ts.map +1 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.form.d.ts +3 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.form.d.ts.map +1 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.form.js +15 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.form.js.map +1 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.js +100 -0
- package/dist/catalog/shaders/corporate-blobs/corporate-blobs.js.map +1 -0
- package/dist/catalog/shaders/fireflies/fireflies.d.ts +18 -0
- package/dist/catalog/shaders/fireflies/fireflies.d.ts.map +1 -0
- package/dist/catalog/shaders/fireflies/fireflies.form.d.ts +3 -0
- package/dist/catalog/shaders/fireflies/fireflies.form.d.ts.map +1 -0
- package/dist/catalog/shaders/fireflies/fireflies.form.js +15 -0
- package/dist/catalog/shaders/fireflies/fireflies.form.js.map +1 -0
- package/dist/catalog/shaders/fireflies/fireflies.js +47 -0
- package/dist/catalog/shaders/fireflies/fireflies.js.map +1 -0
- package/dist/catalog/shaders/godrays/godrays.d.ts +26 -0
- package/dist/catalog/shaders/godrays/godrays.d.ts.map +1 -0
- package/dist/catalog/shaders/godrays/godrays.form.d.ts +3 -0
- package/dist/catalog/shaders/godrays/godrays.form.d.ts.map +1 -0
- package/dist/catalog/shaders/godrays/godrays.form.js +15 -0
- package/dist/catalog/shaders/godrays/godrays.form.js.map +1 -0
- package/dist/catalog/shaders/godrays/godrays.js +83 -0
- package/dist/catalog/shaders/godrays/godrays.js.map +1 -0
- package/dist/catalog/shaders/index.d.ts +73 -0
- package/dist/catalog/shaders/index.d.ts.map +1 -0
- package/dist/catalog/shaders/index.js +30 -0
- package/dist/catalog/shaders/index.js.map +1 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.d.ts +44 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.d.ts.map +1 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.form.d.ts +3 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.form.d.ts.map +1 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.form.js +16 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.form.js.map +1 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.js +91 -0
- package/dist/catalog/shaders/light-beams-and-motes/light-beams-and-motes.js.map +1 -0
- package/dist/catalog/shaders/nebula/nebula.d.ts +20 -0
- package/dist/catalog/shaders/nebula/nebula.d.ts.map +1 -0
- package/dist/catalog/shaders/nebula/nebula.form.d.ts +3 -0
- package/dist/catalog/shaders/nebula/nebula.form.d.ts.map +1 -0
- package/dist/catalog/shaders/nebula/nebula.form.js +15 -0
- package/dist/catalog/shaders/nebula/nebula.form.js.map +1 -0
- package/dist/catalog/shaders/nebula/nebula.js +58 -0
- package/dist/catalog/shaders/nebula/nebula.js.map +1 -0
- package/dist/catalog/shaders/plasma/plasma.d.ts +16 -0
- package/dist/catalog/shaders/plasma/plasma.d.ts.map +1 -0
- package/dist/catalog/shaders/plasma/plasma.form.d.ts +3 -0
- package/dist/catalog/shaders/plasma/plasma.form.d.ts.map +1 -0
- package/dist/catalog/shaders/plasma/plasma.form.js +15 -0
- package/dist/catalog/shaders/plasma/plasma.form.js.map +1 -0
- package/dist/catalog/shaders/plasma/plasma.js +32 -0
- package/dist/catalog/shaders/plasma/plasma.js.map +1 -0
- package/dist/catalog/shaders/simianlights/simianlights.d.ts +20 -0
- package/dist/catalog/shaders/simianlights/simianlights.d.ts.map +1 -0
- package/dist/catalog/shaders/simianlights/simianlights.form.d.ts +3 -0
- package/dist/catalog/shaders/simianlights/simianlights.form.d.ts.map +1 -0
- package/dist/catalog/shaders/simianlights/simianlights.form.js +15 -0
- package/dist/catalog/shaders/simianlights/simianlights.form.js.map +1 -0
- package/dist/catalog/shaders/simianlights/simianlights.js +57 -0
- package/dist/catalog/shaders/simianlights/simianlights.js.map +1 -0
- package/dist/src/components/form/control-form.d.ts +37 -0
- package/dist/src/components/form/control-form.d.ts.map +1 -0
- package/dist/src/components/form/control-form.js +55 -0
- package/dist/src/components/form/control-form.js.map +1 -0
- package/dist/src/components/form/make-controls.d.ts +22 -0
- package/dist/src/components/form/make-controls.d.ts.map +1 -0
- package/dist/src/components/form/make-controls.js +19 -0
- package/dist/src/components/form/make-controls.js.map +1 -0
- package/dist/src/components/form/scope.d.ts +2 -0
- package/dist/src/components/form/scope.d.ts.map +1 -0
- package/dist/src/components/form/scope.js +11 -0
- package/dist/src/components/form/scope.js.map +1 -0
- package/dist/src/components/form/use-field.d.ts +10 -0
- package/dist/src/components/form/use-field.d.ts.map +1 -0
- package/dist/src/components/form/use-field.js +27 -0
- package/dist/src/components/form/use-field.js.map +1 -0
- package/dist/src/components/preset-book-menu/index.d.ts +52 -0
- package/dist/src/components/preset-book-menu/index.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/index.js +152 -0
- package/dist/src/components/preset-book-menu/index.js.map +1 -0
- package/dist/src/components/preset-book-menu/layout.d.ts +25 -0
- package/dist/src/components/preset-book-menu/layout.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/layout.js +19 -0
- package/dist/src/components/preset-book-menu/layout.js.map +1 -0
- package/dist/src/components/preset-book-menu/preset-book-menu.types.d.ts +88 -0
- package/dist/src/components/preset-book-menu/preset-book-menu.types.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/preset-book-menu.types.js +14 -0
- package/dist/src/components/preset-book-menu/preset-book-menu.types.js.map +1 -0
- package/dist/src/components/preset-book-menu/preset-grid.d.ts +16 -0
- package/dist/src/components/preset-book-menu/preset-grid.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/preset-grid.js +49 -0
- package/dist/src/components/preset-book-menu/preset-grid.js.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.d.ts +3 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.js +28 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.js.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.types.d.ts +13 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.types.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.types.js +5 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.types.js.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.web.d.ts +3 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.web.d.ts.map +1 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.web.js +17 -0
- package/dist/src/components/preset-book-menu/resolve-image-uri.web.js.map +1 -0
- package/dist/src/components/preset-control-panel/composite-layer-control-panel.d.ts +14 -0
- package/dist/src/components/preset-control-panel/composite-layer-control-panel.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/composite-layer-control-panel.js +36 -0
- package/dist/src/components/preset-control-panel/composite-layer-control-panel.js.map +1 -0
- package/dist/src/components/preset-control-panel/control-section.d.ts +9 -0
- package/dist/src/components/preset-control-panel/control-section.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/control-section.js +47 -0
- package/dist/src/components/preset-control-panel/control-section.js.map +1 -0
- package/dist/src/components/preset-control-panel/control.d.ts +10 -0
- package/dist/src/components/preset-control-panel/control.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/control.js +35 -0
- package/dist/src/components/preset-control-panel/control.js.map +1 -0
- package/dist/src/components/preset-control-panel/index.d.ts +14 -0
- package/dist/src/components/preset-control-panel/index.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/index.js +49 -0
- package/dist/src/components/preset-control-panel/index.js.map +1 -0
- package/dist/src/components/preset-control-panel/mask-control-panel.d.ts +11 -0
- package/dist/src/components/preset-control-panel/mask-control-panel.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/mask-control-panel.js +34 -0
- package/dist/src/components/preset-control-panel/mask-control-panel.js.map +1 -0
- package/dist/src/components/preset-control-panel/preset-control-panel.d.ts +12 -0
- package/dist/src/components/preset-control-panel/preset-control-panel.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/preset-control-panel.js +23 -0
- package/dist/src/components/preset-control-panel/preset-control-panel.js.map +1 -0
- package/dist/src/components/preset-control-panel/transform-control-panel.d.ts +14 -0
- package/dist/src/components/preset-control-panel/transform-control-panel.d.ts.map +1 -0
- package/dist/src/components/preset-control-panel/transform-control-panel.js +58 -0
- package/dist/src/components/preset-control-panel/transform-control-panel.js.map +1 -0
- package/dist/src/components/preset-tile/index.d.ts +24 -0
- package/dist/src/components/preset-tile/index.d.ts.map +1 -0
- package/dist/src/components/preset-tile/index.js +98 -0
- package/dist/src/components/preset-tile/index.js.map +1 -0
- package/dist/src/components/theme/provider.d.ts +18 -0
- package/dist/src/components/theme/provider.d.ts.map +1 -0
- package/dist/src/components/theme/provider.js +29 -0
- package/dist/src/components/theme/provider.js.map +1 -0
- package/dist/src/components/theme/slots.d.ts +17 -0
- package/dist/src/components/theme/slots.d.ts.map +1 -0
- package/dist/src/components/theme/slots.js +9 -0
- package/dist/src/components/theme/slots.js.map +1 -0
- package/dist/src/components/ui/button.d.ts +14 -0
- package/dist/src/components/ui/button.d.ts.map +1 -0
- package/dist/src/components/ui/button.js +29 -0
- package/dist/src/components/ui/button.js.map +1 -0
- package/dist/src/components/ui/color-picker.d.ts +12 -0
- package/dist/src/components/ui/color-picker.d.ts.map +1 -0
- package/dist/src/components/ui/color-picker.js +43 -0
- package/dist/src/components/ui/color-picker.js.map +1 -0
- package/dist/src/components/ui/index.d.ts +6 -0
- package/dist/src/components/ui/index.d.ts.map +1 -0
- package/dist/src/components/ui/index.js +18 -0
- package/dist/src/components/ui/index.js.map +1 -0
- package/dist/src/components/ui/label.d.ts +10 -0
- package/dist/src/components/ui/label.d.ts.map +1 -0
- package/dist/src/components/ui/label.js +14 -0
- package/dist/src/components/ui/label.js.map +1 -0
- package/dist/src/components/ui/point.d.ts +19 -0
- package/dist/src/components/ui/point.d.ts.map +1 -0
- package/dist/src/components/ui/point.js +52 -0
- package/dist/src/components/ui/point.js.map +1 -0
- package/dist/src/components/ui/polygon-field.d.ts +10 -0
- package/dist/src/components/ui/polygon-field.d.ts.map +1 -0
- package/dist/src/components/ui/polygon-field.js +50 -0
- package/dist/src/components/ui/polygon-field.js.map +1 -0
- package/dist/src/components/ui/readout.d.ts +10 -0
- package/dist/src/components/ui/readout.d.ts.map +1 -0
- package/dist/src/components/ui/readout.js +14 -0
- package/dist/src/components/ui/readout.js.map +1 -0
- package/dist/src/components/ui/slider-value.d.ts +8 -0
- package/dist/src/components/ui/slider-value.d.ts.map +1 -0
- package/dist/src/components/ui/slider-value.js +17 -0
- package/dist/src/components/ui/slider-value.js.map +1 -0
- package/dist/src/components/ui/slider.d.ts +15 -0
- package/dist/src/components/ui/slider.d.ts.map +1 -0
- package/dist/src/components/ui/slider.js +58 -0
- package/dist/src/components/ui/slider.js.map +1 -0
- package/dist/src/components/ui/switch.d.ts +8 -0
- package/dist/src/components/ui/switch.d.ts.map +1 -0
- package/dist/src/components/ui/switch.js +24 -0
- package/dist/src/components/ui/switch.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +187 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.web.d.ts +32 -0
- package/dist/src/index.web.d.ts.map +1 -0
- package/dist/src/index.web.js +119 -0
- package/dist/src/index.web.js.map +1 -0
- package/dist/src/kaleidoscope/controls.d.ts +24 -0
- package/dist/src/kaleidoscope/controls.d.ts.map +1 -0
- package/dist/src/kaleidoscope/controls.js +92 -0
- package/dist/src/kaleidoscope/controls.js.map +1 -0
- package/dist/src/kaleidoscope/effect.d.ts +4 -0
- package/dist/src/kaleidoscope/effect.d.ts.map +1 -0
- package/dist/src/kaleidoscope/effect.js +7 -0
- package/dist/src/kaleidoscope/effect.js.map +1 -0
- package/dist/src/kaleidoscope/effect.types.d.ts +47 -0
- package/dist/src/kaleidoscope/effect.types.d.ts.map +1 -0
- package/dist/src/kaleidoscope/effect.types.js +9 -0
- package/dist/src/kaleidoscope/effect.types.js.map +1 -0
- package/dist/src/kaleidoscope/shader-to-spec.d.ts +4 -0
- package/dist/src/kaleidoscope/shader-to-spec.d.ts.map +1 -0
- package/dist/src/kaleidoscope/shader-to-spec.js +17 -0
- package/dist/src/kaleidoscope/shader-to-spec.js.map +1 -0
- package/dist/src/kaleidoscope/types.d.ts +79 -0
- package/dist/src/kaleidoscope/types.d.ts.map +1 -0
- package/dist/src/kaleidoscope/types.js +18 -0
- package/dist/src/kaleidoscope/types.js.map +1 -0
- package/dist/src/kaleidoscope.preset-book.types.d.ts +86 -0
- package/dist/src/kaleidoscope.preset-book.types.d.ts.map +1 -0
- package/dist/src/kaleidoscope.preset-book.types.js +16 -0
- package/dist/src/kaleidoscope.preset-book.types.js.map +1 -0
- package/dist/src/lib/primitives.types.d.ts +3 -0
- package/dist/src/lib/primitives.types.d.ts.map +1 -0
- package/dist/src/lib/primitives.types.js +5 -0
- package/dist/src/lib/primitives.types.js.map +1 -0
- package/dist/src/lib/test-id.d.ts +30 -0
- package/dist/src/lib/test-id.d.ts.map +1 -0
- package/dist/src/lib/test-id.js +81 -0
- package/dist/src/lib/test-id.js.map +1 -0
- package/dist/src/livekit.d.ts +24 -0
- package/dist/src/livekit.d.ts.map +1 -0
- package/dist/src/livekit.js +63 -0
- package/dist/src/livekit.js.map +1 -0
- package/dist/src/nativewind.d.ts +7 -0
- package/dist/src/nativewind.d.ts.map +1 -0
- package/dist/src/nativewind.js +43 -0
- package/dist/src/nativewind.js.map +1 -0
- package/dist/web-driver/effects/composite.d.ts +14 -0
- package/dist/web-driver/effects/composite.d.ts.map +1 -0
- package/dist/web-driver/effects/composite.js +576 -0
- package/dist/web-driver/effects/composite.js.map +1 -0
- package/dist/web-driver/effects/layer-shaders.d.ts +2 -0
- package/dist/web-driver/effects/layer-shaders.d.ts.map +1 -0
- package/dist/web-driver/effects/layer-shaders.js +11 -0
- package/dist/web-driver/effects/layer-shaders.js.map +1 -0
- package/dist/web-driver/effects/transform.d.ts +4 -0
- package/dist/web-driver/effects/transform.d.ts.map +1 -0
- package/dist/web-driver/effects/transform.js +66 -0
- package/dist/web-driver/effects/transform.js.map +1 -0
- package/dist/web-driver/index.d.ts +6 -0
- package/dist/web-driver/index.d.ts.map +1 -0
- package/dist/web-driver/index.js +21 -0
- package/dist/web-driver/index.js.map +1 -0
- package/dist/web-driver/insertable-streams.d.ts.map +1 -0
- package/dist/web-driver/insertable-streams.js +68 -0
- package/dist/web-driver/insertable-streams.js.map +1 -0
- package/dist/web-driver/segmenter.d.ts.map +1 -0
- package/dist/web-driver/segmenter.js +89 -0
- package/dist/web-driver/segmenter.js.map +1 -0
- package/dist/web-driver/shaders.d.ts +2 -0
- package/dist/web-driver/shaders.d.ts.map +1 -0
- package/dist/web-driver/shaders.generated.d.ts +17 -0
- package/dist/web-driver/shaders.generated.d.ts.map +1 -0
- package/dist/web-driver/shaders.generated.js +1180 -0
- package/dist/web-driver/shaders.generated.js.map +1 -0
- package/dist/web-driver/shaders.js +28 -0
- package/dist/web-driver/shaders.js.map +1 -0
- package/dist/web-driver/tuning.d.ts.map +1 -0
- package/dist/web-driver/tuning.js +61 -0
- package/dist/web-driver/tuning.js.map +1 -0
- package/ios/Kaleidoscope.podspec +22 -15
- package/ios/KaleidoscopeModule/BundledImage.swift +39 -0
- package/ios/KaleidoscopeModule/CompositeLayers.swift +142 -0
- package/ios/KaleidoscopeModule/EffectTuning.swift +86 -86
- package/ios/KaleidoscopeModule/KaleidoscopeModule.swift +55 -27
- package/ios/KaleidoscopeModule/Registration.swift +36 -57
- package/ios/KaleidoscopeModule/effects/CompositeProcessor.swift +906 -0
- package/ios/KaleidoscopeModule/effects/FrameBridge.swift +25 -25
- package/ios/KaleidoscopeModule/effects/TransformProcessor.swift +127 -126
- package/ios/KaleidoscopeModule/gpu/CompositeRendering.swift +352 -0
- package/ios/KaleidoscopeModule/gpu/Ingest.swift +104 -102
- package/ios/KaleidoscopeModule/gpu/MetalRenderer.swift +473 -544
- package/ios/KaleidoscopeModule/gpu/Orientation.swift +41 -41
- package/ios/KaleidoscopeModule/gpu/ShaderLibrary.swift +100 -54
- package/ios/KaleidoscopeModule/gpu/TextureBridge.swift +245 -244
- package/ios/KaleidoscopeModule/segmentation/MaskTuning.swift +11 -11
- package/ios/KaleidoscopeModule/segmentation/Segmenter.swift +360 -359
- package/ios/KaleidoscopeModule/shaders/GENERATIVE.txt +9 -0
- package/ios/KaleidoscopeModule/shaders/SHADERS.txt +13 -2
- package/ios/KaleidoscopeModule/shaders/anamorphic-lensflare.metalsrc +47 -0
- package/ios/KaleidoscopeModule/shaders/clouds.metalsrc +185 -0
- package/ios/KaleidoscopeModule/shaders/composite-blit.metalsrc +22 -0
- package/ios/KaleidoscopeModule/shaders/composite-blur.metalsrc +93 -0
- package/ios/KaleidoscopeModule/shaders/composite-camera.metalsrc +22 -0
- package/ios/KaleidoscopeModule/shaders/composite-image.metalsrc +24 -0
- package/ios/KaleidoscopeModule/shaders/composite-masked.metalsrc +22 -0
- package/ios/KaleidoscopeModule/shaders/composite-subject.metalsrc +23 -0
- package/ios/KaleidoscopeModule/shaders/corporate-blobs.metalsrc +221 -0
- package/ios/KaleidoscopeModule/shaders/fireflies.metalsrc +44 -0
- package/ios/KaleidoscopeModule/shaders/godrays.metalsrc +46 -0
- package/ios/KaleidoscopeModule/shaders/light-beams-and-motes.metalsrc +316 -0
- package/ios/KaleidoscopeModule/shaders/nebula.metalsrc +45 -45
- package/ios/KaleidoscopeModule/shaders/plasma.metalsrc +26 -0
- package/ios/KaleidoscopeModule/shaders/simianlights.metalsrc +45 -45
- package/package.json +485 -115
- package/plugin/build/android/assets.js +45 -0
- package/plugin/build/android/index.js +34 -0
- package/plugin/build/index.js +39 -0
- package/plugin/build/ios/assets.js +110 -0
- package/plugin/build/ios/deployment-target.js +105 -0
- package/plugin/build/ios/index.js +63 -0
- package/plugin/build/ios/pods.js +73 -0
- package/plugin/build/lib/constants.js +15 -0
- package/plugin/build/lib/file-manipulation.js +57 -0
- package/plugin/build/lib/mods.js +36 -0
- package/plugin/build/lib/preset-book.js +215 -0
- package/plugin/build/lib/types.js +16 -0
- package/src/components/form/control-form.tsx +112 -0
- package/src/components/form/make-controls.ts +33 -0
- package/src/components/form/scope.ts +9 -0
- package/src/components/form/use-field.ts +35 -0
- package/src/components/preset-book-menu/index.tsx +286 -0
- package/src/components/preset-book-menu/layout.tsx +63 -0
- package/src/components/preset-book-menu/preset-book-menu.types.ts +112 -0
- package/src/components/preset-book-menu/preset-grid.tsx +80 -0
- package/src/components/preset-book-menu/resolve-image-uri.ts +31 -0
- package/src/components/preset-book-menu/resolve-image-uri.types.ts +18 -0
- package/src/components/preset-book-menu/resolve-image-uri.web.ts +15 -0
- package/src/components/preset-control-panel/composite-layer-control-panel.tsx +56 -0
- package/src/components/preset-control-panel/control-section.tsx +84 -0
- package/src/components/preset-control-panel/control.tsx +50 -0
- package/src/components/preset-control-panel/index.ts +31 -0
- package/src/components/preset-control-panel/mask-control-panel.tsx +93 -0
- package/src/components/preset-control-panel/preset-control-panel.tsx +48 -0
- package/src/components/preset-control-panel/transform-control-panel.tsx +146 -0
- package/src/components/preset-tile/index.tsx +160 -0
- package/src/components/theme/provider.tsx +50 -0
- package/src/components/theme/slots.ts +37 -0
- package/src/components/ui/button.tsx +54 -0
- package/src/components/ui/color-picker.tsx +74 -0
- package/src/components/ui/index.ts +10 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/point.tsx +116 -0
- package/src/components/ui/polygon-field.tsx +84 -0
- package/src/components/ui/readout.tsx +25 -0
- package/src/components/ui/slider-value.ts +15 -0
- package/src/components/ui/slider.tsx +98 -0
- package/src/components/ui/switch.tsx +40 -0
- package/src/index.ts +176 -95
- package/src/index.web.ts +126 -74
- package/src/kaleidoscope/controls.ts +127 -0
- package/src/kaleidoscope/effect.ts +5 -0
- package/src/kaleidoscope/effect.types.ts +63 -0
- package/src/kaleidoscope/shader-to-spec.ts +16 -0
- package/src/kaleidoscope/types.ts +101 -0
- package/src/kaleidoscope.preset-book.types.ts +105 -0
- package/src/lib/primitives.types.ts +5 -0
- package/src/lib/test-id.ts +81 -0
- package/src/livekit.ts +6 -4
- package/src/nativewind.ts +41 -0
- package/android/src/main/assets/backgrounds/stylized-dark.webp +0 -0
- package/android/src/main/java/com/simiancraft/kaleidoscope/effects/BackgroundImageFactory.kt +0 -365
- package/android/src/main/java/com/simiancraft/kaleidoscope/effects/BlurFactory.kt +0 -400
- package/dist/backgrounds/dark-office.d.ts +0 -3
- package/dist/backgrounds/dark-office.d.ts.map +0 -1
- package/dist/backgrounds/dark-office.js +0 -5
- package/dist/backgrounds/dark-office.js.map +0 -1
- package/dist/backgrounds/dark-office.web.d.ts +0 -3
- package/dist/backgrounds/dark-office.web.d.ts.map +0 -1
- package/dist/backgrounds/dark-office.web.js +0 -8
- package/dist/backgrounds/dark-office.web.js.map +0 -1
- package/dist/backgrounds/debug-resolutions.d.ts +0 -3
- package/dist/backgrounds/debug-resolutions.d.ts.map +0 -1
- package/dist/backgrounds/debug-resolutions.js +0 -6
- package/dist/backgrounds/debug-resolutions.js.map +0 -1
- package/dist/backgrounds/debug-resolutions.web.d.ts +0 -3
- package/dist/backgrounds/debug-resolutions.web.d.ts.map +0 -1
- package/dist/backgrounds/debug-resolutions.web.js +0 -8
- package/dist/backgrounds/debug-resolutions.web.js.map +0 -1
- package/dist/backgrounds/home-dark.d.ts +0 -3
- package/dist/backgrounds/home-dark.d.ts.map +0 -1
- package/dist/backgrounds/home-dark.js +0 -5
- package/dist/backgrounds/home-dark.js.map +0 -1
- package/dist/backgrounds/home-dark.web.d.ts +0 -3
- package/dist/backgrounds/home-dark.web.d.ts.map +0 -1
- package/dist/backgrounds/home-dark.web.js +0 -6
- package/dist/backgrounds/home-dark.web.js.map +0 -1
- package/dist/backgrounds/home-light.d.ts +0 -3
- package/dist/backgrounds/home-light.d.ts.map +0 -1
- package/dist/backgrounds/home-light.js +0 -5
- package/dist/backgrounds/home-light.js.map +0 -1
- package/dist/backgrounds/home-light.web.d.ts +0 -3
- package/dist/backgrounds/home-light.web.d.ts.map +0 -1
- package/dist/backgrounds/home-light.web.js +0 -6
- package/dist/backgrounds/home-light.web.js.map +0 -1
- package/dist/backgrounds/index.d.ts +0 -3
- package/dist/backgrounds/index.d.ts.map +0 -1
- package/dist/backgrounds/index.js +0 -6
- package/dist/backgrounds/index.js.map +0 -1
- package/dist/backgrounds/light-office.d.ts +0 -3
- package/dist/backgrounds/light-office.d.ts.map +0 -1
- package/dist/backgrounds/light-office.js +0 -5
- package/dist/backgrounds/light-office.js.map +0 -1
- package/dist/backgrounds/light-office.web.d.ts +0 -3
- package/dist/backgrounds/light-office.web.d.ts.map +0 -1
- package/dist/backgrounds/light-office.web.js +0 -8
- package/dist/backgrounds/light-office.web.js.map +0 -1
- package/dist/backgrounds/nature-dark.d.ts +0 -3
- package/dist/backgrounds/nature-dark.d.ts.map +0 -1
- package/dist/backgrounds/nature-dark.js +0 -5
- package/dist/backgrounds/nature-dark.js.map +0 -1
- package/dist/backgrounds/nature-dark.web.d.ts +0 -3
- package/dist/backgrounds/nature-dark.web.d.ts.map +0 -1
- package/dist/backgrounds/nature-dark.web.js +0 -6
- package/dist/backgrounds/nature-dark.web.js.map +0 -1
- package/dist/backgrounds/nature-light.d.ts +0 -3
- package/dist/backgrounds/nature-light.d.ts.map +0 -1
- package/dist/backgrounds/nature-light.js +0 -5
- package/dist/backgrounds/nature-light.js.map +0 -1
- package/dist/backgrounds/nature-light.web.d.ts +0 -3
- package/dist/backgrounds/nature-light.web.d.ts.map +0 -1
- package/dist/backgrounds/nature-light.web.js +0 -6
- package/dist/backgrounds/nature-light.web.js.map +0 -1
- package/dist/backgrounds/preset-source.types.d.ts +0 -2
- package/dist/backgrounds/preset-source.types.d.ts.map +0 -1
- package/dist/backgrounds/preset-source.types.js +0 -2
- package/dist/backgrounds/preset-source.types.js.map +0 -1
- package/dist/backgrounds/presets.d.ts +0 -3
- package/dist/backgrounds/presets.d.ts.map +0 -1
- package/dist/backgrounds/presets.js +0 -34
- package/dist/backgrounds/presets.js.map +0 -1
- package/dist/backgrounds/simiancraft-dark.d.ts +0 -3
- package/dist/backgrounds/simiancraft-dark.d.ts.map +0 -1
- package/dist/backgrounds/simiancraft-dark.js +0 -5
- package/dist/backgrounds/simiancraft-dark.js.map +0 -1
- package/dist/backgrounds/simiancraft-dark.web.d.ts +0 -3
- package/dist/backgrounds/simiancraft-dark.web.d.ts.map +0 -1
- package/dist/backgrounds/simiancraft-dark.web.js +0 -6
- package/dist/backgrounds/simiancraft-dark.web.js.map +0 -1
- package/dist/backgrounds/simiancraft-light.d.ts +0 -3
- package/dist/backgrounds/simiancraft-light.d.ts.map +0 -1
- package/dist/backgrounds/simiancraft-light.js +0 -5
- package/dist/backgrounds/simiancraft-light.js.map +0 -1
- package/dist/backgrounds/simiancraft-light.web.d.ts +0 -3
- package/dist/backgrounds/simiancraft-light.web.d.ts.map +0 -1
- package/dist/backgrounds/simiancraft-light.web.js +0 -6
- package/dist/backgrounds/simiancraft-light.web.js.map +0 -1
- package/dist/backgrounds/stylized-dark.d.ts +0 -3
- package/dist/backgrounds/stylized-dark.d.ts.map +0 -1
- package/dist/backgrounds/stylized-dark.js +0 -5
- package/dist/backgrounds/stylized-dark.js.map +0 -1
- package/dist/backgrounds/stylized-dark.web.d.ts +0 -3
- package/dist/backgrounds/stylized-dark.web.d.ts.map +0 -1
- package/dist/backgrounds/stylized-dark.web.js +0 -6
- package/dist/backgrounds/stylized-dark.web.js.map +0 -1
- package/dist/backgrounds/stylized-dark.webp +0 -0
- package/dist/backgrounds/stylized-light.d.ts +0 -3
- package/dist/backgrounds/stylized-light.d.ts.map +0 -1
- package/dist/backgrounds/stylized-light.js +0 -5
- package/dist/backgrounds/stylized-light.js.map +0 -1
- package/dist/backgrounds/stylized-light.web.d.ts +0 -3
- package/dist/backgrounds/stylized-light.web.d.ts.map +0 -1
- package/dist/backgrounds/stylized-light.web.js +0 -6
- package/dist/backgrounds/stylized-light.web.js.map +0 -1
- package/dist/index.d.ts +0 -42
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -155
- package/dist/index.js.map +0 -1
- package/dist/index.web.d.ts +0 -49
- package/dist/index.web.d.ts.map +0 -1
- package/dist/index.web.js +0 -113
- package/dist/index.web.js.map +0 -1
- package/dist/livekit.d.ts +0 -24
- package/dist/livekit.d.ts.map +0 -1
- package/dist/livekit.js +0 -57
- package/dist/livekit.js.map +0 -1
- package/dist/types.d.ts +0 -74
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -10
- package/dist/types.js.map +0 -1
- package/dist/web/blur-kernel.d.ts +0 -6
- package/dist/web/blur-kernel.d.ts.map +0 -1
- package/dist/web/blur-kernel.js +0 -41
- package/dist/web/blur-kernel.js.map +0 -1
- package/dist/web/effects/background-image.d.ts +0 -3
- package/dist/web/effects/background-image.d.ts.map +0 -1
- package/dist/web/effects/background-image.js +0 -284
- package/dist/web/effects/background-image.js.map +0 -1
- package/dist/web/effects/blur.d.ts +0 -3
- package/dist/web/effects/blur.d.ts.map +0 -1
- package/dist/web/effects/blur.js +0 -339
- package/dist/web/effects/blur.js.map +0 -1
- package/dist/web/effects/transform.d.ts +0 -4
- package/dist/web/effects/transform.d.ts.map +0 -1
- package/dist/web/effects/transform.js +0 -62
- package/dist/web/effects/transform.js.map +0 -1
- package/dist/web/insertable-streams.d.ts.map +0 -1
- package/dist/web/insertable-streams.js +0 -64
- package/dist/web/insertable-streams.js.map +0 -1
- package/dist/web/segmenter.d.ts.map +0 -1
- package/dist/web/segmenter.js +0 -83
- package/dist/web/segmenter.js.map +0 -1
- package/dist/web/shaders.d.ts +0 -2
- package/dist/web/shaders.d.ts.map +0 -1
- package/dist/web/shaders.generated.d.ts +0 -4
- package/dist/web/shaders.generated.d.ts.map +0 -1
- package/dist/web/shaders.generated.js +0 -54
- package/dist/web/shaders.generated.js.map +0 -1
- package/dist/web/shaders.js +0 -32
- package/dist/web/shaders.js.map +0 -1
- package/dist/web/tuning.d.ts.map +0 -1
- package/dist/web/tuning.js +0 -55
- package/dist/web/tuning.js.map +0 -1
- package/ios/KaleidoscopeModule/effects/BackgroundImageProcessor.swift +0 -293
- package/ios/KaleidoscopeModule/effects/BlurProcessor.swift +0 -238
- package/ios/KaleidoscopeModule/resources/backgrounds/dark-office.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/debug-resolutions.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/home-dark.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/home-light.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/light-office.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/nature-dark.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/nature-light.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/simiancraft-dark.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/simiancraft-light.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/stylized-dark.webp +0 -0
- package/ios/KaleidoscopeModule/resources/backgrounds/stylized-light.webp +0 -0
- package/ios/KaleidoscopeModule/shaders/blur.metalsrc +0 -72
- package/ios/KaleidoscopeModule/shaders/composite.metalsrc +0 -22
- package/src/backgrounds/README.md +0 -83
- package/src/backgrounds/dark-office.ts +0 -6
- package/src/backgrounds/dark-office.web.ts +0 -9
- package/src/backgrounds/dark-office.webp +0 -0
- package/src/backgrounds/debug-resolutions.ts +0 -7
- package/src/backgrounds/debug-resolutions.web.ts +0 -9
- package/src/backgrounds/debug-resolutions.webp +0 -0
- package/src/backgrounds/home-dark.ts +0 -6
- package/src/backgrounds/home-dark.web.ts +0 -7
- package/src/backgrounds/home-dark.webp +0 -0
- package/src/backgrounds/home-light.ts +0 -6
- package/src/backgrounds/home-light.web.ts +0 -7
- package/src/backgrounds/home-light.webp +0 -0
- package/src/backgrounds/index.ts +0 -7
- package/src/backgrounds/light-office.ts +0 -6
- package/src/backgrounds/light-office.web.ts +0 -9
- package/src/backgrounds/light-office.webp +0 -0
- package/src/backgrounds/nature-dark.ts +0 -6
- package/src/backgrounds/nature-dark.web.ts +0 -7
- package/src/backgrounds/nature-dark.webp +0 -0
- package/src/backgrounds/nature-light.ts +0 -6
- package/src/backgrounds/nature-light.web.ts +0 -7
- package/src/backgrounds/nature-light.webp +0 -0
- package/src/backgrounds/preset-source.types.ts +0 -5
- package/src/backgrounds/presets.ts +0 -36
- package/src/backgrounds/simiancraft-dark.ts +0 -6
- package/src/backgrounds/simiancraft-dark.web.ts +0 -7
- package/src/backgrounds/simiancraft-dark.webp +0 -0
- package/src/backgrounds/simiancraft-light.ts +0 -6
- package/src/backgrounds/simiancraft-light.web.ts +0 -7
- package/src/backgrounds/simiancraft-light.webp +0 -0
- package/src/backgrounds/stylized-dark.ts +0 -6
- package/src/backgrounds/stylized-dark.web.ts +0 -7
- package/src/backgrounds/stylized-dark.webp +0 -0
- package/src/backgrounds/stylized-light.ts +0 -6
- package/src/backgrounds/stylized-light.web.ts +0 -7
- package/src/backgrounds/stylized-light.webp +0 -0
- package/src/types.ts +0 -89
- package/src/web/blur-kernel.ts +0 -44
- package/src/web/effects/background-image.ts +0 -364
- package/src/web/effects/blur.ts +0 -430
- package/src/web/effects/transform.ts +0 -69
- package/src/web/insertable-streams.ts +0 -112
- package/src/web/segmenter.ts +0 -107
- package/src/web/shaders.generated.ts +0 -56
- package/src/web/shaders.ts +0 -31
- package/src/web/tuning.ts +0 -67
- /package/{src/backgrounds → catalog/images}/assets.d.ts +0 -0
- /package/{android/src/main/assets/backgrounds → catalog/images/debug}/debug-resolutions.webp +0 -0
- /package/{android/src/main/assets/backgrounds → catalog/images/home}/home-dark.webp +0 -0
- /package/{android/src/main/assets/backgrounds → catalog/images/home}/home-light.webp +0 -0
- /package/{android/src/main/assets/backgrounds/nature-dark.webp → catalog/images/nature/landscape-dark.webp} +0 -0
- /package/{android/src/main/assets/backgrounds/nature-light.webp → catalog/images/nature/landscape-light.webp} +0 -0
- /package/{android/src/main/assets/backgrounds/dark-office.webp → catalog/images/office/office-dark.webp} +0 -0
- /package/{android/src/main/assets/backgrounds/light-office.webp → catalog/images/office/office-light.webp} +0 -0
- /package/{android/src/main/assets/backgrounds/stylized-light.webp → catalog/images/sci-fi/sci-fi-light.webp} +0 -0
- /package/{android/src/main/assets/backgrounds → catalog/images/simiancraft}/simiancraft-dark.webp +0 -0
- /package/{android/src/main/assets/backgrounds → catalog/images/simiancraft}/simiancraft-light.webp +0 -0
- /package/dist/{backgrounds → catalog/images/debug}/debug-resolutions.webp +0 -0
- /package/dist/{backgrounds → catalog/images/home}/home-dark.webp +0 -0
- /package/dist/{backgrounds → catalog/images/home}/home-light.webp +0 -0
- /package/dist/{backgrounds/nature-dark.webp → catalog/images/nature/landscape-dark.webp} +0 -0
- /package/dist/{backgrounds/nature-light.webp → catalog/images/nature/landscape-light.webp} +0 -0
- /package/dist/{backgrounds/dark-office.webp → catalog/images/office/office-dark.webp} +0 -0
- /package/dist/{backgrounds/light-office.webp → catalog/images/office/office-light.webp} +0 -0
- /package/dist/{backgrounds/stylized-light.webp → catalog/images/sci-fi/sci-fi-light.webp} +0 -0
- /package/dist/{backgrounds → catalog/images/simiancraft}/simiancraft-dark.webp +0 -0
- /package/dist/{backgrounds → catalog/images/simiancraft}/simiancraft-light.webp +0 -0
- /package/dist/{web → web-driver}/insertable-streams.d.ts +0 -0
- /package/dist/{web → web-driver}/segmenter.d.ts +0 -0
- /package/dist/{web → web-driver}/tuning.d.ts +0 -0
|
@@ -0,0 +1,906 @@
|
|
|
1
|
+
// iOS composite compositor. Mirrors android/.../effects/CompositeFactory.kt on the iOS
|
|
2
|
+
// Metal pipeline.
|
|
3
|
+
//
|
|
4
|
+
// The multi-layer generalization of ShaderProcessor: a composite is an ordered
|
|
5
|
+
// painter's stack of layers (CompositeLayers, delivered from JS via setCompositeLayers),
|
|
6
|
+
// composited into ONE output texture, layer 0 opaque, later layers blended over.
|
|
7
|
+
// One processor instance serves EVERY composite; the layer stack is data, swapped
|
|
8
|
+
// from JS as the active composite changes, so adding a composite needs no Swift change.
|
|
9
|
+
//
|
|
10
|
+
// Per frame (builds on BackgroundImageProcessor / ShaderProcessor):
|
|
11
|
+
// 1. Ingest the camera CVPixelBuffer (NV12) into the DISPLAY-UPRIGHT "original"
|
|
12
|
+
// BGRA Metal texture via CoreImage (Ingest.swift), as elsewhere.
|
|
13
|
+
// 2. If any layer targets the subject, read the latest mask (Segmenter). The
|
|
14
|
+
// composite's BACKGROUND layers are mask-independent, so the composite composites
|
|
15
|
+
// every frame and ONLY the subject layer is skipped until a mask has
|
|
16
|
+
// completed (mirroring CompositeFactory drawing the rest of the stack and
|
|
17
|
+
// skipping the subject on maskTexId == -1). Kick a new segmentation when
|
|
18
|
+
// idle.
|
|
19
|
+
// 3. Composite every layer into the output buffer's BGRA texture. Each layer's
|
|
20
|
+
// OUTPUT draw is its own composite encoder (the first actual draw clears to
|
|
21
|
+
// opaque black, establishing the base; later draws `.load` and blend with
|
|
22
|
+
// premultiplied over (normal) or add (additive)). A scratch-backed layer
|
|
23
|
+
// renders its content into a .private scratch texture in a SEPARATE pass
|
|
24
|
+
// first. Per layer kind (mirrors the generalized composite.ts / CompositeFactory):
|
|
25
|
+
// - 'image'/background : cover-fit the image (composite-image.metalsrc).
|
|
26
|
+
// - 'direct'/background : raw camera fullscreen (composite-camera.metalsrc).
|
|
27
|
+
// - 'blur'/background : two-pass camera-sampling gaussian
|
|
28
|
+
// (composite-blur.metalsrc) into scratchA->scratchB, then blit
|
|
29
|
+
// (composite-blit.metalsrc).
|
|
30
|
+
// - generative/background : render its frag (the layer .metalsrc, generic
|
|
31
|
+
// uniform-by-name binding) with uTime/uResolution + uniforms.
|
|
32
|
+
// - 'direct'/subject : the masked person (composite-subject.metalsrc).
|
|
33
|
+
// - ANY other layer / subject : render the layer to a scratch, then a
|
|
34
|
+
// masked-composite (composite-masked.metalsrc) multiplies it by
|
|
35
|
+
// the mask alpha. So generative/blur/image can target subject.
|
|
36
|
+
// Subject layers are skipped until a mask has completed (step 2).
|
|
37
|
+
// 4. Hand off via R3 frame-pipelining (commitPipelined), returning the PREVIOUS
|
|
38
|
+
// completed frame, exactly like the other processors.
|
|
39
|
+
//
|
|
40
|
+
// One instance, shared across every frame, so all mutable state is guarded by an
|
|
41
|
+
// os_unfair_lock. Every failure path logs under Kaleidoscope.Composite and returns
|
|
42
|
+
// the ORIGINAL frame; the processor must never crash the capture pipeline.
|
|
43
|
+
|
|
44
|
+
import CoreVideo
|
|
45
|
+
import Foundation
|
|
46
|
+
import Metal
|
|
47
|
+
import MetalKit
|
|
48
|
+
import os.log
|
|
49
|
+
import QuartzCore
|
|
50
|
+
import simd
|
|
51
|
+
import WebRTC
|
|
52
|
+
#if canImport(livekit_react_native_webrtc)
|
|
53
|
+
import livekit_react_native_webrtc
|
|
54
|
+
#elseif canImport(react_native_webrtc)
|
|
55
|
+
import react_native_webrtc
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
@objc(KaleidoscopeCompositeProcessor)
|
|
59
|
+
public final class CompositeProcessor: NSObject, VideoFrameProcessorDelegate {
|
|
60
|
+
private static let log = OSLog(subsystem: "com.simiancraft.kaleidoscope", category: "Composite")
|
|
61
|
+
|
|
62
|
+
private var unsafeLock = os_unfair_lock_s()
|
|
63
|
+
private var renderer: MetalRenderer?
|
|
64
|
+
private var rendererFailed = false
|
|
65
|
+
private let segmenter = Segmenter()
|
|
66
|
+
|
|
67
|
+
// Fixed (non-generative) layer fragments, compiled once. Each lives in its own
|
|
68
|
+
// .metalsrc; the output-drawing ones (image, subject, camera, blit, masked) need
|
|
69
|
+
// the three blend variants (opaque base, over, additive), cached by blend mode.
|
|
70
|
+
// The blur fragment runs into a scratch with blend OFF (its own .dontCare pass),
|
|
71
|
+
// so it needs a plain generative-style pipeline, not a blend variant.
|
|
72
|
+
private var imageFragment: MTLFunction?
|
|
73
|
+
private var subjectFragment: MTLFunction?
|
|
74
|
+
private var cameraFragment: MTLFunction?
|
|
75
|
+
private var blitFragment: MTLFunction?
|
|
76
|
+
private var maskedFragment: MTLFunction?
|
|
77
|
+
private var blurFragment: MTLFunction?
|
|
78
|
+
private var blurPipeline: MTLRenderPipelineState?
|
|
79
|
+
private var imageFailed = false
|
|
80
|
+
private var subjectFailed = false
|
|
81
|
+
private var cameraFailed = false
|
|
82
|
+
private var blitFailed = false
|
|
83
|
+
private var maskedFailed = false
|
|
84
|
+
private var blurFailed = false
|
|
85
|
+
|
|
86
|
+
// Buffer-index maps for the fixed fragments that bind by NAME (resolved from the
|
|
87
|
+
// transpiled .metalsrc via ShaderLibrary.uniformBufferIndices) instead of
|
|
88
|
+
// hardcoded positions, so a spirv-cross re-order can't silently swap a uniform.
|
|
89
|
+
// Populated alongside the fragment in the matching ensure*Fragment.
|
|
90
|
+
private var subjectUniformIndices: [String: Int] = [:]
|
|
91
|
+
private var maskedUniformIndices: [String: Int] = [:]
|
|
92
|
+
private var blurUniformIndices: [String: Int] = [:]
|
|
93
|
+
|
|
94
|
+
/// Pipeline-state cache keyed by "<fragment label>|<blend>". Image, subject, and
|
|
95
|
+
/// each generative shader get one pipeline per blend mode used. Built lazily.
|
|
96
|
+
private var pipelineCache = [String: MTLRenderPipelineState]()
|
|
97
|
+
|
|
98
|
+
// Generative layer fragments + their uniform-index maps, cached by shader name
|
|
99
|
+
// (mirrors ShaderProcessor.ensureGenerative). A failed build is remembered so
|
|
100
|
+
// we don't recompile per frame.
|
|
101
|
+
private var generativeFragments = [String: MTLFunction]()
|
|
102
|
+
private var generativeUniformIndices = [String: [String: Int]]()
|
|
103
|
+
private var generativeFailed = Set<String>()
|
|
104
|
+
|
|
105
|
+
// Image textures by id, loaded lazily on first use; cached for the session.
|
|
106
|
+
// Each entry carries the source aspect for cover-fit. A failed load is
|
|
107
|
+
// remembered so we don't re-read the bundle every frame.
|
|
108
|
+
private var imageTextures = [String: ImageTexture]()
|
|
109
|
+
private var missingImages = Set<String>()
|
|
110
|
+
|
|
111
|
+
/// Host monotonic clock origin for uTime (CACurrentMediaTime; see ShaderProcessor).
|
|
112
|
+
private var startTime: CFTimeInterval?
|
|
113
|
+
|
|
114
|
+
private static let builtinNames: Set<String> = ["uTime", "uResolution"]
|
|
115
|
+
private static let imagesSubdir = "images"
|
|
116
|
+
|
|
117
|
+
private struct ImageTexture {
|
|
118
|
+
let texture: MTLTexture
|
|
119
|
+
let aspect: Float
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@objc override public init() {
|
|
123
|
+
super.init()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@objc(capturer:didCaptureVideoFrame:)
|
|
127
|
+
public func capturer(
|
|
128
|
+
_: RTCVideoCapturer,
|
|
129
|
+
didCapture frame: RTCVideoFrame
|
|
130
|
+
) -> RTCVideoFrame {
|
|
131
|
+
os_unfair_lock_lock(&unsafeLock)
|
|
132
|
+
defer { os_unfair_lock_unlock(&unsafeLock) }
|
|
133
|
+
do {
|
|
134
|
+
return try process(frame)
|
|
135
|
+
} catch {
|
|
136
|
+
os_log("composite failed; forwarding original. %{public}@",
|
|
137
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
138
|
+
return frame
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func ensureRenderer() throws -> MetalRenderer {
|
|
143
|
+
if let renderer { return renderer }
|
|
144
|
+
if rendererFailed { throw RendererError.noMetalDevice }
|
|
145
|
+
do {
|
|
146
|
+
let created = try MetalRenderer(bundle: Bundle(for: CompositeProcessor.self))
|
|
147
|
+
renderer = created
|
|
148
|
+
return created
|
|
149
|
+
} catch {
|
|
150
|
+
rendererFailed = true
|
|
151
|
+
throw error
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private func process(_ frame: RTCVideoFrame) throws -> RTCVideoFrame {
|
|
156
|
+
let layers = CompositeLayers.get()
|
|
157
|
+
if layers.isEmpty {
|
|
158
|
+
// No composite spec delivered yet (or it was cleared). Forward the original.
|
|
159
|
+
return frame
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
guard let input = FrameBridge.inputPixelBuffer(frame) else {
|
|
163
|
+
return frame
|
|
164
|
+
}
|
|
165
|
+
let bufferW = CVPixelBufferGetWidth(input)
|
|
166
|
+
let bufferH = CVPixelBufferGetHeight(input)
|
|
167
|
+
guard bufferW > 0, bufferH > 0 else { return frame }
|
|
168
|
+
|
|
169
|
+
let renderer = try ensureRenderer()
|
|
170
|
+
|
|
171
|
+
// Step 1: ingest NV12 -> DISPLAY-UPRIGHT "original" BGRA texture.
|
|
172
|
+
let rotation = frame.rotation.rawValue
|
|
173
|
+
let width = Ingest.displayWidth(bufferWidth: bufferW, bufferHeight: bufferH, rotation: rotation)
|
|
174
|
+
let height = Ingest.displayHeight(bufferWidth: bufferW, bufferHeight: bufferH, rotation: rotation)
|
|
175
|
+
let (originalBuffer, originalTexture, originalWrapper) = try renderer.originalIngestTarget(
|
|
176
|
+
width: width, height: height
|
|
177
|
+
)
|
|
178
|
+
try TextureBridge.ingest(input: input, into: originalBuffer, frameRotation: rotation)
|
|
179
|
+
|
|
180
|
+
// Step 2: mask, only if a subject layer is present. Unlike the single-effect
|
|
181
|
+
// processors (which forward the original until a mask warms up), a composite's
|
|
182
|
+
// BACKGROUND layers are mask-independent, so we composite the stack regardless
|
|
183
|
+
// and skip ONLY the subject layer when no mask has completed yet; mirroring
|
|
184
|
+
// CompositeFactory, which draws the rest of the stack and skips the subject on
|
|
185
|
+
// maskTexId == -1. Always kick a new segmentation if idle so the mask keeps
|
|
186
|
+
// refreshing.
|
|
187
|
+
let needsSubject = layers.contains { $0.target == "subject" }
|
|
188
|
+
var maskTexture: MTLTexture?
|
|
189
|
+
var maskWrapper: CVMetalTexture?
|
|
190
|
+
var maskBuffer: CVPixelBuffer?
|
|
191
|
+
if needsSubject {
|
|
192
|
+
segmenter.kickIfIdle(input: originalBuffer)
|
|
193
|
+
if let buffer = segmenter.latestMask() {
|
|
194
|
+
let (texture, wrapper) = try TextureBridge.makeTexture(
|
|
195
|
+
from: buffer, cache: renderer.textureCache, pixelFormat: .r8Unorm, planeIndex: 0
|
|
196
|
+
)
|
|
197
|
+
maskBuffer = buffer
|
|
198
|
+
maskTexture = texture
|
|
199
|
+
maskWrapper = wrapper
|
|
200
|
+
}
|
|
201
|
+
// maskTexture stays nil until the first mask completes; the subject layer is
|
|
202
|
+
// skipped those frames (drawLayer guards on a non-nil mask).
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Anchor the monotonic clock at first frame; uTime is seconds since then.
|
|
206
|
+
let now = CACurrentMediaTime()
|
|
207
|
+
if startTime == nil { startTime = now }
|
|
208
|
+
let elapsed = Float(now - (startTime ?? now))
|
|
209
|
+
|
|
210
|
+
let (maskLo, maskHi) = MaskTuning.smoothstepRange(
|
|
211
|
+
hardness: EffectTuning.maskHardness,
|
|
212
|
+
threshold: EffectTuning.maskThreshold
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
// Step 3: composite every layer into the output buffer's texture in one pass.
|
|
216
|
+
let output = try renderer.dequeueOutputBuffer(width: width, height: height)
|
|
217
|
+
let (outputTexture, outputWrapper) = try TextureBridge.makeTexture(
|
|
218
|
+
from: output, cache: renderer.textureCache, pixelFormat: .bgra8Unorm, planeIndex: 0
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
let commandBuffer = try renderer.makeCommandBuffer()
|
|
222
|
+
commandBuffer.label = "Kaleidoscope.Composite"
|
|
223
|
+
|
|
224
|
+
// Composite the stack into the output texture. Unlike a single open encoder
|
|
225
|
+
// for the whole stack, each layer's OUTPUT draw gets its own composite encoder:
|
|
226
|
+
// the base opens `.clear` (opaque black), later layers open `.load`
|
|
227
|
+
// (preserve the running composite). A scratch-backed layer (blur, or any
|
|
228
|
+
// non-direct subject layer) renders its content into a .private scratch in a
|
|
229
|
+
// SEPARATE pass first, then the output encoder samples it. Two encoders
|
|
230
|
+
// cannot be open at once on one command buffer, so the per-layer-encoder
|
|
231
|
+
// shape is what lets the scratch passes interleave. Mirrors the GL "bind
|
|
232
|
+
// output FBO, set blend, draw" the other platforms repeat per layer.
|
|
233
|
+
var isFirstOutputDraw = true
|
|
234
|
+
for (index, layer) in layers.enumerated() {
|
|
235
|
+
let blend = blendFor(isBase: index == 0, blend: layer.blend)
|
|
236
|
+
drawLayer(
|
|
237
|
+
commandBuffer: commandBuffer, renderer: renderer, layer: layer, blend: blend,
|
|
238
|
+
isFirstOutputDraw: &isFirstOutputDraw,
|
|
239
|
+
outputTexture: outputTexture, width: width, height: height, elapsed: elapsed,
|
|
240
|
+
camera: originalTexture, mask: maskTexture,
|
|
241
|
+
maskLo: maskLo, maskHi: maskHi
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
// If NO layer produced an output draw (e.g. a single subject layer with no
|
|
245
|
+
// mask yet), the output texture was never cleared. Clear it to opaque black
|
|
246
|
+
// so the frame is defined rather than reading the pooled buffer's stale
|
|
247
|
+
// contents. A cheap clear-only pass.
|
|
248
|
+
if isFirstOutputDraw {
|
|
249
|
+
let clearEncoder = try renderer.beginCompositeEncoder(
|
|
250
|
+
commandBuffer: commandBuffer, target: outputTexture, clear: true, label: "composite-clear"
|
|
251
|
+
)
|
|
252
|
+
clearEncoder.endEncoding()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Step 4: R3 frame-pipelining. keepAlive holds the per-frame inputs the
|
|
256
|
+
// in-flight GPU command buffer still reads after process() returns: the
|
|
257
|
+
// pooled original buffer + wrapper, the output wrapper, and (when a subject
|
|
258
|
+
// layer ran) the mask buffer + wrapper. Image textures are loaded once via
|
|
259
|
+
// MTKTextureLoader and cached on this instance (.private, not pool buffers),
|
|
260
|
+
// so they need no keep-alive, same as BackgroundImageProcessor's background.
|
|
261
|
+
var keepAlive: [Any] = [originalBuffer, originalWrapper, outputWrapper]
|
|
262
|
+
if let maskBuffer { keepAlive.append(maskBuffer) }
|
|
263
|
+
if let maskWrapper { keepAlive.append(maskWrapper) }
|
|
264
|
+
|
|
265
|
+
guard let ready = renderer.commitPipelined(
|
|
266
|
+
commandBuffer,
|
|
267
|
+
currentOutput: output,
|
|
268
|
+
keepAlive: keepAlive,
|
|
269
|
+
debugTiming: EffectTuning.debugTiming,
|
|
270
|
+
timingLabel: "composite"
|
|
271
|
+
) else {
|
|
272
|
+
return frame
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return FrameBridge.makeOutputFrame(pixelBuffer: ready, like: frame)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/// Map (isBase, blend string) to a CompositeBlend. Base is opaque; "additive" maps
|
|
279
|
+
/// to add; everything else (nil, "normal") maps to premultiplied over. Mirrors
|
|
280
|
+
/// CompositeFactory.applyBlend.
|
|
281
|
+
private func blendFor(isBase: Bool, blend: String?) -> MetalRenderer.CompositeBlend {
|
|
282
|
+
if isBase { return .opaqueBase }
|
|
283
|
+
if blend == "additive" { return .additive }
|
|
284
|
+
return .over
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/// The per-pass V parity a scratch carries (see the V-FLIP reasoning at the top
|
|
288
|
+
/// of renderContentToScratch). A single-pass scratch (image / generative) is
|
|
289
|
+
/// V-flipped relative to a direct draw; a two-pass blur scratch is not.
|
|
290
|
+
private static let scratchOddParity =
|
|
291
|
+
(scale: SIMD2<Float>(1, -1), offset: SIMD2<Float>(0, 1))
|
|
292
|
+
private static let scratchEvenParity =
|
|
293
|
+
(scale: SIMD2<Float>(1, 1), offset: SIMD2<Float>(0, 0))
|
|
294
|
+
|
|
295
|
+
// Composite one layer onto the output. Mirrors the per-layer body of composite.ts /
|
|
296
|
+
// CompositeFactory.drawLayer: a 'subject' layer is mask-stenciled (direct takes the
|
|
297
|
+
// one-pass cam x mask fast path; any other shader renders to a scratch then a
|
|
298
|
+
// masked-composite multiplies by the mask alpha), a 'background' layer draws
|
|
299
|
+
// fullscreen (image cover-fit, direct raw camera, blur the two-pass gaussian,
|
|
300
|
+
// generative its frag). Any failure to build a pipeline / load a image / compile
|
|
301
|
+
// a shader skips THIS layer (logged once) rather than aborting the frame, so a
|
|
302
|
+
// partial composite still composites; mirroring CompositeFactory's per-layer skips.
|
|
303
|
+
//
|
|
304
|
+
// Each output draw opens its OWN composite encoder (clear on the first actual draw,
|
|
305
|
+
// load after); scratch-backed layers render their content in a separate pass
|
|
306
|
+
// first. `isFirstOutputDraw` is inout so the FIRST layer that actually draws
|
|
307
|
+
// clears the output (establishing the opaque base) even if the declared base
|
|
308
|
+
// layer was skipped (e.g. a subject layer with no mask yet).
|
|
309
|
+
private func drawLayer(
|
|
310
|
+
commandBuffer: MTLCommandBuffer,
|
|
311
|
+
renderer: MetalRenderer,
|
|
312
|
+
layer: CompositeLayer,
|
|
313
|
+
blend: MetalRenderer.CompositeBlend,
|
|
314
|
+
isFirstOutputDraw: inout Bool,
|
|
315
|
+
outputTexture: MTLTexture,
|
|
316
|
+
width: Int,
|
|
317
|
+
height: Int,
|
|
318
|
+
elapsed: Float,
|
|
319
|
+
camera: MTLTexture,
|
|
320
|
+
mask: MTLTexture?,
|
|
321
|
+
maskLo: Float,
|
|
322
|
+
maskHi: Float
|
|
323
|
+
) {
|
|
324
|
+
if layer.target == "subject" {
|
|
325
|
+
// Subject layers need the mask; skip until it warms up (mirrors web's
|
|
326
|
+
// subjectReady guard / CompositeFactory's maskTexId == -1 skip).
|
|
327
|
+
guard let mask else { return }
|
|
328
|
+
if layer.shader == "direct" {
|
|
329
|
+
// One-pass fast path: cam x mask.
|
|
330
|
+
guard let subject = ensureSubjectFragment(renderer: renderer),
|
|
331
|
+
let pipeline = ensurePipeline(
|
|
332
|
+
fragment: subject.fragment,
|
|
333
|
+
fragmentLabel: "composite-subject",
|
|
334
|
+
blend: blend,
|
|
335
|
+
renderer: renderer
|
|
336
|
+
) else { return }
|
|
337
|
+
withOutputEncoder(
|
|
338
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
339
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-subject-direct"
|
|
340
|
+
) { encoder in
|
|
341
|
+
// iOS mask is aligned with the camera (the Segmenter's flip bracket),
|
|
342
|
+
// so identity mask UV, unlike web's V-flip.
|
|
343
|
+
renderer.drawCompositeSubjectLayer(
|
|
344
|
+
encoder: encoder, pipeline: pipeline, indices: subject.indices,
|
|
345
|
+
camera: camera, mask: mask,
|
|
346
|
+
maskUvScale: SIMD2<Float>(1, 1), maskUvOffset: SIMD2<Float>(0, 0),
|
|
347
|
+
maskLo: maskLo, maskHi: maskHi
|
|
348
|
+
)
|
|
349
|
+
}
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
// Render the layer's content to a scratch, then stencil it through the mask.
|
|
353
|
+
guard let content = renderContentToScratch(
|
|
354
|
+
commandBuffer: commandBuffer, renderer: renderer, layer: layer,
|
|
355
|
+
width: width, height: height, elapsed: elapsed, camera: camera
|
|
356
|
+
) else { return }
|
|
357
|
+
guard let masked = ensureMaskedFragment(renderer: renderer),
|
|
358
|
+
let pipeline = ensurePipeline(
|
|
359
|
+
fragment: masked.fragment, fragmentLabel: "composite-masked", blend: blend, renderer: renderer
|
|
360
|
+
) else { return }
|
|
361
|
+
withOutputEncoder(
|
|
362
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
363
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-masked"
|
|
364
|
+
) { encoder in
|
|
365
|
+
renderer.drawCompositeMaskedLayer(
|
|
366
|
+
encoder: encoder, pipeline: pipeline, indices: masked.indices,
|
|
367
|
+
content: content.texture, mask: mask,
|
|
368
|
+
maskUvScale: SIMD2<Float>(1, 1), maskUvOffset: SIMD2<Float>(0, 0),
|
|
369
|
+
maskLo: maskLo, maskHi: maskHi
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
return
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Background layers draw fullscreen.
|
|
376
|
+
switch layer.shader {
|
|
377
|
+
case "image":
|
|
378
|
+
guard let id = layer.source else {
|
|
379
|
+
os_log("image layer has no source id; skipping", log: CompositeProcessor.log, type: .info)
|
|
380
|
+
return
|
|
381
|
+
}
|
|
382
|
+
guard let image = ensureImageTexture(id: id, device: renderer.device),
|
|
383
|
+
let fragment = ensureImageFragment(renderer: renderer),
|
|
384
|
+
let pipeline = ensurePipeline(
|
|
385
|
+
fragment: fragment, fragmentLabel: "composite-image", blend: blend, renderer: renderer
|
|
386
|
+
) else { return }
|
|
387
|
+
let cover = coverScale(outW: width, outH: height, imgAspect: image.aspect)
|
|
388
|
+
withOutputEncoder(
|
|
389
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
390
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-image"
|
|
391
|
+
) { encoder in
|
|
392
|
+
renderer.drawCompositeImageLayer(
|
|
393
|
+
encoder: encoder, pipeline: pipeline, image: image.texture, coverScale: cover
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
case "direct":
|
|
397
|
+
// Raw camera fullscreen.
|
|
398
|
+
guard let fragment = ensureCameraFragment(renderer: renderer),
|
|
399
|
+
let pipeline = ensurePipeline(
|
|
400
|
+
fragment: fragment, fragmentLabel: "composite-camera", blend: blend, renderer: renderer
|
|
401
|
+
) else { return }
|
|
402
|
+
withOutputEncoder(
|
|
403
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
404
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-camera"
|
|
405
|
+
) { encoder in
|
|
406
|
+
renderer.drawCompositeCameraLayer(encoder: encoder, pipeline: pipeline, camera: camera)
|
|
407
|
+
}
|
|
408
|
+
case "blur":
|
|
409
|
+
// Two-pass gaussian into a scratch, then blit the scratch to the output.
|
|
410
|
+
guard let content = renderContentToScratch(
|
|
411
|
+
commandBuffer: commandBuffer, renderer: renderer, layer: layer,
|
|
412
|
+
width: width, height: height, elapsed: elapsed, camera: camera
|
|
413
|
+
) else { return }
|
|
414
|
+
guard let fragment = ensureBlitFragment(renderer: renderer),
|
|
415
|
+
let pipeline = ensurePipeline(
|
|
416
|
+
fragment: fragment, fragmentLabel: "composite-blit", blend: blend, renderer: renderer
|
|
417
|
+
) else { return }
|
|
418
|
+
withOutputEncoder(
|
|
419
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
420
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-blit"
|
|
421
|
+
) { encoder in
|
|
422
|
+
renderer.drawCompositeBlitLayer(
|
|
423
|
+
encoder: encoder, pipeline: pipeline, content: content.texture,
|
|
424
|
+
contentUvScale: content.uvScale, contentUvOffset: content.uvOffset
|
|
425
|
+
)
|
|
426
|
+
}
|
|
427
|
+
default:
|
|
428
|
+
// Generative background.
|
|
429
|
+
guard let (fragment, indices) = ensureGenerative(name: layer.shader, renderer: renderer),
|
|
430
|
+
let pipeline = ensurePipeline(
|
|
431
|
+
fragment: fragment, fragmentLabel: layer.shader, blend: blend, renderer: renderer
|
|
432
|
+
) else { return }
|
|
433
|
+
let builtins = makeBuiltinBindings(indices: indices, elapsed: elapsed, width: width, height: height)
|
|
434
|
+
let uniforms = makeUniformBindings(indices: indices, layer: layer)
|
|
435
|
+
withOutputEncoder(
|
|
436
|
+
commandBuffer: commandBuffer, renderer: renderer, outputTexture: outputTexture,
|
|
437
|
+
isFirstOutputDraw: &isFirstOutputDraw, label: "composite-\(layer.shader)"
|
|
438
|
+
) { encoder in
|
|
439
|
+
renderer.drawCompositeGenerativeLayer(
|
|
440
|
+
encoder: encoder, pipeline: pipeline, builtinBindings: builtins, uniformBindings: uniforms
|
|
441
|
+
)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/// Open a one-layer output composite encoder, run `draw`, end it. The FIRST actual
|
|
447
|
+
/// output draw clears the output to opaque black (establishing the base); every
|
|
448
|
+
/// later draw loads the running composite so the pipeline's blend accumulates.
|
|
449
|
+
/// `isFirstOutputDraw` flips false after the first real draw.
|
|
450
|
+
private func withOutputEncoder(
|
|
451
|
+
commandBuffer: MTLCommandBuffer,
|
|
452
|
+
renderer: MetalRenderer,
|
|
453
|
+
outputTexture: MTLTexture,
|
|
454
|
+
isFirstOutputDraw: inout Bool,
|
|
455
|
+
label: String,
|
|
456
|
+
_ draw: (MTLRenderCommandEncoder) -> Void
|
|
457
|
+
) {
|
|
458
|
+
do {
|
|
459
|
+
let encoder = try renderer.beginCompositeEncoder(
|
|
460
|
+
commandBuffer: commandBuffer, target: outputTexture,
|
|
461
|
+
clear: isFirstOutputDraw, label: label
|
|
462
|
+
)
|
|
463
|
+
draw(encoder)
|
|
464
|
+
encoder.endEncoding()
|
|
465
|
+
isFirstOutputDraw = false
|
|
466
|
+
} catch {
|
|
467
|
+
os_log("composite output encoder %{public}@ failed: %{public}@",
|
|
468
|
+
log: CompositeProcessor.log, type: .error, label, error.localizedDescription)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/// Render a layer's content into a .private scratch texture (its own pass, blend
|
|
473
|
+
/// off), returning the texture and the content-UV V-parity term the output draw
|
|
474
|
+
/// must apply when it samples it. Mirrors renderContentToScratch in composite.ts /
|
|
475
|
+
/// CompositeFactory.
|
|
476
|
+
///
|
|
477
|
+
/// V-FLIP PARITY (RISK: reasoned, not device-verified): every Metal
|
|
478
|
+
/// render-to-texture pass flips vertically in buffer space relative to a
|
|
479
|
+
/// directly-sampled texture, because the transpiled passthrough vertex does not
|
|
480
|
+
/// negate gl_Position.y (see MetalRenderer header; the BlurProcessor composite
|
|
481
|
+
/// relies on the same property for its odd-pass blurred background). A layer
|
|
482
|
+
/// drawn DIRECTLY into the output (image/camera/generative background) is one
|
|
483
|
+
/// pass and lands correct. Routing a layer through a scratch adds passes:
|
|
484
|
+
/// - blur: camera -> scratchA (1) -> scratchB (2). TWO passes, EVEN parity, so
|
|
485
|
+
/// scratchB matches the camera orientation; the blit samples it with no V
|
|
486
|
+
/// flip (scratchEvenParity).
|
|
487
|
+
/// - image / generative to subject: ONE pass into scratchA, ODD parity, so the
|
|
488
|
+
/// masked-composite samples it V-flipped to undo the extra pass
|
|
489
|
+
/// (scratchOddParity). This restores the same orientation the layer would
|
|
490
|
+
/// have had drawn directly (the composite-image -sy cover term included).
|
|
491
|
+
/// If a subject generative/image renders vertically inverted on device, flip the
|
|
492
|
+
/// scratchOddParity term to even (and vice-versa); that single constant is the
|
|
493
|
+
/// calibration knob, exactly like BlurProcessor's bgUvScale.
|
|
494
|
+
private func renderContentToScratch(
|
|
495
|
+
commandBuffer: MTLCommandBuffer,
|
|
496
|
+
renderer: MetalRenderer,
|
|
497
|
+
layer: CompositeLayer,
|
|
498
|
+
width: Int,
|
|
499
|
+
height: Int,
|
|
500
|
+
elapsed: Float,
|
|
501
|
+
camera: MTLTexture
|
|
502
|
+
) -> (texture: MTLTexture, uvScale: SIMD2<Float>, uvOffset: SIMD2<Float>)? {
|
|
503
|
+
let scratch: (MTLTexture, MTLTexture)
|
|
504
|
+
do {
|
|
505
|
+
scratch = try renderer.compositeScratch(width: width, height: height)
|
|
506
|
+
} catch {
|
|
507
|
+
os_log("composite scratch alloc failed: %{public}@",
|
|
508
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
509
|
+
return nil
|
|
510
|
+
}
|
|
511
|
+
let (scratchA, scratchB) = scratch
|
|
512
|
+
|
|
513
|
+
if layer.shader == "blur" {
|
|
514
|
+
guard let blur = ensureBlurFragment(renderer: renderer),
|
|
515
|
+
let pipeline = ensureBlurPipeline(fragment: blur.fragment, renderer: renderer)
|
|
516
|
+
else {
|
|
517
|
+
return nil
|
|
518
|
+
}
|
|
519
|
+
let sigma = layer.uniforms["sigma"]?.first ?? 4
|
|
520
|
+
do {
|
|
521
|
+
// Horizontal pass: camera -> scratchA.
|
|
522
|
+
try renderer.encodeCompositeBlurPass(
|
|
523
|
+
commandBuffer: commandBuffer, pipeline: pipeline, indices: blur.indices,
|
|
524
|
+
source: camera, target: scratchA,
|
|
525
|
+
dir: SIMD2<Float>(1 / Float(width), 0), sigma: sigma, label: "composite-blur-h"
|
|
526
|
+
)
|
|
527
|
+
// Vertical pass: scratchA -> scratchB.
|
|
528
|
+
try renderer.encodeCompositeBlurPass(
|
|
529
|
+
commandBuffer: commandBuffer, pipeline: pipeline, indices: blur.indices,
|
|
530
|
+
source: scratchA, target: scratchB,
|
|
531
|
+
dir: SIMD2<Float>(0, 1 / Float(height)), sigma: sigma, label: "composite-blur-v"
|
|
532
|
+
)
|
|
533
|
+
} catch {
|
|
534
|
+
os_log("composite blur pass failed: %{public}@",
|
|
535
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
536
|
+
return nil
|
|
537
|
+
}
|
|
538
|
+
return (scratchB, CompositeProcessor.scratchEvenParity.scale, CompositeProcessor.scratchEvenParity.offset)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// image / generative: render once into scratchA (blend off, cleared).
|
|
542
|
+
if layer.shader == "image" {
|
|
543
|
+
guard let id = layer.source else {
|
|
544
|
+
os_log("image layer has no source id; skipping", log: CompositeProcessor.log, type: .info)
|
|
545
|
+
return nil
|
|
546
|
+
}
|
|
547
|
+
guard let image = ensureImageTexture(id: id, device: renderer.device),
|
|
548
|
+
let fragment = ensureImageFragment(renderer: renderer),
|
|
549
|
+
let pipeline = ensurePipeline(
|
|
550
|
+
fragment: fragment, fragmentLabel: "composite-image",
|
|
551
|
+
blend: .opaqueBase, renderer: renderer
|
|
552
|
+
) else { return nil }
|
|
553
|
+
let cover = coverScale(outW: width, outH: height, imgAspect: image.aspect)
|
|
554
|
+
do {
|
|
555
|
+
try renderer.drawFullscreen(
|
|
556
|
+
commandBuffer: commandBuffer, pipeline: pipeline, target: scratchA, label: "composite-image-scratch"
|
|
557
|
+
) { encoder in
|
|
558
|
+
var coverVar = cover
|
|
559
|
+
encoder.setFragmentBytes(&coverVar, length: MemoryLayout<SIMD2<Float>>.stride, index: 0)
|
|
560
|
+
encoder.setFragmentTexture(image.texture, index: 0)
|
|
561
|
+
encoder.setFragmentSamplerState(renderer.linearClampSampler, index: 0)
|
|
562
|
+
}
|
|
563
|
+
} catch {
|
|
564
|
+
os_log("composite image scratch failed: %{public}@",
|
|
565
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
566
|
+
return nil
|
|
567
|
+
}
|
|
568
|
+
return (scratchA, CompositeProcessor.scratchOddParity.scale, CompositeProcessor.scratchOddParity.offset)
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Generative.
|
|
572
|
+
guard let (fragment, indices) = ensureGenerative(name: layer.shader, renderer: renderer),
|
|
573
|
+
let pipeline = ensurePipeline(
|
|
574
|
+
fragment: fragment, fragmentLabel: layer.shader, blend: .opaqueBase, renderer: renderer
|
|
575
|
+
) else { return nil }
|
|
576
|
+
let builtins = makeBuiltinBindings(indices: indices, elapsed: elapsed, width: width, height: height)
|
|
577
|
+
let uniforms = makeUniformBindings(indices: indices, layer: layer)
|
|
578
|
+
do {
|
|
579
|
+
try renderer.encodeGenerative(
|
|
580
|
+
commandBuffer: commandBuffer, pipeline: pipeline, target: scratchA,
|
|
581
|
+
builtinBindings: builtins, uniformBindings: uniforms, label: "composite-\(layer.shader)-scratch"
|
|
582
|
+
)
|
|
583
|
+
} catch {
|
|
584
|
+
os_log("composite generative scratch failed: %{public}@",
|
|
585
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
586
|
+
return nil
|
|
587
|
+
}
|
|
588
|
+
return (scratchA, CompositeProcessor.scratchOddParity.scale, CompositeProcessor.scratchOddParity.offset)
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// MARK: - Pipeline / fragment caches
|
|
592
|
+
|
|
593
|
+
private func ensurePipeline(
|
|
594
|
+
fragment: MTLFunction,
|
|
595
|
+
fragmentLabel: String,
|
|
596
|
+
blend: MetalRenderer.CompositeBlend,
|
|
597
|
+
renderer: MetalRenderer
|
|
598
|
+
) -> MTLRenderPipelineState? {
|
|
599
|
+
let key = "\(fragmentLabel)|\(blend)"
|
|
600
|
+
if let cached = pipelineCache[key] { return cached }
|
|
601
|
+
do {
|
|
602
|
+
let pipeline = try renderer.makeCompositeLayerPipeline(
|
|
603
|
+
fragment: fragment, blend: blend, label: "composite-\(key)"
|
|
604
|
+
)
|
|
605
|
+
pipelineCache[key] = pipeline
|
|
606
|
+
return pipeline
|
|
607
|
+
} catch {
|
|
608
|
+
os_log("composite pipeline %{public}@ build failed: %{public}@",
|
|
609
|
+
log: CompositeProcessor.log, type: .error, key, error.localizedDescription)
|
|
610
|
+
return nil
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
private func ensureImageFragment(renderer: MetalRenderer) -> MTLFunction? {
|
|
615
|
+
if let fragment = imageFragment { return fragment }
|
|
616
|
+
if imageFailed { return nil }
|
|
617
|
+
do {
|
|
618
|
+
let library = try ShaderLibrary(
|
|
619
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: "composite-image"
|
|
620
|
+
)
|
|
621
|
+
let fragment = try library.function()
|
|
622
|
+
imageFragment = fragment
|
|
623
|
+
return fragment
|
|
624
|
+
} catch {
|
|
625
|
+
imageFailed = true
|
|
626
|
+
os_log("composite-image fragment build failed: %{public}@",
|
|
627
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
628
|
+
return nil
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
private func ensureSubjectFragment(
|
|
633
|
+
renderer: MetalRenderer
|
|
634
|
+
) -> (fragment: MTLFunction, indices: [String: Int])? {
|
|
635
|
+
if let fragment = subjectFragment { return (fragment, subjectUniformIndices) }
|
|
636
|
+
if subjectFailed { return nil }
|
|
637
|
+
do {
|
|
638
|
+
let library = try ShaderLibrary(
|
|
639
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: "composite-subject"
|
|
640
|
+
)
|
|
641
|
+
let fragment = try library.function()
|
|
642
|
+
subjectFragment = fragment
|
|
643
|
+
subjectUniformIndices = library.uniformBufferIndices()
|
|
644
|
+
return (fragment, subjectUniformIndices)
|
|
645
|
+
} catch {
|
|
646
|
+
subjectFailed = true
|
|
647
|
+
os_log("composite-subject fragment build failed: %{public}@",
|
|
648
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
649
|
+
return nil
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/// The raw-camera (direct/background) fragment, compiled once from its
|
|
654
|
+
/// hand-authored .metalsrc and cached on success/failure exactly like the
|
|
655
|
+
/// image/subject fragments. The blit and masked-composite fragments load
|
|
656
|
+
/// through ensureBlitFragment / ensureMaskedFragment below.
|
|
657
|
+
private func ensureCameraFragment(renderer: MetalRenderer) -> MTLFunction? {
|
|
658
|
+
if let fragment = cameraFragment { return fragment }
|
|
659
|
+
if cameraFailed { return nil }
|
|
660
|
+
if let fragment = loadFixedFragment(fileName: "composite-camera", renderer: renderer) {
|
|
661
|
+
cameraFragment = fragment
|
|
662
|
+
return fragment
|
|
663
|
+
}
|
|
664
|
+
cameraFailed = true
|
|
665
|
+
return nil
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/// The scratch-blit fragment (blur/background); compiled once and cached on
|
|
669
|
+
/// success/failure, same pattern as ensureCameraFragment.
|
|
670
|
+
private func ensureBlitFragment(renderer: MetalRenderer) -> MTLFunction? {
|
|
671
|
+
if let fragment = blitFragment { return fragment }
|
|
672
|
+
if blitFailed { return nil }
|
|
673
|
+
if let fragment = loadFixedFragment(fileName: "composite-blit", renderer: renderer) {
|
|
674
|
+
blitFragment = fragment
|
|
675
|
+
return fragment
|
|
676
|
+
}
|
|
677
|
+
blitFailed = true
|
|
678
|
+
return nil
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/// The masked-composite fragment (stencil any layer to the subject); compiled
|
|
682
|
+
/// once and cached on success/failure, with its uniform-index map resolved from
|
|
683
|
+
/// the metalsrc so the mask buffers bind by name (same as ensureSubjectFragment).
|
|
684
|
+
private func ensureMaskedFragment(
|
|
685
|
+
renderer: MetalRenderer
|
|
686
|
+
) -> (fragment: MTLFunction, indices: [String: Int])? {
|
|
687
|
+
if let fragment = maskedFragment { return (fragment, maskedUniformIndices) }
|
|
688
|
+
if maskedFailed { return nil }
|
|
689
|
+
do {
|
|
690
|
+
let library = try ShaderLibrary(
|
|
691
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: "composite-masked"
|
|
692
|
+
)
|
|
693
|
+
let fragment = try library.function()
|
|
694
|
+
maskedFragment = fragment
|
|
695
|
+
maskedUniformIndices = library.uniformBufferIndices()
|
|
696
|
+
return (fragment, maskedUniformIndices)
|
|
697
|
+
} catch {
|
|
698
|
+
maskedFailed = true
|
|
699
|
+
os_log("composite-masked fragment build failed: %{public}@",
|
|
700
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
701
|
+
return nil
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
private func ensureBlurFragment(
|
|
706
|
+
renderer: MetalRenderer
|
|
707
|
+
) -> (fragment: MTLFunction, indices: [String: Int])? {
|
|
708
|
+
if let fragment = blurFragment { return (fragment, blurUniformIndices) }
|
|
709
|
+
if blurFailed { return nil }
|
|
710
|
+
do {
|
|
711
|
+
let library = try ShaderLibrary(
|
|
712
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: "composite-blur"
|
|
713
|
+
)
|
|
714
|
+
let fragment = try library.function()
|
|
715
|
+
blurFragment = fragment
|
|
716
|
+
blurUniformIndices = library.uniformBufferIndices()
|
|
717
|
+
return (fragment, blurUniformIndices)
|
|
718
|
+
} catch {
|
|
719
|
+
blurFailed = true
|
|
720
|
+
os_log("composite-blur fragment build failed: %{public}@",
|
|
721
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
722
|
+
return nil
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/// The blur pass runs into a scratch with blend OFF (a .dontCare pass via
|
|
727
|
+
/// drawFullscreen), so it needs a plain non-blended pipeline (makeGenerative-
|
|
728
|
+
/// Pipeline), not one of the CompositeBlend variants the output draws use. Built once.
|
|
729
|
+
private func ensureBlurPipeline(
|
|
730
|
+
fragment: MTLFunction, renderer: MetalRenderer
|
|
731
|
+
) -> MTLRenderPipelineState? {
|
|
732
|
+
if let pipeline = blurPipeline { return pipeline }
|
|
733
|
+
do {
|
|
734
|
+
let pipeline = try renderer.makeGenerativePipeline(fragment: fragment, label: "composite-blur")
|
|
735
|
+
blurPipeline = pipeline
|
|
736
|
+
return pipeline
|
|
737
|
+
} catch {
|
|
738
|
+
blurFailed = true
|
|
739
|
+
os_log("composite-blur pipeline build failed: %{public}@",
|
|
740
|
+
log: CompositeProcessor.log, type: .error, error.localizedDescription)
|
|
741
|
+
return nil
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/// Compile a hand-authored fixed-binding fragment (`<fileName>.metalsrc`) into its
|
|
746
|
+
/// own MTLLibrary and return its `main0`. Logs and returns nil on failure; the
|
|
747
|
+
/// caller remembers the failure so it doesn't recompile per frame.
|
|
748
|
+
private func loadFixedFragment(fileName: String, renderer: MetalRenderer) -> MTLFunction? {
|
|
749
|
+
do {
|
|
750
|
+
let library = try ShaderLibrary(
|
|
751
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: fileName
|
|
752
|
+
)
|
|
753
|
+
return try library.function()
|
|
754
|
+
} catch {
|
|
755
|
+
os_log("%{public}@ fragment build failed: %{public}@",
|
|
756
|
+
log: CompositeProcessor.log, type: .error, fileName, error.localizedDescription)
|
|
757
|
+
return nil
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/// Build-or-return a generative layer fragment + its uniform-index map. Compiles
|
|
762
|
+
/// `<name>.metalsrc` into its own MTLLibrary and parses the buffer-index
|
|
763
|
+
/// decorations, exactly like ShaderProcessor.ensureGenerative. Caches success
|
|
764
|
+
/// and failure so an unknown/broken layer shader degrades to a skipped layer
|
|
765
|
+
/// without recompiling per frame.
|
|
766
|
+
private func ensureGenerative(
|
|
767
|
+
name: String, renderer: MetalRenderer
|
|
768
|
+
) -> (fragment: MTLFunction, indices: [String: Int])? {
|
|
769
|
+
if let fragment = generativeFragments[name] {
|
|
770
|
+
return (fragment, generativeUniformIndices[name] ?? [:])
|
|
771
|
+
}
|
|
772
|
+
if generativeFailed.contains(name) { return nil }
|
|
773
|
+
do {
|
|
774
|
+
let library = try ShaderLibrary(
|
|
775
|
+
device: renderer.device, bundle: Bundle(for: CompositeProcessor.self), fileName: name
|
|
776
|
+
)
|
|
777
|
+
let fragment = try library.function()
|
|
778
|
+
let indices = library.uniformBufferIndices()
|
|
779
|
+
generativeFragments[name] = fragment
|
|
780
|
+
generativeUniformIndices[name] = indices
|
|
781
|
+
os_log("composite generative layer %{public}@ compiled; uniform indices: %{public}@",
|
|
782
|
+
log: CompositeProcessor.log, type: .info, name, String(describing: indices))
|
|
783
|
+
return (fragment, indices)
|
|
784
|
+
} catch {
|
|
785
|
+
generativeFailed.insert(name)
|
|
786
|
+
os_log("composite generative layer %{public}@ build failed: %{public}@",
|
|
787
|
+
log: CompositeProcessor.log, type: .error, name, error.localizedDescription)
|
|
788
|
+
return nil
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// MARK: - Uniform bindings (mirror ShaderProcessor)
|
|
793
|
+
|
|
794
|
+
private func makeBuiltinBindings(
|
|
795
|
+
indices: [String: Int], elapsed: Float, width: Int, height: Int
|
|
796
|
+
) -> [(index: Int, value: [Float])] {
|
|
797
|
+
var bindings = [(index: Int, value: [Float])]()
|
|
798
|
+
if let i = indices["uTime"] { bindings.append((index: i, value: [elapsed])) }
|
|
799
|
+
if let i = indices["uResolution"] {
|
|
800
|
+
bindings.append((index: i, value: [Float(width), Float(height)]))
|
|
801
|
+
}
|
|
802
|
+
return bindings
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/// Bind each JS-set layer uniform by name -> buffer index. float3 is PADDED to
|
|
806
|
+
/// 16 bytes (a Metal `constant float3&` argument occupies 16 bytes); see the
|
|
807
|
+
/// detailed rationale on ShaderProcessor.makeUniformBindings.
|
|
808
|
+
private func makeUniformBindings(
|
|
809
|
+
indices: [String: Int], layer: CompositeLayer
|
|
810
|
+
) -> [(index: Int, value: [Float])] {
|
|
811
|
+
var bindings = [(index: Int, value: [Float])]()
|
|
812
|
+
for (name, values) in layer.uniforms {
|
|
813
|
+
if CompositeProcessor.builtinNames.contains(name) { continue }
|
|
814
|
+
guard let index = indices[name] else { continue }
|
|
815
|
+
switch values.count {
|
|
816
|
+
case 1, 2, 4:
|
|
817
|
+
bindings.append((index: index, value: values))
|
|
818
|
+
case 3:
|
|
819
|
+
bindings.append((index: index, value: [values[0], values[1], values[2], 0]))
|
|
820
|
+
default:
|
|
821
|
+
os_log("composite layer %{public}@ uniform %{public}@ has unsupported length %d; skipping",
|
|
822
|
+
log: CompositeProcessor.log, type: .info, layer.shader, name, values.count)
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return bindings
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// MARK: - Image loading
|
|
829
|
+
|
|
830
|
+
/// Resolve a composite image `<id>.webp`. The iOS prebuild copies composite images into
|
|
831
|
+
/// the app target's resources under images/<id>.webp (see app.plugin.js's
|
|
832
|
+
/// copyIosImages), so it lands in Bundle.main; fall back to the
|
|
833
|
+
/// Kaleidoscope resource bundle's images/ for a test/static layout.
|
|
834
|
+
/// Mirrors BackgroundImageProcessor.bundledURL but in the images subdir.
|
|
835
|
+
static func imageURL(for id: String) -> URL? {
|
|
836
|
+
let containing = Bundle(for: CompositeProcessor.self)
|
|
837
|
+
let resourceBundle = Bundle.kaleidoscopeResources(relativeTo: containing) ?? containing
|
|
838
|
+
return Bundle.main.url(forResource: id, withExtension: "webp", subdirectory: imagesSubdir)
|
|
839
|
+
?? Bundle.main.url(forResource: id, withExtension: "webp")
|
|
840
|
+
?? resourceBundle.url(forResource: id, withExtension: "webp", subdirectory: imagesSubdir)
|
|
841
|
+
?? resourceBundle.url(forResource: id, withExtension: "webp")
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/// Lazy-load the image WebP as a Metal texture via MTKTextureLoader (decoded by
|
|
845
|
+
/// ImageIO, which supports WebP on iOS 14+; the podspec floors iOS 15). Cached
|
|
846
|
+
/// per id; a failed load is remembered. The texture loads top-left origin like
|
|
847
|
+
/// BackgroundImageProcessor's background; the V-flip parity is folded into the
|
|
848
|
+
/// cover-scale at draw time (see coverScale).
|
|
849
|
+
private func ensureImageTexture(id: String, device: MTLDevice) -> ImageTexture? {
|
|
850
|
+
if let image = imageTextures[id] { return image }
|
|
851
|
+
if missingImages.contains(id) { return nil }
|
|
852
|
+
guard let url = CompositeProcessor.imageURL(for: id) else {
|
|
853
|
+
os_log("composite image %{public}@.webp not found in app bundle or Kaleidoscope.bundle",
|
|
854
|
+
log: CompositeProcessor.log, type: .error, id)
|
|
855
|
+
missingImages.insert(id)
|
|
856
|
+
return nil
|
|
857
|
+
}
|
|
858
|
+
let loader = MTKTextureLoader(device: device)
|
|
859
|
+
let options: [MTKTextureLoader.Option: Any] = [
|
|
860
|
+
.origin: MTKTextureLoader.Origin.topLeft,
|
|
861
|
+
.SRGB: false,
|
|
862
|
+
.textureUsage: NSNumber(value: MTLTextureUsage.shaderRead.rawValue),
|
|
863
|
+
.textureStorageMode: NSNumber(value: MTLStorageMode.private.rawValue)
|
|
864
|
+
]
|
|
865
|
+
do {
|
|
866
|
+
let texture = try loader.newTexture(URL: url, options: options)
|
|
867
|
+
let aspect = Float(texture.width) / Float(max(texture.height, 1))
|
|
868
|
+
let image = ImageTexture(texture: texture, aspect: aspect)
|
|
869
|
+
imageTextures[id] = image
|
|
870
|
+
os_log("composite image %{public}@ loaded: %dx%d aspect=%.3f",
|
|
871
|
+
log: CompositeProcessor.log, type: .info, id, texture.width, texture.height, aspect)
|
|
872
|
+
return image
|
|
873
|
+
} catch {
|
|
874
|
+
missingImages.insert(id)
|
|
875
|
+
os_log("composite image %{public}@ load failed: %{public}@",
|
|
876
|
+
log: CompositeProcessor.log, type: .error, id, error.localizedDescription)
|
|
877
|
+
return nil
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/// Center-crop cover-fit UV scale (mirrors coverScale in composite.ts / CompositeFactory),
|
|
882
|
+
/// with the V axis NEGATED to fold in the MTKTextureLoader V-flip parity. The
|
|
883
|
+
/// composite-image fragment computes uv = (vUv - 0.5) * coverScale + 0.5; a negative
|
|
884
|
+
/// y reflects about the crop window's center, so the image lands semantic-top at
|
|
885
|
+
/// vUv.y=1, matching the CoreImage-rendered camera "original" (which composites
|
|
886
|
+
/// correct on-device). This is the same texture-origin parity fix
|
|
887
|
+
/// BackgroundImageProcessor applies on uBgUvScale.y; here the cover-scale IS the
|
|
888
|
+
/// sampling scale (the fragment centers it about 0.5), so a single -y suffices
|
|
889
|
+
/// and stays centered for both letterbox branches. Camera orientation is handled
|
|
890
|
+
/// at ingest and is independent of this term. RISK: parity is reasoned, not
|
|
891
|
+
/// device-verified on iOS; if a image renders vertically inverted, this -sy is
|
|
892
|
+
/// the single term to flip back to +sy.
|
|
893
|
+
private func coverScale(outW: Int, outH: Int, imgAspect: Float) -> SIMD2<Float> {
|
|
894
|
+
let outAspect = Float(outW) / Float(outH)
|
|
895
|
+
let sx: Float
|
|
896
|
+
let sy: Float
|
|
897
|
+
if outAspect > imgAspect {
|
|
898
|
+
sx = 1
|
|
899
|
+
sy = imgAspect / outAspect
|
|
900
|
+
} else {
|
|
901
|
+
sx = outAspect / imgAspect
|
|
902
|
+
sy = 1
|
|
903
|
+
}
|
|
904
|
+
return SIMD2<Float>(sx, -sy)
|
|
905
|
+
}
|
|
906
|
+
}
|