@pexip/media-processor 20.3.4 → 21.0.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/CHANGELOG.md +47 -0
- package/api-docs/README.mdx +438 -0
- package/api-docs/enumerations/AbortReason.mdx +5 -0
- package/api-docs/functions/avg.mdx +15 -0
- package/api-docs/functions/calculateDistance.mdx +18 -0
- package/api-docs/functions/closedCurve.mdx +27 -0
- package/api-docs/functions/copyByteBufferToFloatBuffer.mdx +16 -0
- package/api-docs/functions/createAnalyzerGraphNode.mdx +19 -0
- package/api-docs/functions/createAnalyzerSubscribableGraphNode.mdx +15 -0
- package/api-docs/functions/createAsyncCallbackLoop.mdx +35 -0
- package/api-docs/functions/createAudioContext.mdx +22 -0
- package/api-docs/functions/createAudioDestinationGraphNode.mdx +9 -0
- package/api-docs/functions/createAudioGraph.mdx +28 -0
- package/api-docs/functions/createAudioGraphProxy.mdx +14 -0
- package/api-docs/functions/createAudioSignalDetector.mdx +51 -0
- package/api-docs/functions/createAudioStats.mdx +19 -0
- package/api-docs/functions/createBenchmark.mdx +26 -0
- package/api-docs/functions/createCanvas.mdx +16 -0
- package/api-docs/functions/createCanvasTransform.mdx +14 -0
- package/api-docs/functions/createChannelMergerGraphNode.mdx +19 -0
- package/api-docs/functions/createChannelSplitterGraphNode.mdx +19 -0
- package/api-docs/functions/createDelayGraphNode.mdx +19 -0
- package/api-docs/functions/createDenoiseWorkletGraphNode.mdx +16 -0
- package/api-docs/functions/createFrameCallbackRequest.mdx +29 -0
- package/api-docs/functions/createGainGraphNode.mdx +15 -0
- package/api-docs/functions/createMediaElementSourceGraphNode.mdx +15 -0
- package/api-docs/functions/createSegmenter.mdx +14 -0
- package/api-docs/functions/createStreamDestinationGraphNode.mdx +15 -0
- package/api-docs/functions/createStreamSourceGraphNode.mdx +16 -0
- package/api-docs/functions/createVADetector.mdx +54 -0
- package/api-docs/functions/createVideoProcessor.mdx +14 -0
- package/api-docs/functions/createVideoTrackProcessor.mdx +9 -0
- package/api-docs/functions/createVideoTrackProcessorWithFallback.mdx +15 -0
- package/api-docs/functions/createVoiceDetectorFromProbability.mdx +15 -0
- package/api-docs/functions/createVoiceDetectorFromTimeData.mdx +19 -0
- package/api-docs/functions/createWindowedStats.mdx +23 -0
- package/api-docs/functions/curve.mdx +15 -0
- package/api-docs/functions/fromByteToFloat.mdx +27 -0
- package/api-docs/functions/fromFloatToByte.mdx +27 -0
- package/api-docs/functions/getAudioStats.mdx +19 -0
- package/api-docs/functions/getBezierCurveControlPoints.mdx +26 -0
- package/api-docs/functions/iou.mdx +19 -0
- package/api-docs/functions/isAnalyzerNodeInit.mdx +13 -0
- package/api-docs/functions/isAudioNode.mdx +13 -0
- package/api-docs/functions/isAudioNodeInit.mdx +13 -0
- package/api-docs/functions/isAudioParam.mdx +13 -0
- package/api-docs/functions/isClipping.mdx +18 -0
- package/api-docs/functions/isEqualSize.mdx +22 -0
- package/api-docs/functions/isLowVolume.mdx +19 -0
- package/api-docs/functions/isMono.mdx +22 -0
- package/api-docs/functions/isRenderEffects.mdx +13 -0
- package/api-docs/functions/isSilent.mdx +22 -0
- package/api-docs/functions/isVoiceActivity.mdx +29 -0
- package/api-docs/functions/labelComponents.mdx +20 -0
- package/api-docs/functions/line.mdx +15 -0
- package/api-docs/functions/loadScript.mdx +14 -0
- package/api-docs/functions/loadWasms.mdx +13 -0
- package/api-docs/functions/nearestPowerOfTwo.mdx +21 -0
- package/api-docs/functions/playVideo.mdx +16 -0
- package/api-docs/functions/pow.mdx +29 -0
- package/api-docs/functions/processAverageVolume.mdx +15 -0
- package/api-docs/functions/resumeAudioOnInterruption.mdx +23 -0
- package/api-docs/functions/resumeAudioOnUnmute.mdx +27 -0
- package/api-docs/functions/rms.mdx +15 -0
- package/api-docs/functions/round.mdx +23 -0
- package/api-docs/functions/scoreComponent.mdx +22 -0
- package/api-docs/functions/setVideoElementSrc.mdx +14 -0
- package/api-docs/functions/subscribeTimeoutAnalyzerNode.mdx +22 -0
- package/api-docs/functions/subscribeWorkletNode.mdx +28 -0
- package/api-docs/functions/sum.mdx +15 -0
- package/api-docs/functions/toDecibel.mdx +18 -0
- package/api-docs/interfaces/Analyzer.mdx +368 -0
- package/api-docs/interfaces/AnalyzerSubscribableOptions.mdx +11 -0
- package/api-docs/interfaces/AsyncAssets.mdx +7 -0
- package/api-docs/interfaces/AudioGraph.mdx +92 -0
- package/api-docs/interfaces/AudioGraphOptions.mdx +6 -0
- package/api-docs/interfaces/AudioNodeInit.mdx +127 -0
- package/api-docs/interfaces/AudioNodeProps.mdx +15 -0
- package/api-docs/interfaces/AudioStats.mdx +16 -0
- package/api-docs/interfaces/BackgroundImage.mdx +6 -0
- package/api-docs/interfaces/Benchmark.mdx +47 -0
- package/api-docs/interfaces/Clock.mdx +11 -0
- package/api-docs/interfaces/Denoise.mdx +50 -0
- package/api-docs/interfaces/Detector.mdx +81 -0
- package/api-docs/interfaces/Frame.mdx +11 -0
- package/api-docs/interfaces/Gain.mdx +227 -0
- package/api-docs/interfaces/ImageRecord.mdx +6 -0
- package/api-docs/interfaces/ImageSegmenterOptions.mdx +8 -0
- package/api-docs/interfaces/MPMask.mdx +145 -0
- package/api-docs/interfaces/Point.mdx +10 -0
- package/api-docs/interfaces/Process.mdx +46 -0
- package/api-docs/interfaces/ProcessEventClose.mdx +7 -0
- package/api-docs/interfaces/ProcessEventDebug.mdx +14 -0
- package/api-docs/interfaces/ProcessEventDestroy.mdx +7 -0
- package/api-docs/interfaces/ProcessEventOpen.mdx +14 -0
- package/api-docs/interfaces/ProcessEventProcess.mdx +14 -0
- package/api-docs/interfaces/ProcessEventUpdate.mdx +14 -0
- package/api-docs/interfaces/ProcessWorkerDebugMessage.mdx +6 -0
- package/api-docs/interfaces/ProcessWorkerEvent.mdx +12 -0
- package/api-docs/interfaces/ProcessWorkerEventDebug.mdx +12 -0
- package/api-docs/interfaces/ProcessWorkerEventOpened.mdx +5 -0
- package/api-docs/interfaces/ProcessWorkerEventProcessed.mdx +12 -0
- package/api-docs/interfaces/ProcessWorkerEventUpdated.mdx +5 -0
- package/api-docs/interfaces/ProcessorEvent.mdx +7 -0
- package/api-docs/interfaces/ProcessorOptions.mdx +16 -0
- package/api-docs/interfaces/ProcessorProcessOptions.mdx +6 -0
- package/api-docs/interfaces/Rect.mdx +8 -0
- package/api-docs/interfaces/RenderEventHandlers.mdx +7 -0
- package/api-docs/interfaces/Renderer.mdx +64 -0
- package/api-docs/interfaces/RendererOptions.mdx +32 -0
- package/api-docs/interfaces/Runner.mdx +41 -0
- package/api-docs/interfaces/Segmentation.mdx +5 -0
- package/api-docs/interfaces/SegmentationModelAsset.mdx +8 -0
- package/api-docs/interfaces/SegmentationParams.mdx +35 -0
- package/api-docs/interfaces/SegmentationSmoothingConfig.mdx +5 -0
- package/api-docs/interfaces/Segmenter.mdx +121 -0
- package/api-docs/interfaces/SegmenterOptions.mdx +13 -0
- package/api-docs/interfaces/SelectionOptions.mdx +15 -0
- package/api-docs/interfaces/Size.mdx +10 -0
- package/api-docs/interfaces/Stats.mdx +11 -0
- package/api-docs/interfaces/StatsOptions.mdx +10 -0
- package/api-docs/interfaces/SubscribableOptions.mdx +9 -0
- package/api-docs/interfaces/ThrottleOptions.mdx +8 -0
- package/api-docs/interfaces/Transform.mdx +62 -0
- package/api-docs/interfaces/VideoFrameLike.mdx +8 -0
- package/api-docs/interfaces/VideoProcessor.mdx +38 -0
- package/api-docs/interfaces/Weights.mdx +12 -0
- package/api-docs/interfaces/WorkletMessagePortOptions.mdx +16 -0
- package/api-docs/interfaces/WorkletModule.mdx +6 -0
- package/api-docs/type-aliases/AnalyzerNodeInit.mdx +3 -0
- package/api-docs/type-aliases/AsyncCallback.mdx +7 -0
- package/api-docs/type-aliases/AudioBufferBytes.mdx +5 -0
- package/api-docs/type-aliases/AudioBufferFloats.mdx +6 -0
- package/api-docs/type-aliases/AudioDestinationNodeInit.mdx +3 -0
- package/api-docs/type-aliases/AudioNodeConnectParam.mdx +3 -0
- package/api-docs/type-aliases/AudioNodeInitConnectParam.mdx +3 -0
- package/api-docs/type-aliases/AudioNodeInitConnection.mdx +3 -0
- package/api-docs/type-aliases/AudioNodeInitConnections.mdx +3 -0
- package/api-docs/type-aliases/AudioNodeParam.mdx +3 -0
- package/api-docs/type-aliases/AudioSamples.mdx +17 -0
- package/api-docs/type-aliases/BaseAudioNode.mdx +3 -0
- package/api-docs/type-aliases/Callback.mdx +20 -0
- package/api-docs/type-aliases/Canvas.mdx +3 -0
- package/api-docs/type-aliases/CanvasContext.mdx +3 -0
- package/api-docs/type-aliases/ChannelSplitterNodeInit.mdx +3 -0
- package/api-docs/type-aliases/Color.mdx +12 -0
- package/api-docs/type-aliases/ConnectInitParamBaseType.mdx +3 -0
- package/api-docs/type-aliases/ConnectInitParamType.mdx +3 -0
- package/api-docs/type-aliases/ConnectParamBase.mdx +11 -0
- package/api-docs/type-aliases/ConnectParamBaseType.mdx +3 -0
- package/api-docs/type-aliases/ConnectParamType.mdx +3 -0
- package/api-docs/type-aliases/DelayNodeInit.mdx +3 -0
- package/api-docs/type-aliases/Delegate.mdx +3 -0
- package/api-docs/type-aliases/DenoiseWorkletNodeInit.mdx +3 -0
- package/api-docs/type-aliases/ExtractMessageEventType.mdx +9 -0
- package/api-docs/type-aliases/GainNodeInit.mdx +3 -0
- package/api-docs/type-aliases/ImageMapIterable.mdx +3 -0
- package/api-docs/type-aliases/ImageType.mdx +6 -0
- package/api-docs/type-aliases/IncludeMessageEventDataType.mdx +10 -0
- package/api-docs/type-aliases/InputFrame.mdx +3 -0
- package/api-docs/type-aliases/IsVoice.mdx +19 -0
- package/api-docs/type-aliases/MediaElementAudioSourceNodeInit.mdx +3 -0
- package/api-docs/type-aliases/MediaStreamAudioDestinationNodeInit.mdx +3 -0
- package/api-docs/type-aliases/MediaStreamAudioSourceNodeInit.mdx +3 -0
- package/api-docs/type-aliases/Node.mdx +3 -0
- package/api-docs/type-aliases/NodeConnectionAction.mdx +3 -0
- package/api-docs/type-aliases/Nodes.mdx +3 -0
- package/api-docs/type-aliases/OptionalKeys.mdx +10 -0
- package/api-docs/type-aliases/ProcessEvents.mdx +17 -0
- package/api-docs/type-aliases/ProcessInputType.mdx +3 -0
- package/api-docs/type-aliases/ProcessStatus.mdx +3 -0
- package/api-docs/type-aliases/ProcessVideoTrack.mdx +15 -0
- package/api-docs/type-aliases/ProcessWorkerEvents.mdx +18 -0
- package/api-docs/type-aliases/ProcessorEvents.mdx +3 -0
- package/api-docs/type-aliases/ProcessorWorkerEvents.mdx +3 -0
- package/api-docs/type-aliases/RenderBackend.mdx +3 -0
- package/api-docs/type-aliases/RenderEffects.mdx +3 -0
- package/api-docs/type-aliases/RenderingEvents.mdx +3 -0
- package/api-docs/type-aliases/RunnerCreator.mdx +21 -0
- package/api-docs/type-aliases/SegmentationModel.mdx +3 -0
- package/api-docs/type-aliases/SegmentationTransform.mdx +3 -0
- package/api-docs/type-aliases/TupleOf.mdx +12 -0
- package/api-docs/type-aliases/UniversalAudioContextState.mdx +6 -0
- package/api-docs/type-aliases/Unsubscribe.mdx +9 -0
- package/api-docs/type-aliases/WasmPaths.mdx +3 -0
- package/api-docs/variables/BACKGROUND_BLUR_AMOUNT.mdx +3 -0
- package/api-docs/variables/BACKGROUND_THRESHOLD.mdx +3 -0
- package/api-docs/variables/CLIP_COUNT_THRESHOLD.mdx +6 -0
- package/api-docs/variables/CLIP_THRESHOLD.mdx +5 -0
- package/api-docs/variables/DOWN_SAMPLE_FACTOR.mdx +3 -0
- package/api-docs/variables/EDGE_BLUR_AMOUNT.mdx +3 -0
- package/api-docs/variables/EXCLUDE_BYSTANDERS.mdx +3 -0
- package/api-docs/variables/FOREGROUND_THRESHOLD.mdx +3 -0
- package/api-docs/variables/FRAME_RATE.mdx +3 -0
- package/api-docs/variables/LIGHT_WRAP_BLUR_AMOUNT.mdx +3 -0
- package/api-docs/variables/LIGHT_WRAP_EDGE_BAND.mdx +3 -0
- package/api-docs/variables/LIGHT_WRAP_INTENSITY.mdx +3 -0
- package/api-docs/variables/LIGHT_WRAP_TIGHTNESS.mdx +3 -0
- package/api-docs/variables/LOW_VOLUME_THRESHOLD.mdx +5 -0
- package/api-docs/variables/MASK_COMBINE_RATIO.mdx +3 -0
- package/api-docs/variables/MONO_THRESHOLD.mdx +6 -0
- package/api-docs/variables/MORPH_DILATE_RADIUS_PX.mdx +3 -0
- package/api-docs/variables/MORPH_ERODE_RADIUS_PX.mdx +3 -0
- package/api-docs/variables/MORPH_PASS.mdx +3 -0
- package/api-docs/variables/PERSON_CENTER.mdx +3 -0
- package/api-docs/variables/PLAY_VIDEO_TIMEOUT.mdx +3 -0
- package/api-docs/variables/PROCESSING_HEIGHT.mdx +3 -0
- package/api-docs/variables/PROCESSING_WIDTH.mdx +3 -0
- package/api-docs/variables/PROCESS_STATUS.mdx +22 -0
- package/api-docs/variables/RENDERING_EVENTS.mdx +14 -0
- package/api-docs/variables/RENDER_BACKEND.mdx +10 -0
- package/api-docs/variables/RENDER_EFFECT.mdx +11 -0
- package/api-docs/variables/SEGMENTATION_MODELS.mdx +10 -0
- package/api-docs/variables/SIGMA_RANGE.mdx +3 -0
- package/api-docs/variables/SIGMA_SPACE.mdx +3 -0
- package/api-docs/variables/SILENT_THRESHOLD.mdx +6 -0
- package/api-docs/variables/STRONG_EDGE_BLUR_AMOUNT.mdx +3 -0
- package/api-docs/variables/VOICE_PROBABILITY_THRESHOLD.mdx +5 -0
- package/api-docs/variables/calculateMaxBlurPass.mdx +13 -0
- package/api-docs/variables/clamping.mdx +26 -0
- package/api-docs/variables/createLazyProps.mdx +19 -0
- package/api-docs/variables/createObjectUpdater.mdx +31 -0
- package/api-docs/variables/createRemoteImageBitmap.mdx +21 -0
- package/api-docs/variables/getCanvasRenderingContext2D.mdx +14 -0
- package/api-docs/variables/getErrorMessage.mdx +13 -0
- package/api-docs/variables/getImageSize.mdx +13 -0
- package/api-docs/variables/handleWebGLContextLoss.mdx +21 -0
- package/api-docs/variables/isRenderingEvents.mdx +13 -0
- package/api-docs/variables/isSegmentationModel.mdx +13 -0
- package/api-docs/variables/resize.mdx +30 -0
- package/api-docs/variables/toRenderingEvents.mdx +13 -0
- package/api-docs/variables/urls.mdx +10 -0
- package/dist/common/backends/webgl/binaryMask.d.ts +8 -0
- package/dist/common/backends/webgl/binaryMask.js +95 -0
- package/dist/common/backends/webgl/blender.d.ts +2 -1
- package/dist/common/backends/webgl/blender.js +18 -15
- package/dist/common/backends/webgl/blur.d.ts +1 -1
- package/dist/common/backends/webgl/blur.js +23 -16
- package/dist/common/backends/webgl/canvas.js +9 -4
- package/dist/common/backends/webgl/diffAbsMask.d.ts +10 -0
- package/dist/common/backends/webgl/diffAbsMask.js +103 -0
- package/dist/common/backends/webgl/geodesicReconstruction.d.ts +13 -0
- package/dist/common/backends/webgl/geodesicReconstruction.js +176 -0
- package/dist/common/backends/webgl/jointBilateralFilter.d.ts +12 -0
- package/dist/common/backends/webgl/jointBilateralFilter.js +108 -0
- package/dist/common/backends/webgl/morphErode.d.ts +13 -0
- package/dist/common/backends/webgl/morphErode.js +121 -0
- package/dist/common/backends/webgl/renderer.js +194 -34
- package/dist/common/backends/webgl/replace.d.ts +17 -0
- package/dist/common/backends/webgl/replace.js +126 -0
- package/dist/common/backends/webgl/selectComponent.d.ts +15 -0
- package/dist/common/backends/webgl/selectComponent.js +102 -0
- package/dist/common/backends/webgl/smoothingMask.d.ts +3 -3
- package/dist/common/backends/webgl/smoothingMask.js +22 -21
- package/dist/common/backends/webgl/tentBlur.d.ts +9 -0
- package/dist/common/backends/webgl/tentBlur.js +118 -0
- package/dist/common/backends/webgl/texture.d.ts +1 -1
- package/dist/common/backends/webgl/texture.js +19 -17
- package/dist/common/backends/webgl/textureToTexture.d.ts +1 -1
- package/dist/common/backends/webgl/textureToTexture.js +19 -16
- package/dist/common/backends/webgl/webglUtils.d.ts +7 -1
- package/dist/common/backends/webgl/webglUtils.js +64 -6
- package/dist/common/backends/webgpu/blender.d.ts +6 -1
- package/dist/common/backends/webgpu/blender.js +96 -51
- package/dist/common/backends/webgpu/constants.js +1 -1
- package/dist/common/backends/webgpu/dualFilterBlur.d.ts +2 -3
- package/dist/common/backends/webgpu/dualFilterBlur.js +146 -140
- package/dist/common/backends/webgpu/jointBilateralFilter.d.ts +7 -0
- package/dist/common/backends/webgpu/jointBilateralFilter.js +162 -0
- package/dist/common/backends/webgpu/renderer.js +211 -39
- package/dist/common/backends/webgpu/replace.d.ts +11 -0
- package/dist/common/backends/webgpu/replace.js +175 -0
- package/dist/common/backends/webgpu/resize.d.ts +4 -0
- package/dist/common/backends/webgpu/resize.js +76 -0
- package/dist/common/backends/webgpu/smoothingMask.d.ts +2 -2
- package/dist/common/backends/webgpu/smoothingMask.js +74 -40
- package/dist/common/backends/webgpu/tentBlur.d.ts +5 -0
- package/dist/common/backends/webgpu/tentBlur.js +131 -0
- package/dist/common/backends/webgpu/texture.d.ts +2 -2
- package/dist/common/backends/webgpu/texture.js +24 -19
- package/dist/common/backends/webgpu/textureToTexture.d.ts +1 -1
- package/dist/common/backends/webgpu/textureToTexture.js +28 -15
- package/dist/common/backends/webgpu/types.d.ts +2 -0
- package/dist/common/backends/webgpu/webgpuUtils.d.ts +24 -4
- package/dist/common/backends/webgpu/webgpuUtils.js +60 -11
- package/dist/common/constants.d.ts +19 -5
- package/dist/common/constants.js +19 -5
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.js +1 -0
- package/dist/common/tsconfig.tsbuildinfo +1 -1
- package/dist/common/types/render.d.ts +142 -13
- package/dist/common/types/utils.d.ts +21 -0
- package/dist/common/utils.d.ts +16 -0
- package/dist/common/utils.js +152 -0
- package/dist/main/benchUtils.d.ts +33 -1
- package/dist/main/benchUtils.js +145 -11
- package/dist/main/tsconfig.tsbuildinfo +1 -1
- package/dist/main/video/canvasTransform.d.ts +1 -1
- package/dist/main/video/canvasTransform.js +135 -47
- package/dist/main/video/index.d.ts +1 -1
- package/dist/main/video/index.js +1 -1
- package/dist/workers/mediaWorker.js +35 -162
- package/dist/workers/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -10
- package/dist/common/backends/webgl/shaders/blendFragmentShader.d.ts +0 -1
- package/dist/common/backends/webgl/shaders/blendFragmentShader.js +0 -21
- package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.d.ts +0 -1
- package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.js +0 -45
- package/dist/common/backends/webgl/shaders/smoothingMaskFragmentShader.d.ts +0 -1
- package/dist/common/backends/webgl/shaders/smoothingMaskFragmentShader.js +0 -57
- package/dist/common/backends/webgl/shaders/textureFragmentShader.d.ts +0 -1
- package/dist/common/backends/webgl/shaders/textureFragmentShader.js +0 -16
- package/dist/common/backends/webgl/shaders/vertexShader.d.ts +0 -1
- package/dist/common/backends/webgl/shaders/vertexShader.js +0 -19
|
@@ -1,192 +1,194 @@
|
|
|
1
1
|
import { assert } from '@pexip/utils';
|
|
2
2
|
import { RENDERING_EVENTS } from '../../constants';
|
|
3
|
-
import
|
|
3
|
+
import blurComputeShader from './shaders/dualBlurComputeShader.wgsl';
|
|
4
4
|
import { clamping } from '../../utils';
|
|
5
|
-
import { RENDER_PASS_COLOR_ATTACHMENT_CLEAR_VALUE } from './constants';
|
|
6
5
|
const clampBlurAmount = clamping(1, 9);
|
|
7
|
-
export const createBlurRenderer = (
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
context.configure({
|
|
13
|
-
device,
|
|
14
|
-
format: presentationFormat,
|
|
15
|
-
alphaMode: 'premultiplied',
|
|
16
|
-
});
|
|
17
|
-
// Helper to create a texture of given size
|
|
18
|
-
const createTexture = (width, height) => device.createTexture({
|
|
19
|
-
format: presentationFormat,
|
|
20
|
-
size: [width, height],
|
|
21
|
-
usage: GPUTextureUsage.TEXTURE_BINDING |
|
|
22
|
-
GPUTextureUsage.COPY_DST |
|
|
23
|
-
GPUTextureUsage.RENDER_ATTACHMENT,
|
|
24
|
-
});
|
|
25
|
-
// Helper to create a uniform buffer to flip downsampling vs upsampling
|
|
26
|
-
const createFlipBuffer = (value) => {
|
|
27
|
-
const buffer = device.createBuffer({
|
|
28
|
-
size: 4,
|
|
29
|
-
mappedAtCreation: true,
|
|
30
|
-
usage: GPUBufferUsage.UNIFORM,
|
|
31
|
-
});
|
|
32
|
-
new Uint32Array(buffer.getMappedRange())[0] = value;
|
|
33
|
-
buffer.unmap();
|
|
34
|
-
return buffer;
|
|
35
|
-
};
|
|
36
|
-
const sampler = device.createSampler({
|
|
37
|
-
magFilter: 'linear',
|
|
38
|
-
minFilter: 'linear',
|
|
6
|
+
export const createBlurRenderer = (device, width, height, textureFormat, isContextLost) => {
|
|
7
|
+
const shaderModule = device.createShaderModule({
|
|
8
|
+
label: 'dual blur compute shader',
|
|
9
|
+
code: blurComputeShader,
|
|
39
10
|
});
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
label: 'dual blur render pipeline',
|
|
11
|
+
const downsamplePipeline = device.createRenderPipeline({
|
|
12
|
+
label: 'dual blur downsample compute pipeline',
|
|
43
13
|
layout: 'auto',
|
|
44
|
-
vertex: {
|
|
14
|
+
vertex: { module: shaderModule, entryPoint: 'vs_main' },
|
|
15
|
+
fragment: {
|
|
45
16
|
module: shaderModule,
|
|
46
|
-
|
|
47
|
-
|
|
17
|
+
targets: [{ format: textureFormat }],
|
|
18
|
+
entryPoint: 'downsample_fs',
|
|
48
19
|
},
|
|
20
|
+
});
|
|
21
|
+
const upsamplePipeline = device.createRenderPipeline({
|
|
22
|
+
label: 'dual blur upsample compute pipeline',
|
|
23
|
+
layout: 'auto',
|
|
24
|
+
vertex: { module: shaderModule, entryPoint: 'vs_main' },
|
|
49
25
|
fragment: {
|
|
50
26
|
module: shaderModule,
|
|
51
|
-
|
|
52
|
-
|
|
27
|
+
targets: [{ format: textureFormat }],
|
|
28
|
+
entryPoint: 'upsample_fs',
|
|
53
29
|
},
|
|
54
|
-
primitive: { topology: 'triangle-list' },
|
|
55
30
|
});
|
|
56
|
-
|
|
31
|
+
const sampler = device.createSampler({
|
|
32
|
+
magFilter: 'linear',
|
|
33
|
+
minFilter: 'linear',
|
|
34
|
+
addressModeU: 'clamp-to-edge',
|
|
35
|
+
addressModeV: 'clamp-to-edge',
|
|
36
|
+
});
|
|
37
|
+
// Helper to create a texture of given size
|
|
38
|
+
const createTexture = (w, h) => device.createTexture({
|
|
39
|
+
label: 'dual filter blur texture',
|
|
40
|
+
format: textureFormat,
|
|
41
|
+
size: [w, h],
|
|
42
|
+
usage: GPUTextureUsage.TEXTURE_BINDING |
|
|
43
|
+
GPUTextureUsage.RENDER_ATTACHMENT,
|
|
44
|
+
});
|
|
45
|
+
// --- State for persistent textures and bind groups ---
|
|
57
46
|
let blurTextures = [];
|
|
58
47
|
let lastWidth = -1;
|
|
59
48
|
let lastHeight = -1;
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
let downsampleRenderPassDescriptor = [];
|
|
50
|
+
let upsampleRenderPassDescriptor = [];
|
|
51
|
+
let downsampleBindGroups = [];
|
|
52
|
+
let upsampleBindGroups = [];
|
|
53
|
+
let cacheFrameTexture = null;
|
|
54
|
+
let cacheFirstDownsampleBindGroup = null;
|
|
55
|
+
let cacheFirstDownsampleRenderPassDescriptor = null;
|
|
56
|
+
// Helper to (re)generate textures and bind groups if needed
|
|
57
|
+
function ensureBlurTextures(pass, frameWidth, frameHeight) {
|
|
62
58
|
const length = clampBlurAmount(pass + 1);
|
|
63
|
-
let needsUpdate = false;
|
|
64
59
|
if (blurTextures.length !== length ||
|
|
65
|
-
lastWidth !==
|
|
66
|
-
lastHeight !==
|
|
60
|
+
lastWidth !== frameWidth ||
|
|
61
|
+
lastHeight !== frameHeight) {
|
|
67
62
|
// Destroy old textures
|
|
68
63
|
for (const t of blurTextures) {
|
|
69
64
|
t.texture.destroy();
|
|
70
65
|
}
|
|
71
66
|
blurTextures = [];
|
|
67
|
+
downsampleBindGroups = [];
|
|
68
|
+
downsampleRenderPassDescriptor = [];
|
|
69
|
+
upsampleBindGroups = [];
|
|
70
|
+
// Invalidate frame cache since firstDst view has changed
|
|
71
|
+
cacheFrameTexture = null;
|
|
72
|
+
cacheFirstDownsampleBindGroup = null;
|
|
72
73
|
for (let i = 0; i < length; i++) {
|
|
73
|
-
const w = Math.max(Math.trunc(
|
|
74
|
-
const h = Math.max(Math.trunc(
|
|
74
|
+
const w = Math.max(Math.trunc(frameWidth / 2 ** i), 1);
|
|
75
|
+
const h = Math.max(Math.trunc(frameHeight / 2 ** i), 1);
|
|
76
|
+
const texture = createTexture(w, h);
|
|
75
77
|
blurTextures.push({
|
|
76
|
-
texture
|
|
78
|
+
texture,
|
|
79
|
+
view: texture.createView(),
|
|
77
80
|
width: w,
|
|
78
81
|
height: h,
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
needsUpdate = true;
|
|
84
|
-
}
|
|
85
|
-
return needsUpdate;
|
|
86
|
-
}
|
|
87
|
-
const flipDownBuffer = createFlipBuffer(0); // create once
|
|
88
|
-
const flipUpBuffer = createFlipBuffer(1); // create once
|
|
89
|
-
return {
|
|
90
|
-
render: (frame, pass) => {
|
|
91
|
-
assert(!isContextLost(), RENDERING_EVENTS.ContextLost);
|
|
92
|
-
// Ensure textures and buffers are up-to-date
|
|
93
|
-
ensureBlurTextures(pass, processor.width, processor.height);
|
|
94
|
-
// Upload frame to the largest texture (level 0)
|
|
95
|
-
const largestTexture = blurTextures[0];
|
|
96
|
-
assert(largestTexture);
|
|
97
|
-
device.queue.copyExternalImageToTexture({ source: frame.frame, flipY: false }, { texture: largestTexture.texture }, { width: largestTexture.width, height: largestTexture.height });
|
|
98
|
-
// Downsampling passes
|
|
99
|
-
for (let i = 1; i < blurTextures.length; i++) {
|
|
84
|
+
// Pre-create downsample bind groups: blurTextures[i-1] → blurTextures[i]
|
|
85
|
+
for (let i = 2; i < blurTextures.length; i++) {
|
|
100
86
|
const src = blurTextures[i - 1];
|
|
101
|
-
assert(src);
|
|
102
87
|
const dst = blurTextures[i];
|
|
88
|
+
assert(src);
|
|
103
89
|
assert(dst);
|
|
104
|
-
|
|
105
|
-
layout:
|
|
90
|
+
downsampleBindGroups.push(device.createBindGroup({
|
|
91
|
+
layout: downsamplePipeline.getBindGroupLayout(0),
|
|
106
92
|
entries: [
|
|
107
93
|
{ binding: 0, resource: sampler },
|
|
108
|
-
{ binding: 1, resource: src.
|
|
109
|
-
{ binding: 2, resource: { buffer: flipDownBuffer } },
|
|
94
|
+
{ binding: 1, resource: src.view },
|
|
110
95
|
],
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
|
|
96
|
+
}));
|
|
97
|
+
downsampleRenderPassDescriptor.push({
|
|
98
|
+
label: `downsample render pass ${i}`,
|
|
114
99
|
colorAttachments: [
|
|
115
|
-
{
|
|
116
|
-
view: dst.texture.createView(),
|
|
117
|
-
loadOp: 'clear',
|
|
118
|
-
storeOp: 'store',
|
|
119
|
-
clearValue: RENDER_PASS_COLOR_ATTACHMENT_CLEAR_VALUE,
|
|
120
|
-
},
|
|
100
|
+
{ loadOp: 'load', storeOp: 'store', view: dst.view },
|
|
121
101
|
],
|
|
122
102
|
});
|
|
123
|
-
passEncoder.setPipeline(pipeline);
|
|
124
|
-
passEncoder.setBindGroup(0, bindGroup);
|
|
125
|
-
passEncoder.draw(6);
|
|
126
|
-
passEncoder.end();
|
|
127
|
-
device.queue.submit([encoder.finish()]);
|
|
128
103
|
}
|
|
129
|
-
//
|
|
104
|
+
// Pre-create upsample bind groups: blurTextures[i+1] → blurTextures[i]
|
|
105
|
+
// Filled in descending order so upsampleBindGroups[0] is the deepest pair.
|
|
130
106
|
for (let i = blurTextures.length - 2; i >= 0; i--) {
|
|
131
107
|
const src = blurTextures[i + 1];
|
|
132
|
-
assert(src);
|
|
133
108
|
const dst = blurTextures[i];
|
|
109
|
+
assert(src);
|
|
134
110
|
assert(dst);
|
|
135
|
-
|
|
136
|
-
layout:
|
|
111
|
+
upsampleBindGroups.push(device.createBindGroup({
|
|
112
|
+
layout: upsamplePipeline.getBindGroupLayout(0),
|
|
137
113
|
entries: [
|
|
138
114
|
{ binding: 0, resource: sampler },
|
|
139
|
-
{ binding: 1, resource: src.
|
|
140
|
-
{ binding: 2, resource: { buffer: flipUpBuffer } },
|
|
115
|
+
{ binding: 1, resource: src.view },
|
|
141
116
|
],
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
|
|
117
|
+
}));
|
|
118
|
+
upsampleRenderPassDescriptor.push({
|
|
119
|
+
label: `upsample render pass ${i}`,
|
|
145
120
|
colorAttachments: [
|
|
146
|
-
{
|
|
147
|
-
view: dst.texture.createView(),
|
|
148
|
-
loadOp: 'clear',
|
|
149
|
-
storeOp: 'store',
|
|
150
|
-
clearValue: RENDER_PASS_COLOR_ATTACHMENT_CLEAR_VALUE,
|
|
151
|
-
},
|
|
121
|
+
{ loadOp: 'load', storeOp: 'store', view: dst.view },
|
|
152
122
|
],
|
|
153
123
|
});
|
|
154
|
-
passEncoder.setPipeline(pipeline);
|
|
155
|
-
passEncoder.setBindGroup(0, bindGroup);
|
|
156
|
-
passEncoder.draw(6);
|
|
157
|
-
passEncoder.end();
|
|
158
|
-
device.queue.submit([encoder.finish()]);
|
|
159
124
|
}
|
|
160
|
-
|
|
125
|
+
lastWidth = frameWidth;
|
|
126
|
+
lastHeight = frameHeight;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
render: (encoder, frame, pass) => {
|
|
131
|
+
assert(!isContextLost(), RENDERING_EVENTS.ContextLost);
|
|
132
|
+
// Ensure textures and bind groups are up-to-date
|
|
133
|
+
ensureBlurTextures(pass, width, height);
|
|
134
|
+
const firstDst = blurTextures[1];
|
|
135
|
+
assert(firstDst);
|
|
136
|
+
// Cache the first downsample bind group (frame → blurTextures[1])
|
|
137
|
+
if (frame !== cacheFrameTexture) {
|
|
138
|
+
cacheFirstDownsampleBindGroup = device.createBindGroup({
|
|
139
|
+
layout: downsamplePipeline.getBindGroupLayout(0),
|
|
140
|
+
entries: [
|
|
141
|
+
{ binding: 0, resource: sampler },
|
|
142
|
+
{ binding: 1, resource: frame.createView() },
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
cacheFirstDownsampleRenderPassDescriptor = {
|
|
146
|
+
label: `downsample render pass 0`,
|
|
147
|
+
colorAttachments: [
|
|
148
|
+
{ loadOp: 'load', storeOp: 'store', view: firstDst.view },
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
cacheFrameTexture = frame;
|
|
152
|
+
}
|
|
153
|
+
assert(cacheFirstDownsampleRenderPassDescriptor);
|
|
154
|
+
// First downsampling: frame → blurTextures[1]
|
|
155
|
+
const firstComputePass = encoder.beginRenderPass(cacheFirstDownsampleRenderPassDescriptor);
|
|
156
|
+
firstComputePass.setPipeline(downsamplePipeline);
|
|
157
|
+
firstComputePass.setBindGroup(0, cacheFirstDownsampleBindGroup);
|
|
158
|
+
firstComputePass.draw(3);
|
|
159
|
+
firstComputePass.end();
|
|
160
|
+
// Subsequent downsampling passes: blurTextures[i-1] → blurTextures[i]
|
|
161
|
+
for (let i = 2; i < blurTextures.length; i++) {
|
|
162
|
+
const dst = blurTextures[i];
|
|
163
|
+
assert(dst);
|
|
164
|
+
// downsampleBindGroups[i-1] covers blurTextures[i-1] → blurTextures[i]
|
|
165
|
+
const bindGroup = downsampleBindGroups[i - 2];
|
|
166
|
+
const renderPassDescriptor = downsampleRenderPassDescriptor[i - 2];
|
|
167
|
+
assert(bindGroup);
|
|
168
|
+
assert(renderPassDescriptor);
|
|
169
|
+
const pass = encoder.beginRenderPass(renderPassDescriptor);
|
|
170
|
+
pass.setPipeline(downsamplePipeline);
|
|
171
|
+
pass.setBindGroup(0, bindGroup);
|
|
172
|
+
pass.draw(3);
|
|
173
|
+
pass.end();
|
|
174
|
+
}
|
|
175
|
+
// Upsampling passes (deepest level first, up to blurTextures[0])
|
|
176
|
+
for (let i = 0; i < upsampleBindGroups.length; i++) {
|
|
177
|
+
const dstIdx = blurTextures.length - 2 - i;
|
|
178
|
+
const dst = blurTextures[dstIdx];
|
|
179
|
+
assert(dst);
|
|
180
|
+
const bindGroup = upsampleBindGroups[i];
|
|
181
|
+
const renderPassDescriptor = upsampleRenderPassDescriptor[i];
|
|
182
|
+
assert(bindGroup);
|
|
183
|
+
assert(renderPassDescriptor);
|
|
184
|
+
const pass = encoder.beginRenderPass(renderPassDescriptor);
|
|
185
|
+
pass.setPipeline(upsamplePipeline);
|
|
186
|
+
pass.setBindGroup(0, bindGroup);
|
|
187
|
+
pass.draw(3);
|
|
188
|
+
pass.end();
|
|
189
|
+
}
|
|
161
190
|
const finalTexture = blurTextures[0];
|
|
162
191
|
assert(finalTexture);
|
|
163
|
-
const finalBindGroup = device.createBindGroup({
|
|
164
|
-
layout: pipeline.getBindGroupLayout(0),
|
|
165
|
-
entries: [
|
|
166
|
-
{ binding: 0, resource: sampler },
|
|
167
|
-
{
|
|
168
|
-
binding: 1,
|
|
169
|
-
resource: finalTexture.texture.createView(),
|
|
170
|
-
},
|
|
171
|
-
{ binding: 2, resource: { buffer: flipUpBuffer } },
|
|
172
|
-
],
|
|
173
|
-
});
|
|
174
|
-
const encoder = device.createCommandEncoder();
|
|
175
|
-
const passEncoder = encoder.beginRenderPass({
|
|
176
|
-
colorAttachments: [
|
|
177
|
-
{
|
|
178
|
-
view: context.getCurrentTexture().createView(),
|
|
179
|
-
loadOp: 'clear',
|
|
180
|
-
storeOp: 'store',
|
|
181
|
-
clearValue: RENDER_PASS_COLOR_ATTACHMENT_CLEAR_VALUE,
|
|
182
|
-
},
|
|
183
|
-
],
|
|
184
|
-
});
|
|
185
|
-
passEncoder.setPipeline(pipeline);
|
|
186
|
-
passEncoder.setBindGroup(0, finalBindGroup);
|
|
187
|
-
passEncoder.draw(6);
|
|
188
|
-
passEncoder.end();
|
|
189
|
-
device.queue.submit([encoder.finish()]);
|
|
190
192
|
return finalTexture.texture;
|
|
191
193
|
},
|
|
192
194
|
release: () => {
|
|
@@ -194,8 +196,12 @@ export const createBlurRenderer = (processor, device, presentationFormat, isCont
|
|
|
194
196
|
t.texture.destroy();
|
|
195
197
|
}
|
|
196
198
|
blurTextures = [];
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
downsampleRenderPassDescriptor = [];
|
|
200
|
+
upsampleRenderPassDescriptor = [];
|
|
201
|
+
downsampleBindGroups = [];
|
|
202
|
+
upsampleBindGroups = [];
|
|
203
|
+
cacheFrameTexture = null;
|
|
204
|
+
cacheFirstDownsampleBindGroup = null;
|
|
199
205
|
},
|
|
200
206
|
};
|
|
201
207
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RendererOptions } from '../../types/render';
|
|
2
|
+
type JointBilateralFilterParams = Pick<RendererOptions, 'sigmaSpace' | 'sigmaRangeLo' | 'sigmaRangeHi' | 'backgroundThreshold' | 'foregroundThreshold'>;
|
|
3
|
+
export declare const createJointBilateralFilterRenderer: (processor: OffscreenCanvas, device: GPUDevice, isContextLost: () => boolean, width: number, height: number, maskFormat: GPUTextureFormat) => {
|
|
4
|
+
render: (encoder: GPUCommandEncoder, maskTexture: GPUTexture, guideTexture: GPUTexture, params: JointBilateralFilterParams) => GPUTexture;
|
|
5
|
+
release: () => void;
|
|
6
|
+
};
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { makeShaderDataDefinitions, makeStructuredView } from 'webgpu-utils';
|
|
2
|
+
import { assert } from '@pexip/utils';
|
|
3
|
+
import { RENDERING_EVENTS } from '../../constants';
|
|
4
|
+
import jointBilateralFilterHorizontalShader from './shaders/jointBilateralFilterHorizontal.wgsl';
|
|
5
|
+
import jointBilateralFilterVerticalShader from './shaders/jointBilateralFilterVertical.wgsl';
|
|
6
|
+
import { updateTextureStorageFormat } from './webgpuUtils';
|
|
7
|
+
export const createJointBilateralFilterRenderer = (processor, device, isContextLost, width, height, maskFormat) => {
|
|
8
|
+
// Dispatch workgroups based on the shader's workgroup size (64x4)
|
|
9
|
+
const TILE_W = 32;
|
|
10
|
+
const TILE_ROWS = 4;
|
|
11
|
+
const TILE_H = 32;
|
|
12
|
+
const TILE_COLS = 4;
|
|
13
|
+
// Create intermediate texture for the filtered result
|
|
14
|
+
const tempTexture = device.createTexture({
|
|
15
|
+
label: 'Joint Bilateral Filtered temporary mask texture',
|
|
16
|
+
format: maskFormat,
|
|
17
|
+
size: [width, height],
|
|
18
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,
|
|
19
|
+
});
|
|
20
|
+
const outputTexture = device.createTexture({
|
|
21
|
+
label: 'Joint Bilateral Filtered Mask Texture',
|
|
22
|
+
format: maskFormat,
|
|
23
|
+
size: [width, height],
|
|
24
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,
|
|
25
|
+
});
|
|
26
|
+
const defs = makeShaderDataDefinitions(jointBilateralFilterHorizontalShader);
|
|
27
|
+
// @ts-expect-error This is what we get from the API
|
|
28
|
+
const uniforms = makeStructuredView(defs.uniforms.params);
|
|
29
|
+
// Create params buffer
|
|
30
|
+
const paramsBuffer = device.createBuffer({
|
|
31
|
+
size: uniforms.arrayBuffer.byteLength,
|
|
32
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
33
|
+
});
|
|
34
|
+
const scaleFactor = width / processor.width;
|
|
35
|
+
const texelWidth = 1 / width;
|
|
36
|
+
const texelHeight = 1 / height;
|
|
37
|
+
uniforms.set({
|
|
38
|
+
width,
|
|
39
|
+
height,
|
|
40
|
+
texelWidth,
|
|
41
|
+
texelHeight,
|
|
42
|
+
});
|
|
43
|
+
const updateParams = (params) => {
|
|
44
|
+
uniforms.set({
|
|
45
|
+
...params,
|
|
46
|
+
sigmaSpace: params.sigmaSpace * scaleFactor,
|
|
47
|
+
});
|
|
48
|
+
device.queue.writeBuffer(paramsBuffer, 0, uniforms.arrayBuffer);
|
|
49
|
+
};
|
|
50
|
+
// Generate shader code with appropriate format
|
|
51
|
+
const shaderHCode = updateTextureStorageFormat(jointBilateralFilterHorizontalShader, maskFormat);
|
|
52
|
+
const shaderVCode = updateTextureStorageFormat(jointBilateralFilterVerticalShader, maskFormat);
|
|
53
|
+
// Cache shader module and pipeline at init time
|
|
54
|
+
const shaderHModule = device.createShaderModule({
|
|
55
|
+
label: 'joint bilateral filter horizontal compute',
|
|
56
|
+
code: shaderHCode,
|
|
57
|
+
});
|
|
58
|
+
const shaderVModule = device.createShaderModule({
|
|
59
|
+
label: 'joint bilateral filter vertical compute',
|
|
60
|
+
code: shaderVCode,
|
|
61
|
+
});
|
|
62
|
+
const computeHPipeline = device.createComputePipeline({
|
|
63
|
+
label: 'joint bilateral filter horizontal pipeline',
|
|
64
|
+
layout: 'auto',
|
|
65
|
+
compute: { module: shaderHModule },
|
|
66
|
+
});
|
|
67
|
+
const computeVPipeline = device.createComputePipeline({
|
|
68
|
+
label: 'joint bilateral filter vertical pipeline',
|
|
69
|
+
layout: 'auto',
|
|
70
|
+
compute: { module: shaderVModule },
|
|
71
|
+
});
|
|
72
|
+
const uniformsHBindGroups = device.createBindGroup({
|
|
73
|
+
layout: computeHPipeline.getBindGroupLayout(1),
|
|
74
|
+
entries: [
|
|
75
|
+
{ binding: 0, resource: { buffer: paramsBuffer } },
|
|
76
|
+
{ binding: 1, resource: tempTexture.createView() },
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
const uniformsVBindGroups = device.createBindGroup({
|
|
80
|
+
layout: computeVPipeline.getBindGroupLayout(1),
|
|
81
|
+
entries: [
|
|
82
|
+
{ binding: 0, resource: { buffer: paramsBuffer } },
|
|
83
|
+
{ binding: 1, resource: outputTexture.createView() },
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
const compute = (label, encoder, pipeline, bindGroup0, bindGroup1, workgroupCountX, workgroupCountY) => {
|
|
87
|
+
const computePass = encoder.beginComputePass({ label });
|
|
88
|
+
computePass.setPipeline(pipeline);
|
|
89
|
+
computePass.setBindGroup(0, bindGroup0);
|
|
90
|
+
computePass.setBindGroup(1, bindGroup1);
|
|
91
|
+
computePass.dispatchWorkgroups(workgroupCountX, workgroupCountY);
|
|
92
|
+
computePass.end();
|
|
93
|
+
};
|
|
94
|
+
const wgCntXH = Math.ceil(width / TILE_W);
|
|
95
|
+
const wgCntYH = Math.ceil(height / TILE_ROWS);
|
|
96
|
+
const wgCntXV = Math.ceil(width / TILE_COLS);
|
|
97
|
+
const wgCntYV = Math.ceil(height / TILE_H);
|
|
98
|
+
let cacheMaskTexture = null;
|
|
99
|
+
let cacheGuideTexture = null;
|
|
100
|
+
let cacheBindGroupH = null;
|
|
101
|
+
let cacheBindGroupV = null;
|
|
102
|
+
const cache = {
|
|
103
|
+
sigmaSpace: -1,
|
|
104
|
+
sigmaRangeLo: -1,
|
|
105
|
+
sigmaRangeHi: -1,
|
|
106
|
+
backgroundThreshold: -1,
|
|
107
|
+
foregroundThreshold: -1,
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
render: (encoder, maskTexture, guideTexture, params) => {
|
|
111
|
+
assert(!isContextLost(), RENDERING_EVENTS.ContextLost);
|
|
112
|
+
if (!(cache.sigmaSpace === params.sigmaSpace &&
|
|
113
|
+
cache.sigmaRangeLo === params.sigmaRangeLo &&
|
|
114
|
+
cache.sigmaRangeHi === params.sigmaRangeHi &&
|
|
115
|
+
cache.backgroundThreshold === params.backgroundThreshold &&
|
|
116
|
+
cache.foregroundThreshold === params.foregroundThreshold)) {
|
|
117
|
+
updateParams(params);
|
|
118
|
+
cache.sigmaSpace = params.sigmaSpace;
|
|
119
|
+
cache.sigmaRangeLo = params.sigmaRangeLo;
|
|
120
|
+
cache.sigmaRangeHi = params.sigmaRangeHi;
|
|
121
|
+
cache.backgroundThreshold = params.backgroundThreshold;
|
|
122
|
+
cache.foregroundThreshold = params.foregroundThreshold;
|
|
123
|
+
}
|
|
124
|
+
// Horizontal
|
|
125
|
+
if (cacheMaskTexture !== maskTexture ||
|
|
126
|
+
cacheGuideTexture !== guideTexture) {
|
|
127
|
+
cacheBindGroupH = device.createBindGroup({
|
|
128
|
+
layout: computeHPipeline.getBindGroupLayout(0),
|
|
129
|
+
entries: [
|
|
130
|
+
{ binding: 0, resource: maskTexture.createView() },
|
|
131
|
+
{ binding: 1, resource: guideTexture.createView() },
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
cacheMaskTexture = maskTexture;
|
|
135
|
+
}
|
|
136
|
+
// Horizontal pipeline
|
|
137
|
+
compute('Joint Bilateral Filter Horizontal pass', encoder, computeHPipeline, cacheBindGroupH, uniformsHBindGroups, wgCntXH, wgCntYH);
|
|
138
|
+
// Vertical
|
|
139
|
+
if (cacheGuideTexture !== guideTexture) {
|
|
140
|
+
cacheBindGroupV = device.createBindGroup({
|
|
141
|
+
layout: computeVPipeline.getBindGroupLayout(0),
|
|
142
|
+
entries: [
|
|
143
|
+
{ binding: 0, resource: tempTexture.createView() },
|
|
144
|
+
{ binding: 1, resource: guideTexture.createView() },
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
cacheGuideTexture = guideTexture;
|
|
148
|
+
}
|
|
149
|
+
compute('Joint Bilateral Filter Vertical pass', encoder, computeVPipeline, cacheBindGroupV, uniformsVBindGroups, wgCntXV, wgCntYV);
|
|
150
|
+
return outputTexture;
|
|
151
|
+
},
|
|
152
|
+
release: () => {
|
|
153
|
+
tempTexture.destroy();
|
|
154
|
+
outputTexture.destroy();
|
|
155
|
+
paramsBuffer.destroy();
|
|
156
|
+
cacheMaskTexture = null;
|
|
157
|
+
cacheGuideTexture = null;
|
|
158
|
+
cacheBindGroupH = null;
|
|
159
|
+
cacheBindGroupV = null;
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
};
|