const model = bodySegmentation.SupportedModels.MediaPipeSelfieSegmentation;
const segmenterConfig = {
solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@1.0.2'
const segmentationConfig = { flipHorizontal: false, landscape: true };
function maskShaderSource() {
attribute vec3 aPosition;
attribute vec2 aTexCoord;
attribute vec4 aVertexColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);
gl_Position = uProjectionMatrix * viewModelPosition;
uniform sampler2D content;
gl_FragColor = vec4(texture2D(content, vTexCoord).xyz, 1.) * smoothstep(0.3, 0.9, texture2D(mask, vTexCoord).x);
createCanvas(800, 800, WEBGL)
const isMobile = window.navigator.userAgent && /Mobi|Android/i.test(window.navigator.userAgent)
cam = createCapture(isMobile ? {
} : VIDEO, { flipped: !isMobile })
fboSize = { width: 800, height: 800 }
captureData = createGraphics(fboSize.width, fboSize.height)
maskData = createGraphics(fboSize.width, fboSize.height)
prevMaskData = createGraphics(fboSize.width, fboSize.height)
fbo = createFramebuffer(fboSize)
maskShader = createShader(...maskShaderSource())
segmenter = await bodySegmentation.createSegmenter(model, segmenterConfig)
captureData.image(cam, 0, 0, fboSize.width, fboSize.height, 0, 0, cam.width, cam.height, COVER)
segmenter.segmentPeople(captureData.elt, segmentationConfig).then((res) => {
return res[0].mask.toImageData()
prevMaskData.image(maskData, 0, 0)
maskData.drawingContext.putImageData(img, 0, 0)
maskShader.setUniform('content', captureData)
maskShader.setUniform('mask', maskData)
plane(fboSize.width, fboSize.height)
bg.draw(() => image(cam, 0, 0, fboSize.width, fboSize.height, 0, 0, cam.width, cam.height, COVER))
fg.draw(() => image(fbo, 0, 0))
function mouseClicked() {