@bvdmitri/gyroview 0.0.0-stage → 0.9.0-cutaway.2
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/CHANGELOG.md +402 -0
- package/LICENSE +21 -0
- package/README.md +313 -2
- package/dist/define.d.ts +3 -0
- package/dist/define.js +4 -0
- package/dist/index.d.ts +1204 -0
- package/dist/index.js +12 -0
- package/dist/packages/adapters/blob/src/BlobRandomAccessSource.js +36 -0
- package/dist/packages/adapters/fetch/src/HttpByteStream.js +173 -0
- package/dist/packages/adapters/fetch/src/HttpRangeSource.js +37 -0
- package/dist/packages/adapters/fetch/src/HttpResource.js +227 -0
- package/dist/packages/adapters/fetch/src/HttpResourceLocator.js +35 -0
- package/dist/packages/adapters/fetch/src/contentRange.js +15 -0
- package/dist/packages/adapters/fetch/src/httpRequest.js +136 -0
- package/dist/packages/adapters/fetch/src/passingFailures.js +23 -0
- package/dist/packages/adapters/fetch/src/rangeFailures.js +16 -0
- package/dist/packages/adapters/fetch/src/recordingVersion.js +37 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyAudioPackager.js +162 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyCodecReader.js +93 -0
- package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +135 -0
- package/dist/packages/adapters/mediabunny/src/bufferSources.js +12 -0
- package/dist/packages/adapters/mediabunny/src/decoderConfigurations.js +43 -0
- package/dist/packages/adapters/mediabunny/src/trackColour.js +20 -0
- package/dist/packages/adapters/mse-audio/src/MediaSourceAudioClock.js +138 -0
- package/dist/packages/adapters/mse-audio/src/SourceBufferFeeder.js +263 -0
- package/dist/packages/adapters/mse-audio/src/events.js +26 -0
- package/dist/packages/adapters/mse-audio/src/mediaSourceSupport.js +81 -0
- package/dist/packages/adapters/three/src/ThreeFrameRenderer.js +215 -0
- package/dist/packages/adapters/three/src/compileAndProve.js +14 -0
- package/dist/packages/adapters/three/src/conversionUniforms.js +60 -0
- package/dist/packages/adapters/three/src/drawSchedules.js +13 -0
- package/dist/packages/adapters/three/src/fullscreenPass.js +52 -0
- package/dist/packages/adapters/three/src/glslLiterals.js +10 -0
- package/dist/packages/adapters/three/src/lensTextures.js +34 -0
- package/dist/packages/adapters/three/src/matrixCorrections.js +34 -0
- package/dist/packages/adapters/three/src/pictureMaterials.js +44 -0
- package/dist/packages/adapters/three/src/renderInto.js +15 -0
- package/dist/packages/adapters/three/src/rendererParts.js +108 -0
- package/dist/packages/adapters/three/src/rendererUniforms.js +176 -0
- package/dist/packages/adapters/three/src/samplingStrategies.js +26 -0
- package/dist/packages/adapters/three/src/scissorBox.js +20 -0
- package/dist/packages/adapters/three/src/seamMeter/SeamMeterPass.js +85 -0
- package/dist/packages/adapters/three/src/seamMeter/rowMeans.js +42 -0
- package/dist/packages/adapters/three/src/shaderPrograms.js +68 -0
- package/dist/packages/adapters/three/src/shaders/analysis.frag.js +4 -0
- package/dist/packages/adapters/three/src/shaders/displayConversion.js +4 -0
- package/dist/packages/adapters/three/src/shaders/equirectangularRays.js +4 -0
- package/dist/packages/adapters/three/src/shaders/fixedJoin.js +4 -0
- package/dist/packages/adapters/three/src/shaders/fullscreen.vert.js +4 -0
- package/dist/packages/adapters/three/src/shaders/header.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensModels.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensSampling.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensTextures.js +4 -0
- package/dist/packages/adapters/three/src/shaders/rawLenses.frag.js +4 -0
- package/dist/packages/adapters/three/src/shaders/rectilinearRays.js +4 -0
- package/dist/packages/adapters/three/src/shaders/screenAreas.js +4 -0
- package/dist/packages/adapters/three/src/shaders/stitch.frag.js +4 -0
- package/dist/packages/adapters/three/src/threeMatrix.js +10 -0
- package/dist/packages/adapters/three/src/webglRenderer.js +37 -0
- package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +152 -0
- package/dist/packages/adapters/webcodecs/src/colorSpaceOf.js +32 -0
- package/dist/packages/core/src/application/download/BlockStore.js +97 -0
- package/dist/packages/core/src/application/download/DownloadedAudioSamples.js +50 -0
- package/dist/packages/core/src/application/download/DownloadedVideoTrack.js +122 -0
- package/dist/packages/core/src/application/download/FileDownload.js +208 -0
- package/dist/packages/core/src/application/download/RecordingBuffer.js +22 -0
- package/dist/packages/core/src/application/download/SampleCursor.js +89 -0
- package/dist/packages/core/src/application/download/SourceByteStream.js +46 -0
- package/dist/packages/core/src/application/download/Transfers.js +82 -0
- package/dist/packages/core/src/application/download/startFileDownload.js +37 -0
- package/dist/packages/core/src/application/gainMatching/GainMatching.js +76 -0
- package/dist/packages/core/src/application/gainMatching/GainMatchingFrameSink.js +80 -0
- package/dist/packages/core/src/application/gainMatching/referenceLensOf.js +18 -0
- package/dist/packages/core/src/application/playback/Buffering.js +54 -0
- package/dist/packages/core/src/application/playback/ClockStart.js +55 -0
- package/dist/packages/core/src/application/playback/ClockWatch.js +76 -0
- package/dist/packages/core/src/application/playback/DecodePipeline.js +234 -0
- package/dist/packages/core/src/application/playback/DecodeRun.js +108 -0
- package/dist/packages/core/src/application/playback/FramePairQueue.js +93 -0
- package/dist/packages/core/src/application/playback/FramePairer.js +77 -0
- package/dist/packages/core/src/application/playback/PictureOnScreen.js +56 -0
- package/dist/packages/core/src/application/playback/PlaybackSession.js +410 -0
- package/dist/packages/core/src/application/playback/SeekOrder.js +35 -0
- package/dist/packages/core/src/application/playback/SessionLifecycle.js +42 -0
- package/dist/packages/core/src/application/playback/StartGate.js +69 -0
- package/dist/packages/core/src/application/playback/TimeUpdates.js +31 -0
- package/dist/packages/core/src/application/playback/WallClock.js +46 -0
- package/dist/packages/core/src/application/playback/keyframeTimeAt.js +15 -0
- package/dist/packages/core/src/application/playback/probeDecoding.js +182 -0
- package/dist/packages/core/src/application/recording/frameTimesOf.js +21 -0
- package/dist/packages/core/src/application/recording/inspectLayout.js +21 -0
- package/dist/packages/core/src/application/recording/inspectRecording.js +125 -0
- package/dist/packages/core/src/application/recording/locateOtherLensFile.js +18 -0
- package/dist/packages/core/src/application/recording/motionOf.js +43 -0
- package/dist/packages/core/src/application/recording/readRecording.js +31 -0
- package/dist/packages/core/src/application/recording/readRecordingFiles.js +130 -0
- package/dist/packages/core/src/application/recording/readSampleTable.js +27 -0
- package/dist/packages/core/src/application/recording/timeRecording.js +57 -0
- package/dist/packages/core/src/application/stabilization/StabilizingFrameSink.js +33 -0
- package/dist/packages/core/src/domain/colour/DisplayConversion.js +137 -0
- package/dist/packages/core/src/domain/colour/TrackColour.js +38 -0
- package/dist/packages/core/src/domain/colour/gainMatch.js +64 -0
- package/dist/packages/core/src/domain/colour/matrixCorrection.js +76 -0
- package/dist/packages/core/src/domain/container/KeyframeRule.js +7 -0
- package/dist/packages/core/src/domain/container/SampleTable.js +29 -0
- package/dist/packages/core/src/domain/container/TrackSampleTable.js +96 -0
- package/dist/packages/core/src/domain/container/presentationOrder.js +10 -0
- package/dist/packages/core/src/domain/download/DownloadPolicy.js +84 -0
- package/dist/packages/core/src/domain/download/isReadyToResume.js +27 -0
- package/dist/packages/core/src/domain/download/planDownloads.js +175 -0
- package/dist/packages/core/src/domain/download/trackNeeds.js +32 -0
- package/dist/packages/core/src/domain/format/boxes/BoxLayout.js +7 -0
- package/dist/packages/core/src/domain/format/boxes/boxConstants.js +16 -0
- package/dist/packages/core/src/domain/format/boxes/boxHeader.js +44 -0
- package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +32 -0
- package/dist/packages/core/src/domain/format/calibration/CalibrationVersion.js +16 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/CalibrationStringLayout.js +34 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/LegacyCalibrationLayout.js +46 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/MeiCalibrationLayout.js +121 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/PolynomialCalibrationLayout.js +46 -0
- package/dist/packages/core/src/domain/format/calibration/offsetTokens.js +94 -0
- package/dist/packages/core/src/domain/format/calibration/parseOffsetString.js +77 -0
- package/dist/packages/core/src/domain/format/calibration/selectCalibration.js +59 -0
- package/dist/packages/core/src/domain/format/calibration/v6TermReading.js +20 -0
- package/dist/packages/core/src/domain/format/captureOrigin.js +34 -0
- package/dist/packages/core/src/domain/format/constants.js +35 -0
- package/dist/packages/core/src/domain/format/info/calibrationSources.js +27 -0
- package/dist/packages/core/src/domain/format/info/infoFields.js +116 -0
- package/dist/packages/core/src/domain/format/info/parseInfoRecord.js +107 -0
- package/dist/packages/core/src/domain/format/info/readInfoRecord.js +14 -0
- package/dist/packages/core/src/domain/format/layout/detectLensLayout.js +133 -0
- package/dist/packages/core/src/domain/format/mp4/hevcCodecString.js +161 -0
- package/dist/packages/core/src/domain/format/mp4/keyframeRules.js +81 -0
- package/dist/packages/core/src/domain/format/mp4/movieBoxes.js +52 -0
- package/dist/packages/core/src/domain/format/mp4/mp4BoxTypes.js +46 -0
- package/dist/packages/core/src/domain/format/mp4/mp4Layouts.js +183 -0
- package/dist/packages/core/src/domain/format/mp4/parseMovie.js +72 -0
- package/dist/packages/core/src/domain/format/mp4/readTable.js +31 -0
- package/dist/packages/core/src/domain/format/mp4/sampleLocations.js +76 -0
- package/dist/packages/core/src/domain/format/mp4/sampleTiming.js +120 -0
- package/dist/packages/core/src/domain/format/mp4/trackHeaders.js +88 -0
- package/dist/packages/core/src/domain/format/naming/RecordingFileName.js +70 -0
- package/dist/packages/core/src/domain/format/records/TrailerRecords.js +100 -0
- package/dist/packages/core/src/domain/format/records/exposure/parseExposureRecord.js +48 -0
- package/dist/packages/core/src/domain/format/records/gyro/FloatGyroSampleLayout.js +38 -0
- package/dist/packages/core/src/domain/format/records/gyro/RawGyroSampleLayout.js +55 -0
- package/dist/packages/core/src/domain/format/records/gyro/SampleColumns.js +89 -0
- package/dist/packages/core/src/domain/format/records/gyro/gyroLayouts.js +12 -0
- package/dist/packages/core/src/domain/format/records/gyro/parseGyroRecord.js +138 -0
- package/dist/packages/core/src/domain/format/records/trim/parseTrimRecord.js +24 -0
- package/dist/packages/core/src/domain/format/trailer/RecordHeader.js +23 -0
- package/dist/packages/core/src/domain/format/trailer/Trailer.js +23 -0
- package/dist/packages/core/src/domain/format/trailer/TrailerFooter.js +27 -0
- package/dist/packages/core/src/domain/format/trailer/locateRecords.js +80 -0
- package/dist/packages/core/src/domain/format/trailer/parseRecordIndex.js +28 -0
- package/dist/packages/core/src/domain/format/trailer/readTrailer.js +60 -0
- package/dist/packages/core/src/domain/motion/exposure/ExposureRecord.js +48 -0
- package/dist/packages/core/src/domain/motion/gyro/GyroTrack.js +70 -0
- package/dist/packages/core/src/domain/motion/gyro/medianStep.js +11 -0
- package/dist/packages/core/src/domain/motion/gyro/repairedTimeline.js +101 -0
- package/dist/packages/core/src/domain/motion/imu/ImuFrame.js +178 -0
- package/dist/packages/core/src/domain/motion/mounting/Mounting.js +131 -0
- package/dist/packages/core/src/domain/motion/orientation/OrientationTrack.js +142 -0
- package/dist/packages/core/src/domain/motion/orientation/estimateGyroBias.js +72 -0
- package/dist/packages/core/src/domain/motion/orientation/gravity.js +97 -0
- package/dist/packages/core/src/domain/motion/stabilization/Stabilizer.js +13 -0
- package/dist/packages/core/src/domain/motion/stabilization/stabilizers.js +86 -0
- package/dist/packages/core/src/domain/motion/timing/CaptureClock.js +41 -0
- package/dist/packages/core/src/domain/motion/timing/FrameTimes.js +85 -0
- package/dist/packages/core/src/domain/motion/timing/frameTimeSources.js +58 -0
- package/dist/packages/core/src/domain/motion/timing/resolveFrameTimes.js +68 -0
- package/dist/packages/core/src/domain/optics/EquidistantModel.js +34 -0
- package/dist/packages/core/src/domain/optics/MeiDistortion.js +27 -0
- package/dist/packages/core/src/domain/optics/MeiModel.js +27 -0
- package/dist/packages/core/src/domain/optics/PolynomialModel.js +39 -0
- package/dist/packages/core/src/domain/optics/lensPose.js +49 -0
- package/dist/packages/core/src/domain/optics/opticsConstants.js +5 -0
- package/dist/packages/core/src/domain/optics/scaledProjection.js +30 -0
- package/dist/packages/core/src/domain/playback/PlayerState.js +83 -0
- package/dist/packages/core/src/domain/rendition/RenditionSpan.js +70 -0
- package/dist/packages/core/src/domain/stitching/LensLayout.js +21 -0
- package/dist/packages/core/src/domain/stitching/StitchingSetup.js +87 -0
- package/dist/packages/core/src/domain/stitching/seamRing.js +4 -0
- package/dist/packages/core/src/domain/view/Framing.js +37 -0
- package/dist/packages/core/src/domain/view/Picture.js +12 -0
- package/dist/packages/core/src/domain/view/PictureQuality.js +26 -0
- package/dist/packages/core/src/domain/view/ViewMode.js +9 -0
- package/dist/packages/core/src/domain/view/ViewState.js +54 -0
- package/dist/packages/core/src/domain/view/lensTilesView.js +64 -0
- package/dist/packages/core/src/domain/view/magnification.js +103 -0
- package/dist/packages/core/src/domain/view/motionLookView.js +100 -0
- package/dist/packages/core/src/domain/view/normalView.js +37 -0
- package/dist/packages/core/src/domain/view/panoramaView.js +95 -0
- package/dist/packages/core/src/domain/view/rectilinear.js +53 -0
- package/dist/packages/core/src/domain/view/screenLayout.js +129 -0
- package/dist/packages/core/src/domain/view/screenLook.js +74 -0
- package/dist/packages/core/src/domain/view/viewGestures.js +104 -0
- package/dist/packages/core/src/domain/view/viewModes.js +31 -0
- package/dist/packages/core/src/ports/FramePair.js +6 -0
- package/dist/packages/core/src/shared/async/Deferred.js +42 -0
- package/dist/packages/core/src/shared/async/RunStop.js +40 -0
- package/dist/packages/core/src/shared/async/iteration.js +24 -0
- package/dist/packages/core/src/shared/binary/ByteRange.js +50 -0
- package/dist/packages/core/src/shared/binary/ByteRangeSet.js +85 -0
- package/dist/packages/core/src/shared/binary/ByteReader.js +104 -0
- package/dist/packages/core/src/shared/binary/concatenated.js +15 -0
- package/dist/packages/core/src/shared/errors/GyroViewError.js +140 -0
- package/dist/packages/core/src/shared/errors/reportLater.js +11 -0
- package/dist/packages/core/src/shared/events/Outbox.js +68 -0
- package/dist/packages/core/src/shared/events/TypedEmitter.js +55 -0
- package/dist/packages/core/src/shared/keysOf.js +10 -0
- package/dist/packages/core/src/shared/lazy.js +11 -0
- package/dist/packages/core/src/shared/mapRecord.js +11 -0
- package/dist/packages/core/src/shared/math/Matrix3.js +121 -0
- package/dist/packages/core/src/shared/math/Quaternion.js +133 -0
- package/dist/packages/core/src/shared/math/Vector3.js +58 -0
- package/dist/packages/core/src/shared/math/clamp.js +9 -0
- package/dist/packages/core/src/shared/math/countAtOrBelow.js +31 -0
- package/dist/packages/core/src/shared/math/minimum.js +17 -0
- package/dist/packages/core/src/shared/protobuf/ProtobufMessage.js +143 -0
- package/dist/packages/core/src/shared/protobuf/wireFormat.js +16 -0
- package/dist/packages/core/src/shared/text/urlPath.js +31 -0
- package/dist/packages/core/src/shared/text/utf8.js +12 -0
- package/dist/packages/core/src/shared/units/angle.js +22 -0
- package/dist/packages/core/src/shared/units/time.js +13 -0
- package/dist/packages/player/src/PlayerSource.js +14 -0
- package/dist/packages/player/src/browserPlayer.js +20 -0
- package/dist/packages/player/src/choices.js +24 -0
- package/dist/packages/player/src/composition/AnimationFrameDraws.js +38 -0
- package/dist/packages/player/src/composition/BrowserAttitudeSensor.js +191 -0
- package/dist/packages/player/src/composition/Disposables.js +31 -0
- package/dist/packages/player/src/composition/DrawingBufferFit.js +119 -0
- package/dist/packages/player/src/composition/animationFrames.js +9 -0
- package/dist/packages/player/src/composition/attitudeSensor.js +18 -0
- package/dist/packages/player/src/composition/browserPorts.js +80 -0
- package/dist/packages/player/src/composition/buildPipeline.js +186 -0
- package/dist/packages/player/src/composition/ensureDecodable.js +62 -0
- package/dist/packages/player/src/composition/openInputs.js +120 -0
- package/dist/packages/player/src/composition/openRecording.js +41 -0
- package/dist/packages/player/src/composition/readInputs.js +25 -0
- package/dist/packages/player/src/composition/renditionFrames.js +160 -0
- package/dist/packages/player/src/controls/ChoiceMenu.js +125 -0
- package/dist/packages/player/src/controls/FullscreenButton.js +29 -0
- package/dist/packages/player/src/controls/MotionLookButton.js +34 -0
- package/dist/packages/player/src/controls/PictureMenus.js +60 -0
- package/dist/packages/player/src/controls/SeekBar.js +126 -0
- package/dist/packages/player/src/controls/SoundControls.js +43 -0
- package/dist/packages/player/src/controls/TransportButtons.js +28 -0
- package/dist/packages/player/src/controls/ViewGestures.js +135 -0
- package/dist/packages/player/src/controls/Wording.js +79 -0
- package/dist/packages/player/src/controls/controlParts.js +38 -0
- package/dist/packages/player/src/controls/controls.js +4 -0
- package/dist/packages/player/src/controls/controlsBar.js +33 -0
- package/dist/packages/player/src/controls/controlsMarkup.js +100 -0
- package/dist/packages/player/src/controls/customControls.js +43 -0
- package/dist/packages/player/src/controls/formatTime.js +19 -0
- package/dist/packages/player/src/controls/icons.js +66 -0
- package/dist/packages/player/src/controls/keyboard.js +120 -0
- package/dist/packages/player/src/controls/messages.js +130 -0
- package/dist/packages/player/src/controls/nativeFullscreen.js +27 -0
- package/dist/packages/player/src/controls/parseMarkup.js +30 -0
- package/dist/packages/player/src/controls/resetViewButton.js +11 -0
- package/dist/packages/player/src/controls/sliderFill.js +15 -0
- package/dist/packages/player/src/element/ElementLoads.js +130 -0
- package/dist/packages/player/src/element/FullscreenToggle.js +93 -0
- package/dist/packages/player/src/element/GyroViewElement.js +358 -0
- package/dist/packages/player/src/element/IdleWatcher.js +71 -0
- package/dist/packages/player/src/element/PlayerCanvas.js +72 -0
- package/dist/packages/player/src/element/TypedEventElement.js +22 -0
- package/dist/packages/player/src/element/accessibleRegion.js +19 -0
- package/dist/packages/player/src/element/attributeNames.js +62 -0
- package/dist/packages/player/src/element/attributes.js +123 -0
- package/dist/packages/player/src/element/defineGyroView.js +20 -0
- package/dist/packages/player/src/element/earlyProperties.js +35 -0
- package/dist/packages/player/src/element/elementProperties.js +34 -0
- package/dist/packages/player/src/element/elementSource.js +39 -0
- package/dist/packages/player/src/element/fetchProperty.js +48 -0
- package/dist/packages/player/src/element/liveSettings.js +137 -0
- package/dist/packages/player/src/element/playbackAttributes.js +52 -0
- package/dist/packages/player/src/element/playerEventMirror.js +33 -0
- package/dist/packages/player/src/element/reflectedProperties.js +96 -0
- package/dist/packages/player/src/element/styles.js +4 -0
- package/dist/packages/player/src/element/template.js +46 -0
- package/dist/packages/player/src/inspectRecording.js +21 -0
- package/dist/packages/player/src/player/FrameLoop.js +35 -0
- package/dist/packages/player/src/player/MotionLook.js +150 -0
- package/dist/packages/player/src/player/PictureSettings.js +59 -0
- package/dist/packages/player/src/player/PlaybackStarts.js +38 -0
- package/dist/packages/player/src/player/Player.js +379 -0
- package/dist/packages/player/src/player/PlayerEvents.js +28 -0
- package/dist/packages/player/src/player/PlayerPhase.js +38 -0
- package/dist/packages/player/src/player/PlayerSound.js +60 -0
- package/dist/packages/player/src/player/PlayerView.js +143 -0
- package/dist/packages/player/src/player/SessionRelay.js +74 -0
- package/dist/packages/player/src/player/StatusAnnouncer.js +29 -0
- package/dist/packages/player/src/player/ensureFinite.js +26 -0
- package/dist/packages/player/src/player/loadRecording.js +47 -0
- package/dist/packages/player/src/player/transportEvents.js +30 -0
- package/dist/packages/player/src/player/viewAngles.js +17 -0
- package/dist/packages/player/src/rendition.js +52 -0
- package/dist/standalone.js +5633 -0
- package/package.json +70 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SHADER_DEFINES } from "./rendererUniforms.js";
|
|
2
|
+
import fullscreen_vert_default from "./shaders/fullscreen.vert.js";
|
|
3
|
+
import { BufferGeometry, Float32BufferAttribute, GLSL3, RawShaderMaterial } from "three";
|
|
4
|
+
//#region ../../packages/adapters/three/src/fullscreenPass.ts
|
|
5
|
+
/**
|
|
6
|
+
* One triangle covering the clip square: two corners lie beyond it so its hypotenuse clears the
|
|
7
|
+
* far edge. The fragment shader decides every pixel.
|
|
8
|
+
*/
|
|
9
|
+
var BEYOND_CLIP = 3;
|
|
10
|
+
var FULLSCREEN_TRIANGLE = [
|
|
11
|
+
-1,
|
|
12
|
+
-1,
|
|
13
|
+
0,
|
|
14
|
+
BEYOND_CLIP,
|
|
15
|
+
-1,
|
|
16
|
+
0,
|
|
17
|
+
-1,
|
|
18
|
+
BEYOND_CLIP,
|
|
19
|
+
0
|
|
20
|
+
];
|
|
21
|
+
var POSITION_COMPONENTS = 3;
|
|
22
|
+
function createFullscreenTriangle() {
|
|
23
|
+
const geometry = new BufferGeometry();
|
|
24
|
+
geometry.setAttribute("position", new Float32BufferAttribute(FULLSCREEN_TRIANGLE, POSITION_COMPONENTS));
|
|
25
|
+
return geometry;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The program of a pass whose chunks refer only to the constants of `rendererUniforms`.
|
|
29
|
+
*/
|
|
30
|
+
function programOf(chunks) {
|
|
31
|
+
return {
|
|
32
|
+
chunks,
|
|
33
|
+
defines: SHADER_DEFINES
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A fullscreen pass over the shared uniforms. The raw shaders ignore the camera three still
|
|
38
|
+
* wants to render with; each pass keeps its own.
|
|
39
|
+
*/
|
|
40
|
+
function createPassMaterial(uniforms, program) {
|
|
41
|
+
return new RawShaderMaterial({
|
|
42
|
+
glslVersion: GLSL3,
|
|
43
|
+
defines: { ...program.defines },
|
|
44
|
+
vertexShader: fullscreen_vert_default,
|
|
45
|
+
fragmentShader: program.chunks.join("\n"),
|
|
46
|
+
uniforms: { ...uniforms },
|
|
47
|
+
depthTest: false,
|
|
48
|
+
depthWrite: false
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { createFullscreenTriangle, createPassMaterial, programOf };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region ../../packages/adapters/three/src/glslLiterals.ts
|
|
2
|
+
/**
|
|
3
|
+
* A number as a GLSL float literal, with its decimal point: three.js writes a define's number as
|
|
4
|
+
* JavaScript prints it, so 3 would be an int, and GLSL ES 3.00 converts no int to a float.
|
|
5
|
+
*/
|
|
6
|
+
function glslFloat(value) {
|
|
7
|
+
return Number.isSafeInteger(value) ? value.toFixed(1) : String(value);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { glslFloat };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { GyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
|
|
2
|
+
import { LinearFilter, NoColorSpace, VideoFrameTexture } from "three";
|
|
3
|
+
//#region ../../packages/adapters/three/src/lensTextures.ts
|
|
4
|
+
/**
|
|
5
|
+
* The textures the decoded frames are uploaded to, one per frame of a pair, read with the
|
|
6
|
+
* given strategy. Three uploads a video frame with `texImage2D` and builds the mip chain after
|
|
7
|
+
* it when asked; the anisotropy applies where the driver offers it and the filter uses the
|
|
8
|
+
* chain.
|
|
9
|
+
*/
|
|
10
|
+
function createLensTextures(count, strategy) {
|
|
11
|
+
return Array.from({ length: count }, () => {
|
|
12
|
+
const texture = new VideoFrameTexture();
|
|
13
|
+
texture.flipY = false;
|
|
14
|
+
texture.colorSpace = NoColorSpace;
|
|
15
|
+
texture.magFilter = LinearFilter;
|
|
16
|
+
applyTextureFilters(texture, strategy);
|
|
17
|
+
return texture;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function applyTextureFilters(texture, strategy) {
|
|
21
|
+
texture.minFilter = strategy.minFilter;
|
|
22
|
+
texture.generateMipmaps = strategy.generateMipmaps;
|
|
23
|
+
texture.anisotropy = strategy.anisotropy;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Three would shrink a frame larger than the GPU's largest texture through a 2D canvas at every
|
|
27
|
+
* upload, slowly and blurred, saying nothing; such a frame is refused instead.
|
|
28
|
+
*/
|
|
29
|
+
function ensureUploadable(frame, maxTextureSize) {
|
|
30
|
+
if (Math.max(frame.displayWidth, frame.displayHeight) <= maxTextureSize) return;
|
|
31
|
+
throw new GyroViewError("render-unavailable", `this GPU holds textures of at most ${maxTextureSize} pixels a side; a decoded frame is ${frame.displayWidth} x ${frame.displayHeight}`);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { applyTextureFilters, createLensTextures, ensureUploadable };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { MATRIX_COEFFICIENTS, namedOrUnspecified } from "../../../core/src/domain/colour/TrackColour.js";
|
|
2
|
+
import { matrixCorrectionOf } from "../../../core/src/domain/colour/matrixCorrection.js";
|
|
3
|
+
import { toThreeMatrix } from "./threeMatrix.js";
|
|
4
|
+
//#region ../../packages/adapters/three/src/matrixCorrections.ts
|
|
5
|
+
/**
|
|
6
|
+
* Follows the matrix each lens's frames name, and brings their texels back to the matrix the
|
|
7
|
+
* track was recorded with where the two differ (ADR 0033): WebKit's decoders convert Y′CbCr with
|
|
8
|
+
* BT.709 whatever a stream says, and name BT.709 on the frames they make.
|
|
9
|
+
*/
|
|
10
|
+
var MatrixCorrections = class {
|
|
11
|
+
lenses;
|
|
12
|
+
uniform;
|
|
13
|
+
named;
|
|
14
|
+
constructor(lenses, uniform) {
|
|
15
|
+
this.lenses = lenses;
|
|
16
|
+
this.uniform = uniform;
|
|
17
|
+
this.named = Array.from({ length: lenses.length });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Updates a lens's correction when its frames name another matrix than before.
|
|
21
|
+
*/
|
|
22
|
+
follow(frames) {
|
|
23
|
+
for (const [index, lens] of this.lenses.entries()) {
|
|
24
|
+
const frame = frames[lens.frameSlot];
|
|
25
|
+
if (!frame) continue;
|
|
26
|
+
const named = namedOrUnspecified(MATRIX_COEFFICIENTS, frame.colorSpace.matrix);
|
|
27
|
+
if (named === this.named[index]) continue;
|
|
28
|
+
this.named[index] = named;
|
|
29
|
+
this.uniform.value[index] = toThreeMatrix(matrixCorrectionOf(lens.displayConversion.matrix, named));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { MatrixCorrections };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SHADER_DEFINES } from "./rendererUniforms.js";
|
|
2
|
+
import { createPassMaterial } from "./fullscreenPass.js";
|
|
3
|
+
import { compileAndProve } from "./compileAndProve.js";
|
|
4
|
+
import { PICTURE_PROGRAMS } from "./shaderPrograms.js";
|
|
5
|
+
import { Camera, Mesh, Scene } from "three";
|
|
6
|
+
//#region ../../packages/adapters/three/src/pictureMaterials.ts
|
|
7
|
+
/**
|
|
8
|
+
* The pictures the player draws: the stitch through the fixed seam join.
|
|
9
|
+
*/
|
|
10
|
+
var PLAYER_SHADERS = {
|
|
11
|
+
programs: PICTURE_PROGRAMS,
|
|
12
|
+
defines: SHADER_DEFINES
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The pictures' materials over the shared uniforms, and any the pictures' programs add.
|
|
16
|
+
*/
|
|
17
|
+
function createPictureMaterials(uniforms, shaders) {
|
|
18
|
+
const materialOf = (kind) => createPassMaterial(uniforms, {
|
|
19
|
+
chunks: shaders.programs[kind],
|
|
20
|
+
defines: shaders.defines
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
rectilinear: materialOf("rectilinear"),
|
|
24
|
+
equirectangular: materialOf("equirectangular"),
|
|
25
|
+
"lens-tiles": materialOf("lens-tiles")
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Compiles and proves every program now: a broken shader then fails here rather than at the first
|
|
30
|
+
* presented frame or the first change of view mode, and a change of mode is instant.
|
|
31
|
+
*/
|
|
32
|
+
function compilePictureMaterials(renderer, geometry, materials) {
|
|
33
|
+
const camera = new Camera();
|
|
34
|
+
for (const material of Object.values(materials)) {
|
|
35
|
+
const scene = new Scene();
|
|
36
|
+
scene.add(new Mesh(geometry, material));
|
|
37
|
+
compileAndProve(renderer, scene, camera);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function disposePictureMaterials(materials) {
|
|
41
|
+
for (const material of Object.values(materials)) material.dispose();
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { PLAYER_SHADERS, compilePictureMaterials, createPictureMaterials, disposePictureMaterials };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region ../../packages/adapters/three/src/renderInto.ts
|
|
2
|
+
/**
|
|
3
|
+
* Runs `draw` with `target` bound, the renderer's own target restored however the drawing ends.
|
|
4
|
+
*/
|
|
5
|
+
function renderInto(renderer, target, draw) {
|
|
6
|
+
const previous = renderer.getRenderTarget();
|
|
7
|
+
renderer.setRenderTarget(target);
|
|
8
|
+
try {
|
|
9
|
+
draw();
|
|
10
|
+
} finally {
|
|
11
|
+
renderer.setRenderTarget(previous);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { renderInto };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { GyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
|
|
2
|
+
import { DEFAULT_PICTURE_QUALITY } from "../../../core/src/domain/view/PictureQuality.js";
|
|
3
|
+
import { createLensTextures } from "./lensTextures.js";
|
|
4
|
+
import { DRAW_AT_ONCE } from "./drawSchedules.js";
|
|
5
|
+
import { SAMPLING_STRATEGIES } from "./samplingStrategies.js";
|
|
6
|
+
import { applyShaderSampling, createRendererUniforms } from "./rendererUniforms.js";
|
|
7
|
+
import { createFullscreenTriangle } from "./fullscreenPass.js";
|
|
8
|
+
import { MatrixCorrections } from "./matrixCorrections.js";
|
|
9
|
+
import { PLAYER_SHADERS, compilePictureMaterials, createPictureMaterials, disposePictureMaterials } from "./pictureMaterials.js";
|
|
10
|
+
import { SeamMeterPass } from "./seamMeter/SeamMeterPass.js";
|
|
11
|
+
import { createRenderer } from "./webglRenderer.js";
|
|
12
|
+
import { Camera, Mesh, Scene } from "three";
|
|
13
|
+
//#region ../../packages/adapters/three/src/rendererParts.ts
|
|
14
|
+
var PLAYER_PICTURES = {
|
|
15
|
+
shaders: PLAYER_SHADERS,
|
|
16
|
+
uniforms: {}
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The parts a renderer was built of, disposed of together, the last built first: on the renderer's
|
|
20
|
+
* disposal, and at once when a later part fails to build (a shader the GPU refuses), so a failed
|
|
21
|
+
* opening leaves nothing behind.
|
|
22
|
+
*/
|
|
23
|
+
var BuiltParts = class BuiltParts {
|
|
24
|
+
parts = [];
|
|
25
|
+
static disposedOnFailure(build) {
|
|
26
|
+
const built = new BuiltParts();
|
|
27
|
+
try {
|
|
28
|
+
return build(built);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
built.dispose();
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
keep(part) {
|
|
35
|
+
this.parts.push(part);
|
|
36
|
+
return part;
|
|
37
|
+
}
|
|
38
|
+
dispose() {
|
|
39
|
+
for (let part = this.parts.pop(); part; part = this.parts.pop()) part.dispose();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The context, textures, uniforms and compiled programs of a renderer that draws with the given
|
|
44
|
+
* pictures. Every program is compiled and proven here, so a broken shader fails at creation
|
|
45
|
+
* rather than at the first frame, and a change of view mode is instant.
|
|
46
|
+
*/
|
|
47
|
+
function openRendererParts(canvas, setup, opening) {
|
|
48
|
+
ensureDrawable(setup);
|
|
49
|
+
return BuiltParts.disposedOnFailure((built) => {
|
|
50
|
+
const renderer = built.keep(createRenderer(canvas, opening.options));
|
|
51
|
+
const shared = sharedParts(setup, opening.pictures, built);
|
|
52
|
+
const pass = new Mesh(built.keep(createFullscreenTriangle()), shared.materials.rectilinear);
|
|
53
|
+
compilePictureMaterials(renderer, pass.geometry, shared.materials);
|
|
54
|
+
const seamProof = built.keep(new SeamMeterPass(renderer, shared.uniforms, setup.lenses.length));
|
|
55
|
+
return {
|
|
56
|
+
...shared,
|
|
57
|
+
renderer,
|
|
58
|
+
scene: new Scene().add(pass),
|
|
59
|
+
camera: new Camera(),
|
|
60
|
+
pass,
|
|
61
|
+
matrixCorrections: new MatrixCorrections(setup.lenses, shared.uniforms.uLensMatrixCorrection),
|
|
62
|
+
lensCount: setup.lenses.length,
|
|
63
|
+
drawSchedule: opening.options.drawSchedule ?? DRAW_AT_ONCE,
|
|
64
|
+
seamProof,
|
|
65
|
+
built
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Compiles and proves the parts' programs again, as at opening: three builds every program anew
|
|
71
|
+
* on a restored context, at its first use otherwise, which would compile on screen in the frame
|
|
72
|
+
* that draws it and at each first change of view mode.
|
|
73
|
+
*/
|
|
74
|
+
function compileAgain(parts) {
|
|
75
|
+
compilePictureMaterials(parts.renderer, parts.pass.geometry, parts.materials);
|
|
76
|
+
parts.seamProof.prove();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The shader has room for `MAX_LENSES` lenses from `LENS_TEXTURES` decoded frames; a layout
|
|
80
|
+
* beyond either would be drawn wrong without a word, so it is refused.
|
|
81
|
+
*/
|
|
82
|
+
function ensureDrawable(setup) {
|
|
83
|
+
if (setup.lenses.length <= 2 && setup.frameSlotCount <= 2) return;
|
|
84
|
+
throw new GyroViewError("unsupported-layout", `the renderer draws at most 2 lenses from 2 frames; the layout has ${setup.lenses.length} lenses in ${setup.frameSlotCount} frames`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The textures, uniforms and programs every picture shares, read at the default quality.
|
|
88
|
+
*/
|
|
89
|
+
function sharedParts(setup, pictures, built) {
|
|
90
|
+
const strategy = SAMPLING_STRATEGIES[DEFAULT_PICTURE_QUALITY];
|
|
91
|
+
const textures = createLensTextures(setup.frameSlotCount, strategy).map((texture) => built.keep(texture));
|
|
92
|
+
const uniforms = createRendererUniforms(setup, textures);
|
|
93
|
+
applyShaderSampling(uniforms, strategy);
|
|
94
|
+
const materials = createPictureMaterials({
|
|
95
|
+
...uniforms,
|
|
96
|
+
...pictures.uniforms
|
|
97
|
+
}, pictures.shaders);
|
|
98
|
+
built.keep({ dispose: () => {
|
|
99
|
+
disposePictureMaterials(materials);
|
|
100
|
+
} });
|
|
101
|
+
return {
|
|
102
|
+
textures,
|
|
103
|
+
uniforms,
|
|
104
|
+
materials
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { BuiltParts, PLAYER_PICTURES, compileAgain, openRendererParts };
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { ensureIndexInRange, ensureInvariant } from "../../../core/src/shared/errors/GyroViewError.js";
|
|
2
|
+
import { MEI_TERM_CAPACITY } from "../../../core/src/domain/optics/MeiDistortion.js";
|
|
3
|
+
import { IDENTITY_MATRIX3 } from "../../../core/src/shared/math/Matrix3.js";
|
|
4
|
+
import { aspectOfArea, planeHalfExtentOf } from "../../../core/src/domain/view/rectilinear.js";
|
|
5
|
+
import { toThreeMatrix } from "./threeMatrix.js";
|
|
6
|
+
import { CONVERSION_DEFINES, conversionUniforms } from "./conversionUniforms.js";
|
|
7
|
+
import { Matrix3, Vector2, Vector3, Vector4 } from "three";
|
|
8
|
+
var LENS_MEI = 0;
|
|
9
|
+
var LENS_RADIAL_POLYNOMIAL = 1;
|
|
10
|
+
/**
|
|
11
|
+
* The constants the player's GLSL sources refer to, injected as preprocessor defines so that
|
|
12
|
+
* this file is their only home; the lab adds its own.
|
|
13
|
+
*/
|
|
14
|
+
var SHADER_DEFINES = Object.fromEntries([
|
|
15
|
+
["MAX_LENSES", 2],
|
|
16
|
+
["LENS_MEI", LENS_MEI],
|
|
17
|
+
["LENS_RADIAL_POLYNOMIAL", LENS_RADIAL_POLYNOMIAL],
|
|
18
|
+
["MEI_RADIAL_TERMS", MEI_TERM_CAPACITY.radial],
|
|
19
|
+
["MEI_TANGENTIAL_ORDERS", MEI_TERM_CAPACITY.tangential],
|
|
20
|
+
["MEI_THIN_PRISM_ORDERS", MEI_TERM_CAPACITY.thinPrism],
|
|
21
|
+
...CONVERSION_DEFINES,
|
|
22
|
+
["SAMPLING_BILINEAR", 0],
|
|
23
|
+
["SAMPLING_TRILINEAR", 1],
|
|
24
|
+
["SAMPLING_SUPERSAMPLED", 2]
|
|
25
|
+
]);
|
|
26
|
+
function createRendererUniforms(setup, textures) {
|
|
27
|
+
const lenses = padded(setup.lenses, "a stitching setup has one or two lenses");
|
|
28
|
+
return {
|
|
29
|
+
...viewUniforms(setup),
|
|
30
|
+
...projectionUniforms(lenses),
|
|
31
|
+
...samplingUniforms(lenses),
|
|
32
|
+
...conversionUniforms(lenses),
|
|
33
|
+
uTexture0: { value: textures[0] ?? null },
|
|
34
|
+
uTexture1: { value: textures[1] ?? null }
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function viewUniforms(setup) {
|
|
38
|
+
return {
|
|
39
|
+
uLensCount: { value: setup.lenses.length },
|
|
40
|
+
uViewRotation: { value: new Matrix3() },
|
|
41
|
+
uStabilization: { value: new Matrix3() },
|
|
42
|
+
uPlaneHalfExtent: { value: 1 },
|
|
43
|
+
uPictureAspect: { value: 1 },
|
|
44
|
+
uScreenArea: { value: Array.from({ length: 2 }, () => new Vector4(0, 0, 1, 1)) },
|
|
45
|
+
uFeather: { value: new Vector2(setup.feather.start, setup.feather.end) }
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function projectionUniforms(lenses) {
|
|
49
|
+
const slots = lenses.map((lens) => slotOf(lens.projection));
|
|
50
|
+
return {
|
|
51
|
+
uLensRotation: { value: lenses.map((lens) => toThreeMatrix(lens.rotation)) },
|
|
52
|
+
uLensKind: { value: slots.map((slot) => slot.kind) },
|
|
53
|
+
uLensPrincipalPoint: { value: lenses.map((lens) => toVector2(lens.projection.principalPoint)) },
|
|
54
|
+
uLensFocal: { value: slots.map((slot) => slot.focal) },
|
|
55
|
+
uLensXi: { value: slots.map((slot) => slot.xi) },
|
|
56
|
+
uLensRadial: { value: slots.flatMap((slot) => slot.radial) },
|
|
57
|
+
uLensTangential: { value: slots.flatMap((slot) => slot.tangential) },
|
|
58
|
+
uLensThinPrism: { value: slots.flatMap((slot) => slot.thinPrism) },
|
|
59
|
+
uLensPolynomial: { value: slots.map((slot) => slot.polynomial) },
|
|
60
|
+
uLensHalfFov: { value: lenses.map((lens) => lens.halfFieldOfView) }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
var NO_MEI_DISTORTION = {
|
|
64
|
+
radial: [],
|
|
65
|
+
tangential: [],
|
|
66
|
+
thinPrism: []
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Exhaustive over the projection kinds: a new kind does not compile until it is packed.
|
|
70
|
+
*/
|
|
71
|
+
function slotOf(projection) {
|
|
72
|
+
switch (projection.kind) {
|
|
73
|
+
case "mei": return {
|
|
74
|
+
kind: LENS_MEI,
|
|
75
|
+
focal: new Vector2(...projection.focal),
|
|
76
|
+
xi: projection.xi,
|
|
77
|
+
...meiTermSlots(projection.distortion),
|
|
78
|
+
polynomial: new Vector4()
|
|
79
|
+
};
|
|
80
|
+
case "radial-polynomial": return {
|
|
81
|
+
kind: LENS_RADIAL_POLYNOMIAL,
|
|
82
|
+
focal: new Vector2(),
|
|
83
|
+
xi: 0,
|
|
84
|
+
...meiTermSlots(NO_MEI_DISTORTION),
|
|
85
|
+
polynomial: new Vector4(...projection.coefficients)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function meiTermSlots(distortion) {
|
|
90
|
+
return {
|
|
91
|
+
radial: fittedToCapacity(distortion.radial, MEI_TERM_CAPACITY.radial, () => 0),
|
|
92
|
+
tangential: fittedToCapacity(distortion.tangential.map((pair) => new Vector2(pair.p1, pair.p2)), MEI_TERM_CAPACITY.tangential, () => new Vector2()),
|
|
93
|
+
thinPrism: fittedToCapacity(distortion.thinPrism.map((term) => new Vector2(term.x, term.y)), MEI_TERM_CAPACITY.thinPrism, () => new Vector2())
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The terms in the room the shader holds for their family, the rest of it zero; more terms than
|
|
98
|
+
* it holds are a defect of the model that made them.
|
|
99
|
+
*/
|
|
100
|
+
function fittedToCapacity(terms, capacity, zero) {
|
|
101
|
+
ensureInvariant(terms.length <= capacity, `a Mei lens has ${terms.length} terms of a family the shader holds ${capacity} of`);
|
|
102
|
+
return Array.from({ length: capacity }, (_unused, index) => terms[index] ?? zero());
|
|
103
|
+
}
|
|
104
|
+
function samplingUniforms(lenses) {
|
|
105
|
+
return {
|
|
106
|
+
uLensWindow: { value: lenses.map((lens) => new Vector4(lens.window.x, lens.window.y, lens.window.width, lens.window.height)) },
|
|
107
|
+
uLensRegion: { value: lenses.map((lens) => new Vector4(lens.region.x, lens.region.y, lens.region.width, lens.region.height)) },
|
|
108
|
+
uLensTexture: { value: lenses.map((lens) => lens.frameSlot) },
|
|
109
|
+
uLensGain: { value: lenses.map(() => new Vector3(1, 1, 1)) },
|
|
110
|
+
uSampling: { value: 0 }
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function applyShaderSampling(uniforms, strategy) {
|
|
114
|
+
uniforms.uSampling.value = strategy.shaderSampling;
|
|
115
|
+
}
|
|
116
|
+
function applyStabilization(uniforms, rotation) {
|
|
117
|
+
uniforms.uStabilization.value = toThreeMatrix(rotation);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Sets one lens's per-channel multiplier; a lens the setup does not have is a defect.
|
|
121
|
+
*/
|
|
122
|
+
function applyLensGain(uniforms, lensIndex, gain) {
|
|
123
|
+
ensureIndexInRange(lensIndex, uniforms.uLensCount.value, "lens");
|
|
124
|
+
uniforms.uLensGain.value[lensIndex]?.set(...gain);
|
|
125
|
+
}
|
|
126
|
+
var NEUTRAL = {
|
|
127
|
+
rotation: IDENTITY_MATRIX3,
|
|
128
|
+
planeHalfExtent: 1,
|
|
129
|
+
pictureAspect: 1
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Sets the uniforms `picture` is drawn from, on a viewport `viewportAspect` wide per unit of
|
|
133
|
+
* height.
|
|
134
|
+
*/
|
|
135
|
+
function applyPicture(uniforms, picture, viewportAspect) {
|
|
136
|
+
const values = valuesOf(picture, viewportAspect);
|
|
137
|
+
uniforms.uViewRotation.value = toThreeMatrix(values.rotation);
|
|
138
|
+
uniforms.uPlaneHalfExtent.value = values.planeHalfExtent;
|
|
139
|
+
uniforms.uPictureAspect.value = values.pictureAspect;
|
|
140
|
+
uniforms.uScreenArea.value = padded(values.areas, "a picture fills one area per lens at most").map((area) => toVector4(area));
|
|
141
|
+
}
|
|
142
|
+
function valuesOf(picture, viewportAspect) {
|
|
143
|
+
switch (picture.kind) {
|
|
144
|
+
case "rectilinear": return {
|
|
145
|
+
rotation: picture.rotation,
|
|
146
|
+
planeHalfExtent: planeHalfExtentOf(picture.fieldOfView),
|
|
147
|
+
pictureAspect: aspectOfArea(picture.area, viewportAspect),
|
|
148
|
+
areas: [picture.area]
|
|
149
|
+
};
|
|
150
|
+
case "equirectangular": return {
|
|
151
|
+
...NEUTRAL,
|
|
152
|
+
rotation: picture.rotation,
|
|
153
|
+
areas: [picture.area]
|
|
154
|
+
};
|
|
155
|
+
case "lens-tiles": return {
|
|
156
|
+
...NEUTRAL,
|
|
157
|
+
areas: picture.tiles
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function toVector4(area) {
|
|
162
|
+
return new Vector4(area.x, area.y, area.width, area.height);
|
|
163
|
+
}
|
|
164
|
+
function toVector2(point) {
|
|
165
|
+
return new Vector2(point.x, point.y);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Uniform arrays have a fixed length; unused slots repeat the last entry and are never read.
|
|
169
|
+
*/
|
|
170
|
+
function padded(entries, expectation) {
|
|
171
|
+
const last = entries.at(-1);
|
|
172
|
+
ensureInvariant(last !== void 0 && entries.length <= 2, expectation);
|
|
173
|
+
return Array.from({ length: 2 }, (_unused, index) => entries[index] ?? last);
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
export { SHADER_DEFINES, applyLensGain, applyPicture, applyShaderSampling, applyStabilization, createRendererUniforms };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LinearFilter, LinearMipmapLinearFilter } from "three";
|
|
2
|
+
/**
|
|
3
|
+
* The record keyed by the quality refuses to compile until every tier has a strategy.
|
|
4
|
+
*/
|
|
5
|
+
var SAMPLING_STRATEGIES = {
|
|
6
|
+
fast: {
|
|
7
|
+
minFilter: LinearFilter,
|
|
8
|
+
generateMipmaps: false,
|
|
9
|
+
anisotropy: 1,
|
|
10
|
+
shaderSampling: 0
|
|
11
|
+
},
|
|
12
|
+
balanced: {
|
|
13
|
+
minFilter: LinearMipmapLinearFilter,
|
|
14
|
+
generateMipmaps: true,
|
|
15
|
+
anisotropy: 4,
|
|
16
|
+
shaderSampling: 1
|
|
17
|
+
},
|
|
18
|
+
high: {
|
|
19
|
+
minFilter: LinearMipmapLinearFilter,
|
|
20
|
+
generateMipmaps: true,
|
|
21
|
+
anisotropy: 8,
|
|
22
|
+
shaderSampling: 2
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { SAMPLING_STRATEGIES };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Vector4 } from "three";
|
|
2
|
+
//#region ../../packages/adapters/three/src/scissorBox.ts
|
|
3
|
+
/**
|
|
4
|
+
* Pixels the box reaches past the area on each side, so that rounding never cuts a pixel the
|
|
5
|
+
* area holds; the shader decides those.
|
|
6
|
+
*/
|
|
7
|
+
var MARGIN_PIXELS = 1;
|
|
8
|
+
/**
|
|
9
|
+
* The box of the drawing buffer a pass is drawn within, in device pixels from the bottom-left
|
|
10
|
+
* corner as three's scissor takes it, around an area of the viewport given from the top-left.
|
|
11
|
+
*/
|
|
12
|
+
function scissorBoxOf(area, buffer) {
|
|
13
|
+
const left = Math.max(Math.floor(area.x * buffer.width) - MARGIN_PIXELS, 0);
|
|
14
|
+
const right = Math.min(Math.ceil((area.x + area.width) * buffer.width) + MARGIN_PIXELS, buffer.width);
|
|
15
|
+
const top = Math.max(Math.floor(area.y * buffer.height) - MARGIN_PIXELS, 0);
|
|
16
|
+
const bottom = Math.min(Math.ceil((area.y + area.height) * buffer.height) + MARGIN_PIXELS, buffer.height);
|
|
17
|
+
return new Vector4(left, buffer.height - bottom, right - left, bottom - top);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { scissorBoxOf };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createFullscreenTriangle, createPassMaterial, programOf } from "../fullscreenPass.js";
|
|
2
|
+
import { compileAndProve } from "../compileAndProve.js";
|
|
3
|
+
import { SEAM_ANALYSIS } from "../shaderPrograms.js";
|
|
4
|
+
import { rowMeansOf } from "./rowMeans.js";
|
|
5
|
+
import { renderInto } from "../renderInto.js";
|
|
6
|
+
import { Camera, Mesh, Scene, WebGLRenderTarget } from "three";
|
|
7
|
+
//#region ../../packages/adapters/three/src/seamMeter/SeamMeterPass.ts
|
|
8
|
+
/**
|
|
9
|
+
* Samples taken around the seam ring per lens: enough to average out content, few enough that
|
|
10
|
+
* the read-back is negligible.
|
|
11
|
+
*/
|
|
12
|
+
var SEAM_SAMPLES = 64;
|
|
13
|
+
/**
|
|
14
|
+
* SeamMeter over the GPU: renders what each lens sees along the seam ring into one row of a tiny
|
|
15
|
+
* target and reads the rows back, sharing the stitch's uniforms so it always looks at the frames
|
|
16
|
+
* on screen. Compiled and proven when created, so a broken shader fails there and not
|
|
17
|
+
* mid-playback.
|
|
18
|
+
*/
|
|
19
|
+
var SeamMeterPass = class {
|
|
20
|
+
renderer;
|
|
21
|
+
lensCount;
|
|
22
|
+
target = new WebGLRenderTarget(SEAM_SAMPLES, 2, {
|
|
23
|
+
depthBuffer: false,
|
|
24
|
+
stencilBuffer: false
|
|
25
|
+
});
|
|
26
|
+
pixels = new Uint8Array(SEAM_SAMPLES * 2 * 4);
|
|
27
|
+
camera = new Camera();
|
|
28
|
+
scene = new Scene();
|
|
29
|
+
material;
|
|
30
|
+
geometry = createFullscreenTriangle();
|
|
31
|
+
isDisposed = false;
|
|
32
|
+
constructor(renderer, uniforms, lensCount) {
|
|
33
|
+
this.renderer = renderer;
|
|
34
|
+
this.lensCount = lensCount;
|
|
35
|
+
this.material = createPassMaterial(uniforms, programOf(SEAM_ANALYSIS));
|
|
36
|
+
this.scene.add(new Mesh(this.geometry, this.material));
|
|
37
|
+
try {
|
|
38
|
+
this.prove();
|
|
39
|
+
} catch (error) {
|
|
40
|
+
this.dispose();
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compiles and proves the meter's program now, rather than at its first measurement.
|
|
46
|
+
*/
|
|
47
|
+
prove() {
|
|
48
|
+
compileAndProve(this.renderer, this.scene, this.camera);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mean colour (0..1) each lens shows along the seam where they can be compared, or undefined
|
|
52
|
+
* when they cannot be anywhere.
|
|
53
|
+
*/
|
|
54
|
+
async measure() {
|
|
55
|
+
try {
|
|
56
|
+
await this.readSeam();
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (this.isDisposed || this.renderer.getContext().isContextLost()) return void 0;
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
return this.isDisposed ? void 0 : rowMeansOf(this.pixels, SEAM_SAMPLES, this.lensCount);
|
|
62
|
+
}
|
|
63
|
+
dispose() {
|
|
64
|
+
if (this.isDisposed) return;
|
|
65
|
+
this.isDisposed = true;
|
|
66
|
+
this.target.dispose();
|
|
67
|
+
this.material.dispose();
|
|
68
|
+
this.geometry.dispose();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Renders the seam rows into the meter's target, the renderer's own target restored however the
|
|
72
|
+
* drawing ends.
|
|
73
|
+
*/
|
|
74
|
+
draw() {
|
|
75
|
+
renderInto(this.renderer, this.target, () => {
|
|
76
|
+
this.renderer.render(this.scene, this.camera);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async readSeam() {
|
|
80
|
+
this.draw();
|
|
81
|
+
await this.renderer.readRenderTargetPixelsAsync(this.target, 0, 0, SEAM_SAMPLES, 2, this.pixels);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
export { SeamMeterPass };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var CHANNEL_MAX = 255;
|
|
2
|
+
var ALPHA = 3;
|
|
3
|
+
/**
|
|
4
|
+
* A channel at or above this level (of 255) is blown out, or nearly: the lens's exposure no
|
|
5
|
+
* longer scales it, so its ratio to the other lens says nothing about their exposures.
|
|
6
|
+
*/
|
|
7
|
+
var BLOWN_OUT_LEVEL = 250;
|
|
8
|
+
/**
|
|
9
|
+
* Mean RGB (0..1) of each row of an RGBA8 image, one row per lens and one column per direction
|
|
10
|
+
* along the seam, over the directions every row images (non-zero alpha) and none shows blown out:
|
|
11
|
+
* only there do the lenses' colours differ by their exposures. Undefined when no such direction
|
|
12
|
+
* is left, because then there is nothing to match.
|
|
13
|
+
*/
|
|
14
|
+
function rowMeansOf(pixels, width, rowCount) {
|
|
15
|
+
const rows = Array.from({ length: rowCount }, (_, row) => pixels.subarray(row * width * 4, (row + 1) * width * 4));
|
|
16
|
+
const columns = Array.from({ length: width }, (_, column) => column * 4).filter((offset) => rows.every((row) => isComparable(row, offset)));
|
|
17
|
+
return columns.length === 0 ? void 0 : rows.map((row) => meanOf(row, columns));
|
|
18
|
+
}
|
|
19
|
+
function isComparable(row, offset) {
|
|
20
|
+
const texel = row.subarray(offset, offset + 4);
|
|
21
|
+
return (texel[ALPHA] ?? 0) !== 0 && texel.subarray(0, ALPHA).every((channel) => channel < BLOWN_OUT_LEVEL);
|
|
22
|
+
}
|
|
23
|
+
function meanOf(row, columns) {
|
|
24
|
+
const sum = [
|
|
25
|
+
0,
|
|
26
|
+
0,
|
|
27
|
+
0
|
|
28
|
+
];
|
|
29
|
+
for (const offset of columns) {
|
|
30
|
+
sum[0] += row[offset] ?? 0;
|
|
31
|
+
sum[1] += row[offset + 1] ?? 0;
|
|
32
|
+
sum[2] += row[offset + 2] ?? 0;
|
|
33
|
+
}
|
|
34
|
+
const scale = columns.length * CHANNEL_MAX;
|
|
35
|
+
return [
|
|
36
|
+
sum[0] / scale,
|
|
37
|
+
sum[1] / scale,
|
|
38
|
+
sum[2] / scale
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { rowMeansOf };
|