@pexip/media-processor 17.3.0 → 18.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 +45 -0
- package/dist/common/backends/webgl/blender.d.ts +11 -0
- package/dist/common/backends/webgl/blender.js +104 -0
- package/dist/common/backends/webgl/blur.d.ts +5 -0
- package/dist/common/backends/webgl/blur.js +153 -0
- package/dist/common/backends/webgl/canvas.d.ts +5 -0
- package/dist/common/backends/webgl/canvas.js +77 -0
- package/dist/common/backends/webgl/renderer.d.ts +8 -0
- package/dist/common/backends/webgl/renderer.js +126 -0
- package/dist/common/backends/webgl/shaders/blendFragmentShader.d.ts +1 -0
- package/dist/common/backends/webgl/shaders/blendFragmentShader.js +63 -0
- package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.d.ts +1 -0
- package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.js +45 -0
- package/dist/common/backends/webgl/shaders/textureFragmentShader.d.ts +1 -0
- package/dist/common/backends/webgl/shaders/textureFragmentShader.js +16 -0
- package/dist/common/backends/webgl/shaders/vertexShader.d.ts +1 -0
- package/dist/common/backends/webgl/shaders/vertexShader.js +19 -0
- package/dist/common/backends/webgl/texture.d.ts +6 -0
- package/dist/common/backends/webgl/texture.js +94 -0
- package/dist/common/backends/webgl/types.d.ts +5 -0
- package/dist/common/backends/webgl/types.js +1 -0
- package/dist/common/backends/webgl/webgl.mock.js +8 -0
- package/dist/common/backends/webgl/webglUtils.d.ts +80 -0
- package/dist/common/backends/webgl/webglUtils.js +194 -0
- package/dist/common/canvasRenderUtils.d.ts +62 -0
- package/dist/{main/video → common}/canvasRenderUtils.js +100 -61
- package/dist/common/constants.d.ts +27 -0
- package/dist/common/constants.js +23 -0
- package/dist/common/index.d.ts +9 -0
- package/dist/common/index.js +9 -0
- package/dist/common/m3.d.ts +17 -0
- package/dist/common/m3.js +69 -0
- package/dist/common/tsconfig.tsbuildinfo +1 -0
- package/dist/common/types/media.d.ts +22 -0
- package/dist/common/types/media.js +1 -0
- package/dist/common/types/messageEvents.d.ts +31 -0
- package/dist/common/types/messageEvents.js +1 -0
- package/dist/common/types/processor.d.ts +15 -0
- package/dist/common/types/processor.js +1 -0
- package/dist/common/types/render.d.ts +38 -0
- package/dist/common/types/render.js +1 -0
- package/dist/common/types/segmentation.d.ts +99 -0
- package/dist/common/types/segmentation.js +4 -0
- package/dist/common/types/utils.d.ts +19 -0
- package/dist/common/types/utils.js +1 -0
- package/dist/common/utils.d.ts +35 -0
- package/dist/common/utils.js +129 -0
- package/dist/main/benchUtils.d.ts +3 -2
- package/dist/main/benchUtils.js +7 -6
- package/dist/main/index.d.ts +2 -0
- package/dist/main/index.js +2 -0
- package/dist/main/process.d.ts +1 -11
- package/dist/main/process.js +0 -20
- package/dist/main/tsconfig.tsbuildinfo +1 -1
- package/dist/main/types.d.ts +2 -2
- package/dist/main/video/canvasTransform.d.ts +14 -5
- package/dist/main/video/canvasTransform.js +101 -86
- package/dist/main/video/constants.d.ts +0 -6
- package/dist/main/video/constants.js +0 -6
- package/dist/main/video/index.d.ts +2 -2
- package/dist/main/video/index.js +2 -2
- package/dist/main/video/load.d.ts +0 -14
- package/dist/main/video/load.js +0 -8
- package/dist/main/video/segmenters/mediapipe.d.ts +9 -11
- package/dist/main/video/segmenters/mediapipe.js +127 -77
- package/dist/main/video/typeGuards.d.ts +0 -1
- package/dist/main/video/typeGuards.js +2 -8
- package/dist/main/video/types.d.ts +19 -61
- package/dist/main/video/types.js +1 -20
- package/dist/main/video/utils.d.ts +5 -12
- package/dist/main/video/utils.js +5 -152
- package/dist/main/video/video.js +1 -0
- package/dist/main/video/videoStreamTrackProcessor.js +7 -4
- package/dist/workers/global.d.js +0 -0
- package/dist/workers/mediaWorker.d.ts +1 -0
- package/dist/workers/mediaWorker.js +188 -0
- package/dist/workers/tsconfig.tsbuildinfo +1 -1
- package/dist/worklets/tsconfig.tsbuildinfo +1 -1
- package/package.json +23 -14
- package/dist/main/video/canvasRenderUtils.d.ts +0 -27
- package/dist/main/video/segmenters/index.d.ts +0 -1
- package/dist/main/video/segmenters/index.js +0 -1
- package/dist/workers/index.js +0 -1
- /package/dist/{workers/index.d.ts → common/backends/webgl/webgl.mock.d.ts} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const textureFragmentShaderSource = `#version 300 es
|
|
2
|
+
precision mediump float;
|
|
3
|
+
|
|
4
|
+
// Passed in from the vertex shader.
|
|
5
|
+
in vec2 v_texCoord;
|
|
6
|
+
|
|
7
|
+
// The texture.
|
|
8
|
+
uniform sampler2D u_texture;
|
|
9
|
+
|
|
10
|
+
// we need to declare an output for the fragment shader
|
|
11
|
+
out vec4 outColor;
|
|
12
|
+
|
|
13
|
+
void main() {
|
|
14
|
+
outColor = texture(u_texture, v_texCoord);
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const vertexShaderSource = "#version 300 es\n// an attribute is an input (in) to a vertex shader.\n// It will receive data from a buffer\nin vec2 a_position;\nin vec2 a_texCoord;\n\n// Used to pass in the resolution of the canvas\nuniform mat3 u_matrix;\n\n// Used to pass the texture coordinates to the fragment shader\nout vec2 v_texCoord;\n\nvoid main() {\n gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);\n\n // pass the texCoord to the fragment shader\n v_texCoord = a_texCoord;\n}\n";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const vertexShaderSource = `#version 300 es
|
|
2
|
+
// an attribute is an input (in) to a vertex shader.
|
|
3
|
+
// It will receive data from a buffer
|
|
4
|
+
in vec2 a_position;
|
|
5
|
+
in vec2 a_texCoord;
|
|
6
|
+
|
|
7
|
+
// Used to pass in the resolution of the canvas
|
|
8
|
+
uniform mat3 u_matrix;
|
|
9
|
+
|
|
10
|
+
// Used to pass the texture coordinates to the fragment shader
|
|
11
|
+
out vec2 v_texCoord;
|
|
12
|
+
|
|
13
|
+
void main() {
|
|
14
|
+
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
|
|
15
|
+
|
|
16
|
+
// pass the texCoord to the fragment shader
|
|
17
|
+
v_texCoord = a_texCoord;
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { assert } from '../../utils';
|
|
2
|
+
import { m3 } from '../../m3';
|
|
3
|
+
import { createAndSetupTexture, createGLProgram } from './webglUtils';
|
|
4
|
+
import { vertexShaderSource } from './shaders/vertexShader';
|
|
5
|
+
import { textureFragmentShaderSource } from './shaders/textureFragmentShader';
|
|
6
|
+
export const createTextureRenderer = (processor) => {
|
|
7
|
+
const { gl, program, attribLocations, uniformLocations, release } = createGLProgram(processor, {
|
|
8
|
+
attribs: {
|
|
9
|
+
position: 'a_position',
|
|
10
|
+
texCoord: 'a_texCoord',
|
|
11
|
+
},
|
|
12
|
+
uniforms: {
|
|
13
|
+
matrix: 'u_matrix',
|
|
14
|
+
texture: 'u_texture',
|
|
15
|
+
},
|
|
16
|
+
vertexSrc: vertexShaderSource,
|
|
17
|
+
fragmentSrc: textureFragmentShaderSource,
|
|
18
|
+
});
|
|
19
|
+
const vao = gl.createVertexArray();
|
|
20
|
+
gl.bindVertexArray(vao);
|
|
21
|
+
// Position
|
|
22
|
+
const positionBuffer = gl.createBuffer();
|
|
23
|
+
gl.enableVertexAttribArray(attribLocations.position);
|
|
24
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
25
|
+
gl.vertexAttribPointer(attribLocations.position, 2, gl.FLOAT, false, 0, 0);
|
|
26
|
+
// Put a unit quad in the buffer
|
|
27
|
+
gl.bufferData(gl.ARRAY_BUFFER,
|
|
28
|
+
// prettier-ignore
|
|
29
|
+
new Float32Array([
|
|
30
|
+
0, 0,
|
|
31
|
+
0, 1,
|
|
32
|
+
1, 0,
|
|
33
|
+
1, 0,
|
|
34
|
+
0, 1,
|
|
35
|
+
1, 1,
|
|
36
|
+
]), gl.STATIC_DRAW);
|
|
37
|
+
// Texture coordinates for the rectangle
|
|
38
|
+
const texCoordBuffer = gl.createBuffer();
|
|
39
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
|
|
40
|
+
gl.bufferData(gl.ARRAY_BUFFER,
|
|
41
|
+
// prettier-ignore
|
|
42
|
+
new Float32Array([
|
|
43
|
+
0, 0,
|
|
44
|
+
0, 1,
|
|
45
|
+
1, 0,
|
|
46
|
+
1, 0,
|
|
47
|
+
0, 1,
|
|
48
|
+
1, 1,
|
|
49
|
+
]), gl.STATIC_DRAW);
|
|
50
|
+
gl.enableVertexAttribArray(attribLocations.texCoord);
|
|
51
|
+
gl.vertexAttribPointer(attribLocations.texCoord, 2, gl.FLOAT, false, 0, 0);
|
|
52
|
+
const frameTexture = createAndSetupTexture(gl);
|
|
53
|
+
const outputTexture = createAndSetupTexture(gl);
|
|
54
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, processor.width, processor.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
55
|
+
const frameBuffer = gl.createFramebuffer();
|
|
56
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
57
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
|
|
58
|
+
return {
|
|
59
|
+
render: (video) => {
|
|
60
|
+
// Draw on the frame buffer
|
|
61
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
|
|
62
|
+
gl.viewport(0, 0, processor.width, processor.height);
|
|
63
|
+
gl.clearColor(0, 0, 0, 1);
|
|
64
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
65
|
+
gl.useProgram(program);
|
|
66
|
+
gl.bindVertexArray(vao);
|
|
67
|
+
// Texture Unit setup
|
|
68
|
+
gl.uniform1i(uniformLocations.texture, 0);
|
|
69
|
+
// Project, position and scale to full-size of the canvas
|
|
70
|
+
const matrix = m3.projection(1, 1, 1);
|
|
71
|
+
gl.uniformMatrix3fv(uniformLocations.matrix, false, matrix);
|
|
72
|
+
// Frame texture
|
|
73
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
74
|
+
gl.bindTexture(gl.TEXTURE_2D, frameTexture);
|
|
75
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video.frame);
|
|
76
|
+
gl.generateMipmap(gl.TEXTURE_2D);
|
|
77
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
78
|
+
assert(outputTexture);
|
|
79
|
+
return {
|
|
80
|
+
texture: outputTexture,
|
|
81
|
+
width: processor.width,
|
|
82
|
+
height: processor.height,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
release: () => {
|
|
86
|
+
gl.deleteBuffer(positionBuffer);
|
|
87
|
+
gl.deleteBuffer(texCoordBuffer);
|
|
88
|
+
gl.deleteTexture(frameTexture);
|
|
89
|
+
gl.deleteTexture(outputTexture);
|
|
90
|
+
gl.deleteVertexArray(vao);
|
|
91
|
+
release();
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { MPMask } from '../../types/segmentation';
|
|
2
|
+
import type { TextureInfo } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* WebGL Shader type enum
|
|
5
|
+
*/
|
|
6
|
+
export declare const GL_SHADER_TYPE: {
|
|
7
|
+
readonly VertexShader: 35633;
|
|
8
|
+
readonly FragmentShader: 35632;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* WebGL Shader name enum for error output
|
|
12
|
+
*/
|
|
13
|
+
export declare const GL_SHADER_NAME: {
|
|
14
|
+
readonly 35633: "VertexShader";
|
|
15
|
+
readonly 35632: "FragmentShader";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The type of WebGl shader:
|
|
19
|
+
* `WebGLRenderingContext.VERTEX_SHADER` | `WebGLRenderingContext.FRAGMENT_SHADER`
|
|
20
|
+
*/
|
|
21
|
+
export type GLShaderType = (typeof GL_SHADER_TYPE)[keyof typeof GL_SHADER_TYPE];
|
|
22
|
+
/**
|
|
23
|
+
* Brand string for type ensuring the shader source is a GLSL ES 3.00 shader
|
|
24
|
+
*/
|
|
25
|
+
type GLShaderSource = string & {
|
|
26
|
+
__glShaderSource: true;
|
|
27
|
+
};
|
|
28
|
+
type Release = () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Ensure the shader source is WebGL2's shader language aka GLSL ES 3.00
|
|
31
|
+
*/
|
|
32
|
+
export declare const isShaderSource: (src: unknown) => src is GLShaderSource;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure the shader source is WebGL2's shader language aka GLSL ES 3.00
|
|
35
|
+
*/
|
|
36
|
+
export declare const assertShaderSource: (src: unknown) => asserts src is GLShaderSource;
|
|
37
|
+
/**
|
|
38
|
+
* Load a shader
|
|
39
|
+
* @param gl - WebGLRenderingContext
|
|
40
|
+
* @param shaderType - The type of shader to load {@link GL_SHADER_TYPE}
|
|
41
|
+
* @param shaderSource - The source of the shader
|
|
42
|
+
*/
|
|
43
|
+
export declare const loadShader: (gl: WebGLRenderingContext, shaderType: GLShaderType, shaderSource: GLShaderSource) => WebGLShader;
|
|
44
|
+
/**
|
|
45
|
+
* Create a WebGL program from 2 provided shaders
|
|
46
|
+
* @param gl - WebGLRenderingContext
|
|
47
|
+
* @param shaders - The shader tuple of `[vertexShader, fragmentShader]`
|
|
48
|
+
* @param attribs - An array of attribs names.
|
|
49
|
+
* Locations will be assigned by index if not passed in.
|
|
50
|
+
* @param locations - The locations for the attribs.
|
|
51
|
+
* A parallel array to opt_attribs letting you assign locations.
|
|
52
|
+
*/
|
|
53
|
+
export declare const createProgram: (gl: WebGLRenderingContext, shaders: [WebGLShader, WebGLShader], attribs?: string[], locations?: number[]) => [WebGLProgram, Release];
|
|
54
|
+
/**
|
|
55
|
+
* Create a WebGL program from 2 sources
|
|
56
|
+
* @param gl - WebGLRenderingContext
|
|
57
|
+
* @param shaderSources - The shader source tuple of `[vertexShaderSource, fragmentShaderSource]`
|
|
58
|
+
* @param attribs - An array of attribs names.
|
|
59
|
+
* Locations will be assigned by index if not passed in.
|
|
60
|
+
* @param locations - The locations for the attribs.
|
|
61
|
+
* A parallel array to opt_attribs letting you assign locations.
|
|
62
|
+
*/
|
|
63
|
+
export declare const createProgramFromSources: (gl: WebGLRenderingContext, [vs, fs]: [GLShaderSource, GLShaderSource], attribs?: string[], locations?: number[]) => [WebGLProgram, Release];
|
|
64
|
+
export declare const createAndSetupTexture: (gl: WebGL2RenderingContext) => WebGLTexture | null;
|
|
65
|
+
type Location<S extends string> = S extends `u_${string}` ? ReturnType<WebGL2RenderingContext['getUniformLocation']> : S extends `a_${string}` ? ReturnType<WebGL2RenderingContext['getAttribLocation']> : never;
|
|
66
|
+
export declare const getLocations: <T extends Record<string, string>>(gl: WebGL2RenderingContext, program: WebGLProgram, locations: T) => { [Key in keyof T]: Location<T[Key]>; };
|
|
67
|
+
export declare const createGLProgram: <A extends Record<string, string>, U extends Record<string, string>>(processCanvas: OffscreenCanvas, { attribs, uniforms, vertexSrc, fragmentSrc, }: {
|
|
68
|
+
attribs: A;
|
|
69
|
+
uniforms: U;
|
|
70
|
+
vertexSrc: string;
|
|
71
|
+
fragmentSrc: string;
|
|
72
|
+
}) => {
|
|
73
|
+
gl: WebGL2RenderingContext;
|
|
74
|
+
program: WebGLProgram;
|
|
75
|
+
attribLocations: { [Key in keyof A]: Location<A[Key]>; };
|
|
76
|
+
uniformLocations: { [Key_1 in keyof U]: Location<U[Key_1]>; };
|
|
77
|
+
release: Release;
|
|
78
|
+
};
|
|
79
|
+
export declare const toTextureInfo: (mask: MPMask) => TextureInfo;
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGL Shader type enum
|
|
3
|
+
*/
|
|
4
|
+
export const GL_SHADER_TYPE = {
|
|
5
|
+
VertexShader: WebGLRenderingContext.VERTEX_SHADER,
|
|
6
|
+
FragmentShader: WebGLRenderingContext.FRAGMENT_SHADER,
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* WebGL Shader name enum for error output
|
|
10
|
+
*/
|
|
11
|
+
export const GL_SHADER_NAME = {
|
|
12
|
+
[GL_SHADER_TYPE.VertexShader]: 'VertexShader',
|
|
13
|
+
[GL_SHADER_TYPE.FragmentShader]: 'FragmentShader',
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Ensure the shader source is WebGL2's shader language aka GLSL ES 3.00
|
|
17
|
+
*/
|
|
18
|
+
export const isShaderSource = (src) => {
|
|
19
|
+
if (typeof src === 'string') {
|
|
20
|
+
return src.startsWith('#version 300 es');
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Ensure the shader source is WebGL2's shader language aka GLSL ES 3.00
|
|
26
|
+
*/
|
|
27
|
+
export const assertShaderSource = src => {
|
|
28
|
+
if (!isShaderSource(src)) {
|
|
29
|
+
throw new Error('Expecting GLSL ES 3.00 shader source');
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const errorRE = /ERROR:\s*\d+:(\d+)/gi;
|
|
33
|
+
function addLineNumbersWithError(src, log = '', lineOffset = 0) {
|
|
34
|
+
// Note: Error message formats are not defined by any spec so this may or may not work.
|
|
35
|
+
const matches = [...log.matchAll(errorRE)];
|
|
36
|
+
const lineNoToErrorMap = new Map(matches.map((m, ndx) => {
|
|
37
|
+
if (!m[1] || m.index === undefined) {
|
|
38
|
+
return [0, log];
|
|
39
|
+
}
|
|
40
|
+
const lineNo = parseInt(m[1], 10);
|
|
41
|
+
const next = matches[ndx + 1];
|
|
42
|
+
const end = next ? next.index : log.length;
|
|
43
|
+
const msg = log.substring(m.index, end);
|
|
44
|
+
return [lineNo - 1, msg];
|
|
45
|
+
}));
|
|
46
|
+
return src
|
|
47
|
+
.split('\n')
|
|
48
|
+
.map((line, lineNo) => {
|
|
49
|
+
const err = lineNoToErrorMap.get(lineNo);
|
|
50
|
+
return `${lineNo + 1 + lineOffset}: ${line}${err ? `\n\n^^^ ${err}` : ''}`;
|
|
51
|
+
})
|
|
52
|
+
.join('\n');
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load a shader
|
|
56
|
+
* @param gl - WebGLRenderingContext
|
|
57
|
+
* @param shaderType - The type of shader to load {@link GL_SHADER_TYPE}
|
|
58
|
+
* @param shaderSource - The source of the shader
|
|
59
|
+
*/
|
|
60
|
+
export const loadShader = (gl, shaderType, shaderSource) => {
|
|
61
|
+
// Create the shader object
|
|
62
|
+
const shader = gl.createShader(shaderType);
|
|
63
|
+
if (!shader) {
|
|
64
|
+
throw new Error(`Unable to create ${GL_SHADER_NAME[shaderType]}`);
|
|
65
|
+
}
|
|
66
|
+
// Load the shader source
|
|
67
|
+
gl.shaderSource(shader, shaderSource);
|
|
68
|
+
// Compile the shader
|
|
69
|
+
gl.compileShader(shader);
|
|
70
|
+
// Check the compile status
|
|
71
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getShaderParameter#gl.compile_status
|
|
72
|
+
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
|
73
|
+
if (!compiled) {
|
|
74
|
+
// Something went wrong during compilation; get the error
|
|
75
|
+
const lastError = gl.getShaderInfoLog(shader);
|
|
76
|
+
gl.deleteShader(shader);
|
|
77
|
+
const message = `Error compiling ${GL_SHADER_NAME[shaderType]}: ${lastError ?? ''}\n${lastError ? addLineNumbersWithError(shaderSource, lastError) : 'no error message available'}`;
|
|
78
|
+
throw new Error(message);
|
|
79
|
+
}
|
|
80
|
+
return shader;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Create a WebGL program from 2 provided shaders
|
|
84
|
+
* @param gl - WebGLRenderingContext
|
|
85
|
+
* @param shaders - The shader tuple of `[vertexShader, fragmentShader]`
|
|
86
|
+
* @param attribs - An array of attribs names.
|
|
87
|
+
* Locations will be assigned by index if not passed in.
|
|
88
|
+
* @param locations - The locations for the attribs.
|
|
89
|
+
* A parallel array to opt_attribs letting you assign locations.
|
|
90
|
+
*/
|
|
91
|
+
export const createProgram = (gl, shaders, attribs, locations) => {
|
|
92
|
+
const program = gl.createProgram();
|
|
93
|
+
if (!program) {
|
|
94
|
+
throw new Error('Unable to create WebGL program');
|
|
95
|
+
}
|
|
96
|
+
shaders.forEach(function (shader) {
|
|
97
|
+
gl.attachShader(program, shader);
|
|
98
|
+
});
|
|
99
|
+
attribs?.forEach(function (attrib, ndx) {
|
|
100
|
+
const locationIdx = locations?.[ndx] ?? ndx;
|
|
101
|
+
gl.bindAttribLocation(program, locationIdx, attrib);
|
|
102
|
+
});
|
|
103
|
+
gl.linkProgram(program);
|
|
104
|
+
// Check the link status
|
|
105
|
+
const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
|
|
106
|
+
if (!linked) {
|
|
107
|
+
// something went wrong with the link
|
|
108
|
+
const lastError = gl.getProgramInfoLog(program);
|
|
109
|
+
gl.deleteProgram(program);
|
|
110
|
+
throw new Error(`Error in program linking: ${lastError ?? ''}\n${shaders
|
|
111
|
+
.map(shader => {
|
|
112
|
+
const src = addLineNumbersWithError(gl.getShaderSource(shader) ?? '');
|
|
113
|
+
const shaderType = gl.getShaderParameter(shader, gl.SHADER_TYPE);
|
|
114
|
+
return `${GL_SHADER_NAME[shaderType]}:\n${src}`;
|
|
115
|
+
})
|
|
116
|
+
.join('\n')}`);
|
|
117
|
+
}
|
|
118
|
+
return [
|
|
119
|
+
program,
|
|
120
|
+
() => {
|
|
121
|
+
shaders.forEach(shader => {
|
|
122
|
+
gl.detachShader(program, shader);
|
|
123
|
+
gl.deleteShader(shader);
|
|
124
|
+
});
|
|
125
|
+
gl.deleteProgram(program);
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Create a WebGL program from 2 sources
|
|
131
|
+
* @param gl - WebGLRenderingContext
|
|
132
|
+
* @param shaderSources - The shader source tuple of `[vertexShaderSource, fragmentShaderSource]`
|
|
133
|
+
* @param attribs - An array of attribs names.
|
|
134
|
+
* Locations will be assigned by index if not passed in.
|
|
135
|
+
* @param locations - The locations for the attribs.
|
|
136
|
+
* A parallel array to opt_attribs letting you assign locations.
|
|
137
|
+
*/
|
|
138
|
+
export const createProgramFromSources = (gl, [vs, fs], attribs, locations) => createProgram(gl, [
|
|
139
|
+
loadShader(gl, GL_SHADER_TYPE.VertexShader, vs),
|
|
140
|
+
loadShader(gl, GL_SHADER_TYPE.FragmentShader, fs),
|
|
141
|
+
], attribs, locations);
|
|
142
|
+
export const createAndSetupTexture = (gl) => {
|
|
143
|
+
const texture = gl.createTexture();
|
|
144
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
145
|
+
// Set the parameters so we don't need mips and so we're not filtering
|
|
146
|
+
// and we don't repeat at the edges.
|
|
147
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
148
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
149
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
150
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
151
|
+
return texture;
|
|
152
|
+
};
|
|
153
|
+
export const getLocations = (gl, program, locations) => Object.keys(locations).reduce((acc, key) => {
|
|
154
|
+
const k = key;
|
|
155
|
+
const location = locations[k];
|
|
156
|
+
if (!location) {
|
|
157
|
+
return acc;
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
...acc,
|
|
161
|
+
[key]: location.startsWith('u_')
|
|
162
|
+
? gl.getUniformLocation(program, location)
|
|
163
|
+
: gl.getAttribLocation(program, location),
|
|
164
|
+
};
|
|
165
|
+
}, {});
|
|
166
|
+
export const createGLProgram = (processCanvas, { attribs, uniforms, vertexSrc, fragmentSrc, }) => {
|
|
167
|
+
const gl = processCanvas.getContext('webgl2', {
|
|
168
|
+
premultipliedAlpha: false,
|
|
169
|
+
});
|
|
170
|
+
if (!gl) {
|
|
171
|
+
throw new Error('WebGL2 is not supported');
|
|
172
|
+
}
|
|
173
|
+
gl.enable(gl.BLEND);
|
|
174
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
175
|
+
assertShaderSource(vertexSrc);
|
|
176
|
+
assertShaderSource(fragmentSrc);
|
|
177
|
+
const [program, release] = createProgramFromSources(gl, [
|
|
178
|
+
vertexSrc,
|
|
179
|
+
fragmentSrc,
|
|
180
|
+
]);
|
|
181
|
+
return {
|
|
182
|
+
gl,
|
|
183
|
+
program,
|
|
184
|
+
attribLocations: getLocations(gl, program, attribs),
|
|
185
|
+
uniformLocations: getLocations(gl, program, uniforms),
|
|
186
|
+
release,
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
export const toTextureInfo = (mask) => ({
|
|
190
|
+
texture: mask.getAsWebGLTexture(),
|
|
191
|
+
width: mask.width,
|
|
192
|
+
height: mask.height,
|
|
193
|
+
});
|
|
194
|
+
/* eslint-enable max-params --- this is utils */
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Segmentation } from './types/media';
|
|
2
|
+
interface InternalCanvases {
|
|
3
|
+
drawImageDataCanvas?: OffscreenCanvas;
|
|
4
|
+
maskCanvas?: OffscreenCanvas;
|
|
5
|
+
blurredMaskCanvas?: OffscreenCanvas;
|
|
6
|
+
blurredCanvas?: OffscreenCanvas;
|
|
7
|
+
downScaledCanvas?: OffscreenCanvas;
|
|
8
|
+
backgroundImageCanvas?: OffscreenCanvas;
|
|
9
|
+
inputCanvas?: OffscreenCanvas;
|
|
10
|
+
}
|
|
11
|
+
export interface Point {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
export interface Size {
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
export type Rect = Point & Size;
|
|
20
|
+
/**
|
|
21
|
+
* Context Attributes
|
|
22
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext}
|
|
23
|
+
*/
|
|
24
|
+
interface CanvasRenderingContext2DOptions {
|
|
25
|
+
alpha?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const getCanvasRenderingContext2D: (canvas: OffscreenCanvas, options?: CanvasRenderingContext2DOptions) => OffscreenCanvasRenderingContext2D;
|
|
28
|
+
export declare const flipCanvasHorizontal: (canvas: OffscreenCanvas) => void;
|
|
29
|
+
export declare const getImageSize: (image: CanvasImageSource) => Size;
|
|
30
|
+
/**
|
|
31
|
+
* Create an OffscreenCanvas with provided width and height. When
|
|
32
|
+
* OffscreenCanvas is not available, a Canvas element is returned.
|
|
33
|
+
*
|
|
34
|
+
* @param width - canvas.width
|
|
35
|
+
* @param height - canvas.height
|
|
36
|
+
*/
|
|
37
|
+
export declare const createOffscreenCanvas: (width: number, height: number) => OffscreenCanvas;
|
|
38
|
+
/**
|
|
39
|
+
* Compare the provided width and height to see if they are the same
|
|
40
|
+
*
|
|
41
|
+
* @param widthA - The width of A
|
|
42
|
+
* @param heightA - The height of A
|
|
43
|
+
* @param widthB - The width of B
|
|
44
|
+
* @param heightB - The height of B
|
|
45
|
+
*/
|
|
46
|
+
export declare const isEqualSize: (widthA: number, heightA: number, widthB: number, heightB: number) => boolean;
|
|
47
|
+
export declare const clearCanvas: (canvas: OffscreenCanvas) => void;
|
|
48
|
+
export declare const createCanvasRenderUtils: (processingWidth: number, processingHeight: number) => {
|
|
49
|
+
evaluateInput: (inputImage: CanvasImageSource) => OffscreenCanvas;
|
|
50
|
+
renderImageToCanvas: (image: CanvasImageSource, canvas: OffscreenCanvas, dw?: number, dh?: number, options?: CanvasRenderingContext2DOptions) => void;
|
|
51
|
+
drawBlurEffect: (canvas: OffscreenCanvas, inputImage: CanvasImageSource, segmentations: Segmentation | Segmentation[], foregroundThreshold?: number, backgroundBlurAmount?: number, edgeBlurAmount?: number, flipHorizontal?: boolean) => void;
|
|
52
|
+
drawOverlayEffect: (canvas: OffscreenCanvas, inputImage: CanvasImageSource, backgroundImage: CanvasImageSource | OffscreenCanvas, segmentations: Segmentation | Segmentation[], foregroundThreshold?: number, backgroundBlurAmount?: number, edgeBlurAmount?: number, flipHorizontal?: boolean) => void;
|
|
53
|
+
renderImageToOffScreenCanvas: (image: CanvasImageSource, canvasName: keyof InternalCanvases) => OffscreenCanvas;
|
|
54
|
+
renderImageDataToOffScreenCanvas: (image: ImageData, canvasName: keyof InternalCanvases) => OffscreenCanvas;
|
|
55
|
+
drawAndBlurImageOnOffScreenCanvas: ({ image, blurAmount, offscreenCanvasName, preserveOldDrawing, }: {
|
|
56
|
+
image: CanvasImageSource;
|
|
57
|
+
blurAmount: number;
|
|
58
|
+
offscreenCanvasName: keyof InternalCanvases;
|
|
59
|
+
preserveOldDrawing?: boolean | undefined;
|
|
60
|
+
}) => OffscreenCanvas;
|
|
61
|
+
};
|
|
62
|
+
export {};
|