Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
sam2_pytorch
Commits
3af09475
Commit
3af09475
authored
Dec 05, 2025
by
luopl
Browse files
"Initial commit"
parents
Pipeline
#3140
canceled with stages
Changes
585
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2041 additions
and
0 deletions
+2041
-0
demo/frontend/src/common/components/video/effects/PixelateEffect.ts
...end/src/common/components/video/effects/PixelateEffect.ts
+89
-0
demo/frontend/src/common/components/video/effects/PixelateMaskGLEffect.ts
...c/common/components/video/effects/PixelateMaskGLEffect.ts
+145
-0
demo/frontend/src/common/components/video/effects/ReplaceGLEffect.ts
...nd/src/common/components/video/effects/ReplaceGLEffect.ts
+191
-0
demo/frontend/src/common/components/video/effects/ScopeGLEffect.ts
...tend/src/common/components/video/effects/ScopeGLEffect.ts
+174
-0
demo/frontend/src/common/components/video/effects/SobelEffect.ts
...ontend/src/common/components/video/effects/SobelEffect.ts
+88
-0
demo/frontend/src/common/components/video/effects/VibrantMaskEffect.ts
.../src/common/components/video/effects/VibrantMaskEffect.ts
+179
-0
demo/frontend/src/common/components/video/effects/shaders/Arrow.frag
...nd/src/common/components/video/effects/shaders/Arrow.frag
+207
-0
demo/frontend/src/common/components/video/effects/shaders/BackgroundBlur.frag
...mmon/components/video/effects/shaders/BackgroundBlur.frag
+45
-0
demo/frontend/src/common/components/video/effects/shaders/Burst.frag
...nd/src/common/components/video/effects/shaders/Burst.frag
+141
-0
demo/frontend/src/common/components/video/effects/shaders/Cutout.frag
...d/src/common/components/video/effects/shaders/Cutout.frag
+68
-0
demo/frontend/src/common/components/video/effects/shaders/DefaultVert.vert
.../common/components/video/effects/shaders/DefaultVert.vert
+25
-0
demo/frontend/src/common/components/video/effects/shaders/EraseForeground.frag
...mon/components/video/effects/shaders/EraseForeground.frag
+51
-0
demo/frontend/src/common/components/video/effects/shaders/Gradient.frag
...src/common/components/video/effects/shaders/Gradient.frag
+34
-0
demo/frontend/src/common/components/video/effects/shaders/NoisyMask.frag
...rc/common/components/video/effects/shaders/NoisyMask.frag
+68
-0
demo/frontend/src/common/components/video/effects/shaders/Overlay.frag
.../src/common/components/video/effects/shaders/Overlay.frag
+170
-0
demo/frontend/src/common/components/video/effects/shaders/Overlay.vert
.../src/common/components/video/effects/shaders/Overlay.vert
+26
-0
demo/frontend/src/common/components/video/effects/shaders/Pixelate.frag
...src/common/components/video/effects/shaders/Pixelate.frag
+38
-0
demo/frontend/src/common/components/video/effects/shaders/PixelateMask.frag
...common/components/video/effects/shaders/PixelateMask.frag
+62
-0
demo/frontend/src/common/components/video/effects/shaders/Replace.frag
.../src/common/components/video/effects/shaders/Replace.frag
+111
-0
demo/frontend/src/common/components/video/effects/shaders/Scope.frag
...nd/src/common/components/video/effects/shaders/Scope.frag
+129
-0
No files found.
demo/frontend/src/common/components/video/effects/PixelateEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/Pixelate.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
PixelateEffect
extends
BaseGLEffect
{
private
_blockSize
:
number
=
10.0
;
constructor
()
{
super
(
3
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
):
void
{
super
.
setupUniforms
(
gl
,
program
,
init
);
gl
.
uniform1f
(
gl
.
getUniformLocation
(
program
,
'
uBlockSize
'
),
this
.
_blockSize
);
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
if
(
!
program
)
{
return
;
}
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
const
blockSize
=
[
10
,
20
,
30
][
this
.
variant
];
// dynamic uniforms per frame
gl
.
uniform1f
(
gl
.
getUniformLocation
(
program
,
'
uBlockSize
'
),
blockSize
);
gl
.
activeTexture
(
gl
.
TEXTURE0
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_frameTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
context
.
width
,
context
.
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
context
.
frame
,
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
gl
.
pixelStorei
(
gl
.
UNPACK_FLIP_Y_WEBGL
,
true
);
// Apply shader
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
}
demo/frontend/src/common/components/video/effects/PixelateMaskGLEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/PixelateMask.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
{
preAllocateTextures
}
from
'
@/common/utils/ShaderUtils
'
;
import
{
RLEObject
,
decode
}
from
'
@/jscocotools/mask
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
PixelateMaskGLEffect
extends
BaseGLEffect
{
private
_numMasks
:
number
=
0
;
private
_numMasksUniformLocation
:
WebGLUniformLocation
|
null
=
null
;
// Must from start 1, main texture takes.
private
_masksTextureUnitStart
:
number
=
1
;
private
_maskTextures
:
WebGLTexture
[]
=
[];
constructor
()
{
super
(
3
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
):
void
{
super
.
setupUniforms
(
gl
,
program
,
init
);
this
.
_numMasksUniformLocation
=
gl
.
getUniformLocation
(
program
,
'
uNumMasks
'
);
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
this
.
_numMasks
);
// We know the max number of textures, pre-allocate 3.
this
.
_maskTextures
=
preAllocateTextures
(
gl
,
3
);
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
if
(
!
program
)
{
return
;
}
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
const
blockSize
=
[
10
,
20
,
30
][
this
.
variant
];
// dynamic uniforms per frame
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
context
.
masks
.
length
);
gl
.
uniform1f
(
gl
.
getUniformLocation
(
program
,
'
uBlockSize
'
),
blockSize
);
gl
.
activeTexture
(
gl
.
TEXTURE0
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_frameTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
context
.
width
,
context
.
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
context
.
frame
,
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
// Create and bind 2D textures for each mask
context
.
masks
.
forEach
((
mask
,
index
)
=>
{
const
decodedMask
=
decode
([
mask
.
bitmap
as
RLEObject
]);
const
maskData
=
decodedMask
.
data
as
Uint8Array
;
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_maskTextures
[
index
]);
gl
.
pixelStorei
(
gl
.
UNPACK_ALIGNMENT
,
1
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
LUMINANCE
,
context
.
height
,
context
.
width
,
0
,
gl
.
LUMINANCE
,
gl
.
UNSIGNED_BYTE
,
maskData
,
);
// dynamic uniforms per mask
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
`uMaskTexture
${
index
}
`
),
this
.
_masksTextureUnitStart
+
index
,
);
});
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
// Unbind textures
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
context
.
masks
.
forEach
((
_
,
index
)
=>
{
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
});
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
async
cleanup
():
Promise
<
void
>
{
super
.
cleanup
();
if
(
this
.
_gl
!=
null
)
{
// Delete mask textures to prevent memory leaks
this
.
_maskTextures
.
forEach
(
texture
=>
{
if
(
texture
!=
null
&&
this
.
_gl
!=
null
)
{
this
.
_gl
.
deleteTexture
(
texture
);
}
});
this
.
_maskTextures
=
[];
}
}
}
demo/frontend/src/common/components/video/effects/ReplaceGLEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
angeryIcon
from
'
@/assets/icons/angery.png
'
;
import
heartIcon
from
'
@/assets/icons/heart.png
'
;
import
whistleIcon
from
'
@/assets/icons/whistle.png
'
;
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/Replace.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
{
normalizeBounds
,
preAllocateTextures
}
from
'
@/common/utils/ShaderUtils
'
;
import
{
RLEObject
,
decode
}
from
'
@/jscocotools/mask
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
ReplaceGLEffect
extends
BaseGLEffect
{
private
_numMasks
:
number
=
0
;
private
_numMasksUniformLocation
:
WebGLUniformLocation
|
null
=
null
;
private
_bitmap
:
ImageBitmap
[]
=
[];
private
_extraTextureUnit
:
number
=
1
;
private
_extraTexture
:
WebGLTexture
|
null
=
null
;
private
_fillBg
:
number
=
0
;
private
_fillBgLocation
:
WebGLUniformLocation
|
null
=
null
;
private
_masksTextureUnitStart
:
number
=
2
;
private
_maskTextures
:
WebGLTexture
[]
=
[];
constructor
()
{
super
(
6
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
async
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
)
{
super
.
setupUniforms
(
gl
,
program
,
init
);
this
.
_extraTexture
=
gl
.
createTexture
();
this
.
_numMasksUniformLocation
=
gl
.
getUniformLocation
(
program
,
'
uNumMasks
'
);
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
this
.
_numMasks
);
this
.
_fillBgLocation
=
gl
.
getUniformLocation
(
program
,
'
uFill
'
);
gl
.
uniform1i
(
this
.
_fillBgLocation
,
this
.
_fillBg
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uEmojiTexture
'
),
this
.
_extraTextureUnit
,
);
// We know the max number of textures, pre-allocate 3.
this
.
_maskTextures
=
preAllocateTextures
(
gl
,
3
);
this
.
_bitmap
=
[];
// clear any previous pool of texture
let
response
=
await
fetch
(
angeryIcon
);
let
blob
=
await
response
.
blob
();
const
angery
=
await
createImageBitmap
(
blob
);
response
=
await
fetch
(
heartIcon
);
blob
=
await
response
.
blob
();
const
heart
=
await
createImageBitmap
(
blob
);
response
=
await
fetch
(
whistleIcon
);
blob
=
await
response
.
blob
();
const
whistle
=
await
createImageBitmap
(
blob
);
this
.
_bitmap
=
[
angery
,
heart
,
whistle
];
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
invariant
(
program
!==
null
,
'
Not WebGL program found
'
);
const
iconIndex
=
Math
.
floor
(
this
.
variant
/
2
)
%
this
.
_bitmap
.
length
;
if
(
this
.
_bitmap
===
null
)
{
return
;
}
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
// dynamic uniforms per frame
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
context
.
masks
.
length
);
gl
.
uniform1i
(
this
.
_fillBgLocation
,
this
.
variant
%
2
===
0
?
0
:
1
);
// Bind the extra texture/emoji to texture unit 1
if
(
this
.
_bitmap
.
length
)
{
gl
.
activeTexture
(
gl
.
TEXTURE0
+
this
.
_extraTextureUnit
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_extraTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
this
.
_bitmap
[
iconIndex
].
width
,
this
.
_bitmap
[
iconIndex
].
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
this
.
_bitmap
[
iconIndex
],
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_WRAP_S
,
gl
.
CLAMP_TO_EDGE
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_WRAP_T
,
gl
.
CLAMP_TO_EDGE
);
}
context
.
masks
.
forEach
((
mask
,
index
)
=>
{
const
decodedMask
=
decode
([
mask
.
bitmap
as
RLEObject
]);
const
maskData
=
decodedMask
.
data
as
Uint8Array
;
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_maskTextures
[
index
]);
const
boundaries
=
normalizeBounds
(
mask
.
bounds
[
0
],
mask
.
bounds
[
1
],
context
.
width
,
context
.
height
,
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
`uMaskTexture
${
index
}
`
),
index
+
this
.
_masksTextureUnitStart
,
);
gl
.
uniform4fv
(
gl
.
getUniformLocation
(
program
,
`bbox
${
index
}
`
),
boundaries
);
gl
.
pixelStorei
(
gl
.
UNPACK_ALIGNMENT
,
1
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
LUMINANCE
,
context
.
height
,
context
.
width
,
0
,
gl
.
LUMINANCE
,
gl
.
UNSIGNED_BYTE
,
maskData
,
);
});
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
// Unbind textures
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
context
.
masks
.
forEach
((
_
,
index
)
=>
{
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
});
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
async
cleanup
():
Promise
<
void
>
{
super
.
cleanup
();
if
(
this
.
_gl
!=
null
)
{
// Delete mask textures to prevent memory leaks
this
.
_maskTextures
.
forEach
(
texture
=>
{
if
(
texture
!=
null
&&
this
.
_gl
!=
null
)
{
this
.
_gl
.
deleteTexture
(
texture
);
}
});
this
.
_maskTextures
=
[];
}
}
}
demo/frontend/src/common/components/video/effects/ScopeGLEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
{
hexToRgb
}
from
'
@/common/components/video/editor/VideoEditorUtils
'
;
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/Scope.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
{
normalizeBounds
,
preAllocateTextures
}
from
'
@/common/utils/ShaderUtils
'
;
import
{
RLEObject
,
decode
}
from
'
@/jscocotools/mask
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
ScopeGLEffect
extends
BaseGLEffect
{
private
_numMasks
:
number
=
0
;
private
_numMasksUniformLocation
:
WebGLUniformLocation
|
null
=
null
;
// Must from start 2, main texture takes 0 and 1.
private
_masksTextureUnitStart
:
number
=
2
;
private
_maskTextures
:
WebGLTexture
[]
=
[];
constructor
()
{
super
(
6
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
):
void
{
super
.
setupUniforms
(
gl
,
program
,
init
);
this
.
_numMasksUniformLocation
=
gl
.
getUniformLocation
(
program
,
'
uNumMasks
'
);
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
this
.
_numMasks
);
// We know the max number of textures, pre-allocate 3.
this
.
_maskTextures
=
preAllocateTextures
(
gl
,
3
);
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
if
(
!
program
)
{
return
;
}
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
// dynamic uniforms per frame
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
context
.
masks
.
length
);
gl
.
activeTexture
(
gl
.
TEXTURE0
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_frameTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
context
.
width
,
context
.
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
context
.
frame
,
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
// Create and bind 2D textures for each mask
context
.
masks
.
forEach
((
mask
,
index
)
=>
{
const
decodedMask
=
decode
([
mask
.
bitmap
as
RLEObject
]);
const
maskData
=
decodedMask
.
data
as
Uint8Array
;
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_maskTextures
[
index
]);
const
boundaries
=
normalizeBounds
(
mask
.
bounds
[
0
],
mask
.
bounds
[
1
],
context
.
width
,
context
.
height
,
);
const
styleIndex
=
Math
.
floor
(
this
.
variant
/
2
)
%
2
;
// dynamic uniforms per mask
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
`uMaskTexture
${
index
}
`
),
this
.
_masksTextureUnitStart
+
index
,
);
const
color
=
hexToRgb
(
context
.
maskColors
[
index
]);
gl
.
uniform4f
(
gl
.
getUniformLocation
(
program
,
`uMaskColor
${
index
}
`
),
color
.
r
,
color
.
g
,
color
.
b
,
color
.
a
,
);
gl
.
uniform4fv
(
gl
.
getUniformLocation
(
program
,
`bbox
${
index
}
`
),
boundaries
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uFillColor
'
),
this
.
variant
%
2
===
0
?
0
:
1
,
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uLight
'
),
styleIndex
===
0
?
0
:
1
,
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uTransparency
'
),
Math
.
floor
(
this
.
variant
/
2
)
%
3
===
2
?
1
:
0
,
);
gl
.
pixelStorei
(
gl
.
UNPACK_ALIGNMENT
,
1
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
LUMINANCE
,
context
.
height
,
context
.
width
,
0
,
gl
.
LUMINANCE
,
gl
.
UNSIGNED_BYTE
,
maskData
,
);
});
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
// Unbind textures
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
context
.
masks
.
forEach
((
_
,
index
)
=>
{
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
});
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
async
cleanup
():
Promise
<
void
>
{
super
.
cleanup
();
if
(
this
.
_gl
!=
null
)
{
// Delete mask textures to prevent memory leaks
this
.
_maskTextures
.
forEach
(
texture
=>
{
if
(
texture
!=
null
&&
this
.
_gl
!=
null
)
{
this
.
_gl
.
deleteTexture
(
texture
);
}
});
this
.
_maskTextures
=
[];
}
}
}
demo/frontend/src/common/components/video/effects/SobelEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/Sobel.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
SobelEffect
extends
BaseGLEffect
{
constructor
()
{
super
(
4
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
):
void
{
super
.
setupUniforms
(
gl
,
program
,
init
);
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
if
(
!
program
)
{
return
;
}
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
const
pairIndex
=
Math
.
floor
(
this
.
variant
/
2
)
%
2
;
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uSwapColor
'
),
this
.
variant
%
2
===
0
?
1
:
0
,
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uMonocolor
'
),
pairIndex
===
0
?
0
:
1
,
);
gl
.
activeTexture
(
gl
.
TEXTURE0
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_frameTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
context
.
width
,
context
.
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
context
.
frame
,
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
}
demo/frontend/src/common/components/video/effects/VibrantMaskEffect.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
BaseGLEffect
from
'
@/common/components/video/effects/BaseGLEffect
'
;
import
{
EffectFrameContext
,
EffectInit
,
}
from
'
@/common/components/video/effects/Effect
'
;
import
vertexShaderSource
from
'
@/common/components/video/effects/shaders/DefaultVert.vert?raw
'
;
import
fragmentShaderSource
from
'
@/common/components/video/effects/shaders/VibrantMask.frag?raw
'
;
import
{
Tracklet
}
from
'
@/common/tracker/Tracker
'
;
import
{
generateLUTDATA
,
load3DLUT
,
preAllocateTextures
,
}
from
'
@/common/utils/ShaderUtils
'
;
import
{
RLEObject
,
decode
}
from
'
@/jscocotools/mask
'
;
import
invariant
from
'
invariant
'
;
import
{
CanvasForm
}
from
'
pts
'
;
export
default
class
VibrantMaskEffect
extends
BaseGLEffect
{
private
lutSize
:
number
=
4
;
private
_numMasks
:
number
=
0
;
private
_numMasksUniformLocation
:
WebGLUniformLocation
|
null
=
null
;
private
_currentFrameLocation
:
WebGLUniformLocation
|
null
=
null
;
private
_lutTextures
:
WebGLTexture
[]
=
[];
private
_maskTextures
:
WebGLTexture
[]
=
[];
// Must be 1, main background texture takes 0.
private
_extraTextureUnit
:
number
=
1
;
// Must from start 2, main texture takes 0 and 1.
private
_masksTextureUnitStart
:
number
=
2
;
constructor
()
{
super
(
3
);
this
.
vertexShaderSource
=
vertexShaderSource
;
this
.
fragmentShaderSource
=
fragmentShaderSource
;
}
protected
setupUniforms
(
gl
:
WebGL2RenderingContext
,
program
:
WebGLProgram
,
init
:
EffectInit
,
):
void
{
super
.
setupUniforms
(
gl
,
program
,
init
);
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
'
uColorGradeLUT
'
),
this
.
_extraTextureUnit
,
);
this
.
_numMasksUniformLocation
=
gl
.
getUniformLocation
(
program
,
'
uNumMasks
'
);
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
this
.
_numMasks
);
this
.
_currentFrameLocation
=
gl
.
getUniformLocation
(
program
,
'
uCurrentFrame
'
,
);
gl
.
uniform1f
(
this
.
_currentFrameLocation
,
0
);
// We know the max number of textures, pre-allocate 3.
this
.
_maskTextures
=
preAllocateTextures
(
gl
,
3
);
this
.
_lutTextures
=
[];
// clear any previous pool of textures
for
(
let
i
=
0
;
i
<
this
.
numVariants
;
i
++
)
{
const
_lutData
=
generateLUTDATA
(
this
.
lutSize
);
const
_extraTexture
=
load3DLUT
(
gl
,
this
.
lutSize
,
_lutData
);
this
.
_lutTextures
.
push
(
_extraTexture
as
WebGLTexture
);
}
}
apply
(
form
:
CanvasForm
,
context
:
EffectFrameContext
,
_tracklets
:
Tracklet
[])
{
const
gl
=
this
.
_gl
;
const
program
=
this
.
_program
;
if
(
!
program
)
{
return
;
}
invariant
(
gl
!==
null
,
'
WebGL2 context is required
'
);
gl
.
clearColor
(
0.0
,
0.0
,
0.0
,
1.0
);
gl
.
clear
(
gl
.
COLOR_BUFFER_BIT
);
// dynamic uniforms per frame
gl
.
uniform1f
(
this
.
_currentFrameLocation
,
context
.
frameIndex
);
gl
.
uniform1i
(
this
.
_numMasksUniformLocation
,
context
.
masks
.
length
);
// Bind the LUT texture to texture unit 1
const
lutTexture
=
this
.
_lutTextures
[
this
.
variant
];
gl
.
activeTexture
(
gl
.
TEXTURE1
);
gl
.
bindTexture
(
gl
.
TEXTURE_3D
,
lutTexture
);
gl
.
activeTexture
(
gl
.
TEXTURE0
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_frameTexture
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
RGBA
,
context
.
width
,
context
.
height
,
0
,
gl
.
RGBA
,
gl
.
UNSIGNED_BYTE
,
context
.
frame
,
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MIN_FILTER
,
gl
.
NEAREST
);
gl
.
texParameteri
(
gl
.
TEXTURE_2D
,
gl
.
TEXTURE_MAG_FILTER
,
gl
.
NEAREST
);
// Create and bind 2D textures for each mask
context
.
masks
.
forEach
((
mask
,
index
)
=>
{
const
decodedMask
=
decode
([
mask
.
bitmap
as
RLEObject
]);
const
maskData
=
decodedMask
.
data
as
Uint8Array
;
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
this
.
_maskTextures
[
index
]);
// dynamic uniforms per mask
gl
.
uniform1i
(
gl
.
getUniformLocation
(
program
,
`uMaskTexture
${
index
}
`
),
this
.
_masksTextureUnitStart
+
index
,
);
gl
.
pixelStorei
(
gl
.
UNPACK_ALIGNMENT
,
1
);
gl
.
texImage2D
(
gl
.
TEXTURE_2D
,
0
,
gl
.
LUMINANCE
,
context
.
height
,
context
.
width
,
0
,
gl
.
LUMINANCE
,
gl
.
UNSIGNED_BYTE
,
maskData
,
);
});
gl
.
drawArrays
(
gl
.
TRIANGLE_STRIP
,
0
,
4
);
// Unbind textures
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
context
.
masks
.
forEach
((
_
,
index
)
=>
{
gl
.
activeTexture
(
gl
.
TEXTURE0
+
index
+
this
.
_masksTextureUnitStart
);
gl
.
bindTexture
(
gl
.
TEXTURE_2D
,
null
);
});
const
ctx
=
form
.
ctx
;
invariant
(
this
.
_canvas
!==
null
,
'
canvas is required
'
);
ctx
.
drawImage
(
this
.
_canvas
,
0
,
0
);
}
async
cleanup
():
Promise
<
void
>
{
super
.
cleanup
();
if
(
this
.
_gl
!=
null
)
{
// Delete mask textures to prevent memory leaks
this
.
_maskTextures
.
forEach
(
texture
=>
{
if
(
texture
!=
null
&&
this
.
_gl
!=
null
)
{
this
.
_gl
.
deleteTexture
(
texture
);
}
});
this
.
_maskTextures
=
[];
}
}
}
demo/frontend/src/common/components/video/effects/shaders/Arrow.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
vec2
uSize
;
uniform
int
uNumMasks
;
uniform
float
uCurrentFrame
;
uniform
bool
uLineColor
;
uniform
bool
uArrow
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
uniform
vec4
bbox0
;
uniform
vec4
bbox1
;
uniform
vec4
bbox2
;
out
vec4
fragColor
;
float
addv
(
vec2
a
)
{
return
a
.
x
+
a
.
y
;
}
#define dd(a) dot(a,a)
vec2
solveCubic2
(
vec3
a
)
{
float
p
=
a
.
y
-
a
.
x
*
a
.
x
/
3
.
0
f
;
float
p3
=
p
*
p
*
p
;
float
q
=
a
.
x
*
(
2
.
0
f
*
a
.
x
*
a
.
x
-
9
.
0
f
*
a
.
y
)
/
27
.
0
f
+
a
.
z
;
float
d
=
q
*
q
+
4
.
0
f
*
p3
/
27
.
0
f
;
if
(
d
>
0
.
0
f
)
{
vec2
x
=
(
vec2
(
1
.
0
f
,
-
1
.
0
f
)
*
sqrt
(
d
)
-
q
)
*
0
.
5
f
;
return
vec2
(
addv
(
sign
(
x
)
*
pow
(
abs
(
x
),
vec2
(
1
.
0
f
/
3
.
0
f
)))
-
a
.
x
/
3
.
0
f
);
}
float
v
=
acos
(
-
sqrt
(
-
27
.
0
f
/
p3
)
*
q
*
0
.
5
f
)
/
3
.
0
f
;
float
m
=
cos
(
v
);
float
n
=
sin
(
v
)
*
1
.
732050808
f
;
return
vec2
(
m
+
m
,
-
n
-
m
)
*
sqrt
(
-
p
/
3
.
0
f
)
-
a
.
x
/
3
.
0
f
;
}
float
calculateDistanceToQuadraticBezier
(
vec2
p
,
vec2
a
,
vec2
b
,
vec2
c
)
{
b
+=
mix
(
vec2
(
1e-4
f
),
vec2
(
0
.
0
f
),
abs
(
sign
(
b
*
2
.
0
f
-
a
-
c
)));
vec2
A
=
b
-
a
;
vec2
B
=
c
-
b
-
A
;
vec2
C
=
p
-
a
;
vec2
D
=
A
*
2
.
0
f
;
vec2
T
=
clamp
((
solveCubic2
(
vec3
(
-
3
.
0
f
*
dot
(
A
,
B
),
dot
(
C
,
B
)
-
2
.
0
f
*
dd
(
A
),
dot
(
C
,
A
))
/
-
dd
(
B
))),
0
.
0
f
,
1
.
0
f
);
return
sqrt
(
min
(
dd
(
C
-
(
D
+
B
*
T
.
x
)
*
T
.
x
),
dd
(
C
-
(
D
+
B
*
T
.
y
)
*
T
.
y
)));
}
float
crossProduct
(
vec2
a
,
vec2
b
)
{
return
a
.
x
*
b
.
y
-
a
.
y
*
b
.
x
;
}
bool
pointInTriangle
(
vec2
pt
,
vec2
v0
,
vec2
v1
,
vec2
v2
)
{
vec2
v0v1
=
v1
-
v0
;
vec2
v1v2
=
v2
-
v1
;
vec2
v2v0
=
v0
-
v2
;
float
d0
=
sign
(
crossProduct
(
v0v1
,
pt
-
v0
));
float
d1
=
sign
(
crossProduct
(
v1v2
,
pt
-
v1
));
float
d2
=
sign
(
crossProduct
(
v2v0
,
pt
-
v2
));
bool
has_neg
=
(
d0
<
0
.
0
f
)
||
(
d1
<
0
.
0
f
)
||
(
d2
<
0
.
0
f
);
bool
has_pos
=
(
d0
>
0
.
0
f
)
||
(
d1
>
0
.
0
f
)
||
(
d2
>
0
.
0
f
);
return
!
(
has_neg
&&
has_pos
);
}
void
main
()
{
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
vec2
fragCoord
=
vTexCoord
*
uSize
;
float
aspectRatio
=
uSize
.
y
/
uSize
.
x
;
float
time
=
uCurrentFrame
*
0
.
05
f
;
vec3
multicolor
=
vec3
(
0
.
5
f
+
0
.
5
f
*
sin
(
time
),
0
.
5
f
+
0
.
5
f
*
cos
(
time
),
0
.
5
f
-
0
.
5
f
*
sin
(
time
));
vec4
mask1
=
vec4
(
0
.
0
f
);
vec4
mask2
=
vec4
(
0
.
0
f
);
vec4
mask3
=
vec4
(
0
.
0
f
);
bool
scoped
=
false
;
bool
intersected
=
false
;
float
threshold
=
0
.
75
f
;
float
circleRadius
=
0
.
015
f
;
if
(
uNumMasks
>
0
)
{
mask1
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
bool
visible
=
bbox0
!=
vec4
(
0
.
0
f
);
vec2
p0
=
vec2
((
bbox0
.
x
+
bbox0
.
z
)
*
0
.
5
f
,
bbox0
.
y
);
// Top center
vec2
p1
=
vec2
(
bbox0
.
x
+
0
.
5
f
*
(
bbox0
.
z
-
bbox0
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
sin
(
time
)),
bbox0
.
y
-
0
.
25
f
);
//vec2 p1 = vec2(0.5f, 0.5f);
vec2
p2
=
vec2
(
bbox0
.
x
+
0
.
5
f
*
(
bbox0
.
z
-
bbox0
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
cos
(
time
)),
(
bbox0
.
w
+
bbox0
.
y
)
*
0
.
5
f
);
float
d
=
calculateDistanceToQuadraticBezier
(
vTexCoord
,
p0
,
p1
,
p2
);
d
*=
length
(
uSize
.
xy
)
*
0
.
25
f
;
vec2
v0
=
p0
+
vec2
(
-
0
.
020
f
,
-
0
.
020
f
);
// Left vertex
vec2
v1
=
p0
+
vec2
(
0
.
020
f
,
-
0
.
020
f
);
// Right vertex
vec2
v2
=
p0
+
vec2
(
0
.
0
f
,
0
.
020
f
);
// Bottom vertex
// Check if the point is inside the triangle
bool
inside
=
pointInTriangle
(
vTexCoord
,
v0
,
v1
,
v2
);
// Circle drawing
vec2
adjustedCoord
=
vTexCoord
-
p0
;
adjustedCoord
.
x
/=
aspectRatio
;
float
circleDistance
=
length
(
adjustedCoord
);
if
(
d
<
threshold
&&
visible
)
{
scoped
=
true
;
}
if
(
uArrow
&&
inside
&&
visible
)
{
intersected
=
true
;
}
else
if
(
!
uArrow
&&
circleDistance
<
circleRadius
&&
visible
)
{
intersected
=
true
;
}
}
if
(
uNumMasks
>
1
)
{
mask2
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
bool
visible
=
bbox1
!=
vec4
(
0
.
0
f
);
vec2
p0
=
vec2
((
bbox1
.
x
+
bbox1
.
z
)
*
0
.
5
f
,
bbox1
.
y
);
vec2
p1
=
vec2
(
bbox1
.
x
+
0
.
5
f
*
(
bbox1
.
z
-
bbox1
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
sin
(
time
)),
bbox1
.
y
-
0
.
25
f
);
vec2
p2
=
vec2
(
bbox1
.
x
+
0
.
5
f
*
(
bbox1
.
z
-
bbox1
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
cos
(
time
)),
(
bbox1
.
w
+
bbox1
.
y
)
*
0
.
5
f
);
float
d
=
calculateDistanceToQuadraticBezier
(
vTexCoord
,
p0
,
p1
,
p2
);
d
*=
length
(
uSize
.
xy
)
*
0
.
25
f
;
vec2
v0
=
p0
+
vec2
(
-
0
.
020
f
,
-
0
.
020
f
);
vec2
v1
=
p0
+
vec2
(
0
.
020
f
,
-
0
.
020
f
);
vec2
v2
=
p0
+
vec2
(
0
.
0
f
,
0
.
020
f
);
bool
inside
=
pointInTriangle
(
vTexCoord
,
v0
,
v1
,
v2
);
// Circle drawing
vec2
adjustedCoord
=
vTexCoord
-
p0
;
adjustedCoord
.
x
/=
aspectRatio
;
float
circleDistance
=
length
(
adjustedCoord
);
if
(
d
<
threshold
&&
visible
)
{
scoped
=
true
;
}
if
(
uArrow
&&
inside
&&
visible
)
{
intersected
=
true
;
}
else
if
(
!
uArrow
&&
circleDistance
<
circleRadius
&&
visible
)
{
intersected
=
true
;
}
}
if
(
uNumMasks
>
2
)
{
mask3
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
bool
visible
=
bbox2
!=
vec4
(
0
.
0
f
);
vec2
p0
=
vec2
((
bbox2
.
x
+
bbox2
.
z
)
*
0
.
5
f
,
bbox2
.
y
);
vec2
p1
=
vec2
(
bbox2
.
x
+
0
.
5
f
*
(
bbox2
.
z
-
bbox2
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
sin
(
time
)),
bbox2
.
y
-
0
.
25
f
);
vec2
p2
=
vec2
(
bbox2
.
x
+
0
.
5
f
*
(
bbox2
.
z
-
bbox2
.
x
)
*
(
0
.
5
f
+
0
.
5
f
*
cos
(
time
)),
(
bbox2
.
w
+
bbox2
.
y
)
*
0
.
5
f
);
float
d
=
calculateDistanceToQuadraticBezier
(
vTexCoord
,
p0
,
p1
,
p2
);
d
*=
length
(
uSize
.
xy
)
*
0
.
25
f
;
vec2
v0
=
p0
+
vec2
(
-
0
.
020
f
,
-
0
.
020
f
);
vec2
v1
=
p0
+
vec2
(
0
.
020
f
,
-
0
.
020
f
);
vec2
v2
=
p0
+
vec2
(
0
.
0
f
,
0
.
020
f
);
bool
inside
=
pointInTriangle
(
vTexCoord
,
v0
,
v1
,
v2
);
vec2
adjustedCoord
=
vTexCoord
-
p0
;
adjustedCoord
.
x
/=
aspectRatio
;
float
circleDistance
=
length
(
adjustedCoord
);
if
(
d
<
threshold
&&
visible
)
{
scoped
=
true
;
}
if
(
uArrow
&&
inside
&&
visible
)
{
intersected
=
true
;
}
else
if
(
!
uArrow
&&
circleDistance
<
circleRadius
&&
visible
)
{
intersected
=
true
;
}
}
bool
overlap
=
(
mask1
.
r
>
0
.
0
f
||
mask2
.
r
>
0
.
0
f
||
mask3
.
r
>
0
.
0
f
);
if
(
overlap
)
{
fragColor
=
color
;
}
if
(
scoped
||
intersected
)
{
fragColor
=
uLineColor
?
vec4
(
multicolor
,
1
.
0
f
)
:
vec4
(
1
.
0
f
);
if
(
intersected
)
{
fragColor
=
vec4
(
multicolor
,
1
.
0
f
);
}
}
else
{
fragColor
=
overlap
?
color
:
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
}
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/BackgroundBlur.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
vec2
uSize
;
uniform
int
uBlurRadius
;
out
vec4
fragColor
;
void
main
()
{
vec2
texOffset
=
1
.
0
f
/
uSize
;
// texel color
vec3
color
=
texture
(
uSampler
,
vTexCoord
).
rgb
;
float
sampleCount
=
0
.
0
f
;
// sample the surrounding pixels based on the blur radius
for
(
int
x
=
-
uBlurRadius
;
x
<=
uBlurRadius
;
x
++
)
{
for
(
int
y
=
-
uBlurRadius
;
y
<=
uBlurRadius
;
y
++
)
{
vec2
offset
=
vec2
(
float
(
x
),
float
(
y
))
*
texOffset
;
color
+=
texture
(
uSampler
,
vTexCoord
+
offset
).
rgb
;
sampleCount
+=
1
.
0
f
;
}
}
// average the colors of the sampled pixels
color
/=
sampleCount
;
fragColor
=
vec4
(
color
,
1
.
0
f
);
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Burst.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
highp
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
vec2
uSize
;
// resolution
uniform
int
uNumMasks
;
uniform
bool
uLineColor
;
uniform
bool
uInterleave
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
uniform
vec4
uMaskColor0
;
uniform
vec4
uMaskColor1
;
uniform
vec4
uMaskColor2
;
uniform
vec4
bbox0
;
uniform
vec4
bbox1
;
uniform
vec4
bbox2
;
out
vec4
fragColor
;
void
main
()
{
float
PI
=
radians
(
180
.
0
f
);
float
lines
=
uInterleave
?
12
.
0
f
:
80
.
0
f
;
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
vec4
color1
=
uMaskColor0
/
255
.
0
;
vec4
color2
=
uMaskColor1
/
255
.
0
;
vec4
color3
=
uMaskColor2
/
255
.
0
;
vec4
mask1
=
vec4
(
0
.
0
f
);
vec4
mask2
=
vec4
(
0
.
0
f
);
vec4
mask3
=
vec4
(
0
.
0
f
);
vec4
scopedColor
=
vec4
(
0
.
0
f
);
vec2
fragCoord
=
vTexCoord
*
uSize
;
// transform to pixel space
bool
scoped
=
false
;
vec4
transparent
=
vec4
(
0
.
0
);
float
p
=
PI
/
lines
;
if
(
uNumMasks
>
0
)
{
mask1
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center1
=
(
bbox0
.
xy
+
bbox0
.
zw
)
*
0
.
5
f
*
uSize
;
vec2
fragCoordT
=
(
fragCoord
-
center1
)
/
uSize
.
y
;
float
a
=
mod
(
atan
(
fragCoordT
.
y
,
fragCoordT
.
x
)
+
p
,
p
+
p
)
-
p
;
// angle of fragment
float
pattern
=
sin
(
a
*
lines
);
// smoothstep for antialiasing
float
line
=
smoothstep
(
2
.
8
/
uSize
.
y
,
0
.
0
,
length
(
fragCoordT
)
*
abs
(
sin
(
a
)));
vec4
colorToBlend
=
uLineColor
?
vec4
(
color1
.
rgb
,
0
.
80
f
)
:
vec4
(
1
.
0
f
);
bool
visible
=
bbox0
!=
vec4
(
0
.
0
f
);
if
(
uInterleave
&&
visible
)
{
vec4
tempColor
=
mix
(
transparent
,
colorToBlend
,
step
(
0
.
0
,
pattern
));
scopedColor
+=
tempColor
;
scoped
=
true
;
}
else
if
(
!
uInterleave
&&
visible
)
{
vec4
tempColor
=
uLineColor
?
vec4
(
color1
.
rgb
*
line
,
line
)
:
vec4
(
line
);
scopedColor
+=
tempColor
;
scoped
=
true
;
}
}
if
(
uNumMasks
>
1
)
{
mask2
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center2
=
(
bbox1
.
xy
+
bbox1
.
zw
)
*
0
.
5
f
*
uSize
;
vec2
fragCoordT
=
(
fragCoord
-
center2
)
/
uSize
.
y
;
float
a
=
mod
(
atan
(
fragCoordT
.
y
,
fragCoordT
.
x
)
+
p
,
p
+
p
)
-
p
;
// angle of fragment
float
pattern
=
sin
(
a
*
lines
);
float
line
=
smoothstep
(
2
.
8
/
uSize
.
y
,
0
.
0
,
length
(
fragCoordT
)
*
abs
(
sin
(
a
)));
vec4
colorToBlend
=
uLineColor
?
vec4
(
color2
.
rgb
,
0
.
8
f
)
:
vec4
(
1
.
0
f
);
bool
visible
=
bbox1
!=
vec4
(
0
.
0
f
);
if
(
uInterleave
&&
visible
)
{
vec4
tempColor
=
mix
(
transparent
,
colorToBlend
,
step
(
0
.
0
,
pattern
));
if
(
scopedColor
==
vec4
(
0
.
0
))
{
scopedColor
+=
tempColor
;
}
scoped
=
true
;
}
else
if
(
!
uInterleave
&&
visible
)
{
vec4
tempColor
=
uLineColor
?
vec4
(
color2
.
rgb
*
line
,
line
)
:
vec4
(
line
);
scopedColor
+=
tempColor
;
scoped
=
true
;
}
}
if
(
uNumMasks
>
2
)
{
mask3
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center3
=
(
bbox2
.
xy
+
bbox2
.
zw
)
*
0
.
5
f
*
uSize
;
vec2
fragCoordT
=
(
fragCoord
-
center3
)
/
uSize
.
y
;
float
a
=
mod
(
atan
(
fragCoordT
.
y
,
fragCoordT
.
x
)
+
p
,
p
+
p
)
-
p
;
// angle of fragment
float
pattern
=
sin
(
a
*
lines
);
float
line
=
smoothstep
(
2
.
8
/
uSize
.
y
,
0
.
0
,
length
(
fragCoordT
)
*
abs
(
sin
(
a
)));
vec4
colorToBlend
=
uLineColor
?
vec4
(
color3
.
rgb
,
0
.
8
f
)
:
vec4
(
1
.
0
f
);
bool
visible
=
bbox2
!=
vec4
(
0
.
0
f
);
if
(
uInterleave
&&
visible
)
{
vec4
tempColor
=
mix
(
transparent
,
colorToBlend
,
step
(
0
.
0
,
pattern
));
if
(
scopedColor
==
vec4
(
0
.
0
))
{
scopedColor
+=
tempColor
;
}
scoped
=
true
;
}
else
if
(
!
uInterleave
&&
visible
)
{
vec4
tempColor
=
uLineColor
?
vec4
(
color3
.
rgb
*
line
,
line
)
:
vec4
(
line
);
scopedColor
+=
tempColor
;
scoped
=
true
;
}
}
bool
overlap
=
(
mask1
.
r
>
0
.
0
f
||
mask2
.
r
>
0
.
0
f
||
mask3
.
r
>
0
.
0
f
);
if
(
scoped
)
{
fragColor
=
overlap
?
color
:
scopedColor
;
}
else
{
fragColor
=
overlap
?
color
:
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
}
}
demo/frontend/src/common/components/video/effects/shaders/Cutout.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
float
uContrast
;
uniform
int
uNumMasks
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
out
vec4
fragColor
;
vec3
applySepia
(
vec4
color
)
{
float
gray
=
dot
(
color
.
rgb
,
vec3
(
0
.
3
,
0
.
59
,
0
.
11
));
vec3
sepia
=
vec3
(
gray
)
*
vec3
(
1
.
2
,
1
.
0
,
0
.
8
);
sepia
.
r
=
min
(
sepia
.
r
,
1
.
0
);
sepia
.
g
=
min
(
sepia
.
g
,
1
.
0
);
sepia
.
b
=
min
(
sepia
.
b
,
1
.
0
);
return
sepia
;
}
void
main
()
{
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
vec4
color1
=
vec4
(
0
.
0
f
);
vec4
color2
=
vec4
(
0
.
0
f
);
vec4
color3
=
vec4
(
0
.
0
f
);
if
(
uNumMasks
>
0
)
{
color1
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
if
(
uNumMasks
>
1
)
{
color2
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
if
(
uNumMasks
>
2
)
{
color3
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
bool
overlap
=
(
color1
.
r
>
0
.
0
f
||
color2
.
r
>
0
.
0
f
||
color3
.
r
>
0
.
0
f
);
if
(
overlap
)
{
if
(
uContrast
==
0
.
0
)
{
color
=
vec4
(
applySepia
(
color
),
color
.
a
);
}
else
{
color
.
rgb
=
((
color
.
rgb
-
0
.
5
)
*
max
(
uContrast
,
0
.
0
))
+
0
.
5
;
}
fragColor
=
color
;
}
else
{
fragColor
=
vec4
(
0
.
0
f
);
}
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/DefaultVert.vert
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
layout
(
location
=
0
)
in
vec4
aPosition
;
layout
(
location
=
1
)
in
vec2
aTexCoord
;
out
vec2
vTexCoord
;
void
main
()
{
vTexCoord
=
vec2
(
aTexCoord
.
s
,
1
.
0
f
-
aTexCoord
.
t
);
gl_Position
=
aPosition
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/EraseForeground.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
lowp
float
;
in
vec2
vTexCoord
;
uniform
int
uNumMasks
;
uniform
vec3
uBgColor
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
out
vec4
fragColor
;
void
main
()
{
vec4
finalColor
=
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
float
totalMaskValue
=
0
.
0
f
;
if
(
uNumMasks
>
0
)
{
float
maskValue0
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue0
;
}
if
(
uNumMasks
>
1
)
{
float
maskValue1
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue1
;
}
if
(
uNumMasks
>
2
)
{
float
maskValue2
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue2
;
}
if
(
totalMaskValue
>
0
.
0
f
)
{
finalColor
=
vec4
(
uBgColor
,
1
.
0
f
);
}
else
{
finalColor
.
a
=
0
.
0
f
;
}
fragColor
=
finalColor
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Gradient.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
precision
mediump
sampler3D
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
sampler3D
uColorGradeLUT
;
uniform
mediump
vec2
uSize
;
out
vec4
fragColor
;
void
main
()
{
// texel color
vec3
color
=
texture
(
uSampler
,
vTexCoord
).
rgb
;
vec3
gradedColor
=
texture
(
uColorGradeLUT
,
color
).
rgb
;
fragColor
=
vec4
(
gradedColor
,
1
);
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/NoisyMask.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
float
uCurrentFrame
;
uniform
int
uNumMasks
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
out
vec4
fragColor
;
vec3
startColor
=
vec3
(
0
.
0
f
,
0
.
67
f
,
1
.
0
f
);
vec3
endColor
=
vec3
(
0
.
05
f
,
0
.
06
f
,
0
.
05
f
);
float
random
(
vec2
st
)
{
return
fract
(
sin
(
dot
(
st
.
xy
,
vec2
(
12
.
9898
f
,
78
.
233
f
)))
*
43758
.
5453123
f
);
}
void
main
()
{
vec4
finalColor
=
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
float
totalMaskValue
=
0
.
0
f
;
if
(
uNumMasks
>
0
)
{
float
maskValue0
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue0
;
}
if
(
uNumMasks
>
1
)
{
float
maskValue1
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue1
;
}
if
(
uNumMasks
>
2
)
{
float
maskValue2
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
totalMaskValue
+=
maskValue2
;
}
// Dynamic color alteration using sin(time)
float
time
=
uCurrentFrame
*
0
.
1
f
;
vec3
dynamicColor
=
mix
(
startColor
,
endColor
,
sin
(
time
));
vec3
colorVariation
=
mix
(
vec3
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
),
vec3
(
1
.
0
f
,
1
.
0
f
,
1
.
0
f
),
vTexCoord
.
y
);
// apply randomness to the final color
float
rnd
=
random
(
vTexCoord
.
xy
);
if
(
totalMaskValue
>
0
.
0
f
)
{
finalColor
=
vec4
(
mix
(
dynamicColor
,
colorVariation
,
rnd
),
1
.
0
f
);
}
else
{
finalColor
.
a
=
0
.
0
f
;
}
fragColor
=
finalColor
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Overlay.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
highp
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
vec2
uSize
;
uniform
int
uNumMasks
;
uniform
float
uOpacity
;
uniform
bool
uBorder
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
uniform
vec4
uMaskColor0
;
uniform
vec4
uMaskColor1
;
uniform
vec4
uMaskColor2
;
uniform
float
uTime
;
uniform
vec2
uClickPos
;
uniform
int
uActiveMask
;
out
vec4
fragColor
;
vec4
lowerSaturation
(
vec4
color
,
float
saturationFactor
)
{
float
luminance
=
0
.
299
f
*
color
.
r
+
0
.
587
f
*
color
.
g
+
0
.
114
f
*
color
.
b
;
// Calculate luminance
vec3
gray
=
vec3
(
luminance
);
vec3
saturated
=
mix
(
gray
,
color
.
rgb
,
saturationFactor
);
// Mix gray with original color based on saturation factor
return
vec4
(
saturated
,
color
.
a
);
}
vec4
detectEdges
(
sampler2D
textureSampler
,
float
coverage
,
vec4
edgeColor
)
{
vec2
tvTexCoord
=
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
);
vec2
texOffset
=
1
.
0
f
/
uSize
;
vec3
result
=
vec3
(
0
.
0
f
);
// neighboring pixels
vec3
tLeft
=
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
-
coverage
,
coverage
)).
rgb
;
vec3
tRight
=
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
coverage
,
-
coverage
)).
rgb
;
vec3
bLeft
=
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
-
coverage
,
-
coverage
)).
rgb
;
vec3
bRight
=
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
coverage
,
coverage
)).
rgb
;
// calculate the gradient edge of the current pixel using [3x3] sobel operator.
vec3
xEdge
=
tLeft
+
2
.
0
f
*
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
-
coverage
,
0
)).
rgb
+
bLeft
-
tRight
-
2
.
0
f
*
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
coverage
,
0
)).
rgb
-
bRight
;
vec3
yEdge
=
tLeft
+
2
.
0
f
*
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
0
,
coverage
)).
rgb
+
tRight
-
bLeft
-
2
.
0
f
*
texture
(
textureSampler
,
tvTexCoord
+
texOffset
*
vec2
(
0
,
-
coverage
)).
rgb
-
bRight
;
// magnitude of the gradient at the current pixel.
result
=
sqrt
(
xEdge
*
xEdge
+
yEdge
*
yEdge
);
return
result
.
r
>
1e-6
f
?
edgeColor
:
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
}
vec2
calculateAdjustedTexCoord
(
vec2
vTexCoord
,
vec4
bbox
,
float
aspectRatio
)
{
vec2
center
=
vec2
((
bbox
.
x
+
bbox
.
z
)
*
0
.
5
f
,
bbox
.
w
);
float
radiusX
=
abs
(
bbox
.
z
-
bbox
.
x
);
float
radiusY
=
radiusX
/
aspectRatio
;
float
scale
=
1
.
0
f
;
radiusX
*=
scale
;
radiusY
*=
scale
;
vec2
adjustedTexCoord
=
(
vTexCoord
-
center
)
/
vec2
(
radiusX
,
radiusY
)
+
vec2
(
0
.
5
f
);
return
adjustedTexCoord
;
}
void
main
()
{
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
vec4
color1
=
uMaskColor0
/
255
.
0
;
vec4
color2
=
uMaskColor1
/
255
.
0
;
vec4
color3
=
uMaskColor2
/
255
.
0
;
float
saturationFactor
=
0
.
7
;
float
aspectRatio
=
uSize
.
y
/
uSize
.
x
;
vec2
tvTexCoord
=
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
);
vec4
finalColor
=
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
float
totalMaskValue
=
0
.
0
f
;
vec4
edgeColor
=
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
float
numRipples
=
1
.
75
;
float
timeThreshold
=
1
.
1
;
// can take any value from [0.0, 1.5]
vec2
adjustedClickCoord
=
calculateAdjustedTexCoord
(
vTexCoord
,
vec4
(
uClickPos
,
uClickPos
+
0
.
1
),
aspectRatio
);
if
(
uNumMasks
>
0
)
{
float
maskValue0
=
texture
(
uMaskTexture0
,
tvTexCoord
).
r
;
vec4
saturatedColor
=
lowerSaturation
(
color1
,
saturationFactor
);
vec4
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
vec4
rippleColor
=
vec4
(
color1
.
rgb
,
0
.
2
);
if
(
uActiveMask
==
0
&&
uTime
<
timeThreshold
)
{
float
dist
=
length
(
adjustedClickCoord
);
float
colorFactor
=
abs
(
sin
((
dist
-
uTime
)
*
numRipples
));
plainColor
=
vec4
(
mix
(
rippleColor
,
plainColor
,
colorFactor
));
};
if
(
uTime
>=
timeThreshold
)
{
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
}
finalColor
+=
maskValue0
*
plainColor
;
totalMaskValue
+=
maskValue0
;
edgeColor
=
detectEdges
(
uMaskTexture0
,
1
.
25
,
color1
);
}
if
(
uNumMasks
>
1
)
{
float
maskValue1
=
texture
(
uMaskTexture1
,
tvTexCoord
).
r
;
vec4
saturatedColor
=
lowerSaturation
(
color2
,
saturationFactor
);
vec4
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
vec4
rippleColor
=
vec4
(
color2
.
rgb
,
0
.
2
);
if
(
uActiveMask
==
1
&&
uTime
<
timeThreshold
)
{
float
dist
=
length
(
adjustedClickCoord
);
float
colorFactor
=
abs
(
sin
((
dist
-
uTime
)
*
numRipples
));
plainColor
=
vec4
(
mix
(
rippleColor
,
plainColor
,
colorFactor
));
}
if
(
uTime
>=
timeThreshold
)
{
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
}
finalColor
+=
maskValue1
*
plainColor
;
totalMaskValue
+=
maskValue1
;
if
(
edgeColor
.
a
<=
0
.
0
f
)
{
edgeColor
=
detectEdges
(
uMaskTexture1
,
1
.
25
,
color2
);
}
}
if
(
uNumMasks
>
2
)
{
float
maskValue2
=
texture
(
uMaskTexture2
,
tvTexCoord
).
r
;
vec4
saturatedColor
=
lowerSaturation
(
color3
,
saturationFactor
);
vec4
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
vec4
rippleColor
=
vec4
(
color3
.
rgb
,
0
.
2
);
if
(
uActiveMask
==
2
&&
uTime
<
timeThreshold
)
{
float
dist
=
length
(
adjustedClickCoord
);
float
colorFactor
=
abs
(
sin
((
dist
-
uTime
)
*
numRipples
));
plainColor
=
vec4
(
mix
(
rippleColor
,
plainColor
,
colorFactor
));
}
if
(
uTime
>=
timeThreshold
)
{
plainColor
=
vec4
(
vec3
(
saturatedColor
).
rgb
,
1
.
0
);
}
finalColor
+=
maskValue2
*
plainColor
;
totalMaskValue
+=
maskValue2
;
if
(
edgeColor
.
a
<=
0
.
0
f
)
{
edgeColor
=
detectEdges
(
uMaskTexture2
,
1
.
25
,
color3
);
}
}
if
(
totalMaskValue
>
0
.
0
f
)
{
finalColor
/=
totalMaskValue
;
finalColor
=
mix
(
color
,
finalColor
,
uOpacity
);
}
else
{
finalColor
.
a
=
0
.
0
f
;
}
if
(
edgeColor
.
a
>
0
.
0
f
&&
uBorder
)
{
finalColor
=
vec4
(
vec3
(
edgeColor
),
1
.
0
f
);
}
fragColor
=
finalColor
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Overlay.vert
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
layout
(
location
=
0
)
in
vec4
aPosition
;
layout
(
location
=
1
)
in
vec2
aTexCoord
;
out
vec2
vTexCoord
;
void
main
()
{
// Rotate texture 90 degrees clockwise
vTexCoord
=
vec2
(
1
.
0
f
-
aTexCoord
.
t
,
aTexCoord
.
s
);
gl_Position
=
aPosition
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Pixelate.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
mediump
vec2
uSize
;
uniform
lowp
float
uBlockSize
;
out
vec4
fragColor
;
void
main
()
{
vec2
uv
=
vTexCoord
.
xy
;
float
dx
=
uBlockSize
/
uSize
.
x
;
float
dy
=
uBlockSize
/
uSize
.
y
;
// Sample from 2 places to get a better average texel color
vec2
sampleCoord
=
(
vec2
(
dx
*
floor
((
uv
.
x
/
dx
)),
dy
*
floor
((
uv
.
y
/
dy
)))
+
vec2
(
dx
*
ceil
((
uv
.
x
/
dx
)),
dy
*
ceil
((
uv
.
y
/
dy
))))
/
2
.
0
f
;
vec4
frameColor
=
texture
(
uSampler
,
sampleCoord
);
fragColor
=
frameColor
;
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/PixelateMask.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
mediump
vec2
uSize
;
uniform
lowp
float
uBlockSize
;
uniform
int
uNumMasks
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
out
vec4
fragColor
;
void
main
()
{
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
vec2
uv
=
vTexCoord
.
xy
;
float
dx
=
uBlockSize
/
uSize
.
x
;
float
dy
=
uBlockSize
/
uSize
.
y
;
vec4
color1
=
vec4
(
0
.
0
f
);
vec4
color2
=
vec4
(
0
.
0
f
);
vec4
color3
=
vec4
(
0
.
0
f
);
vec2
sampleCoord
=
(
vec2
(
dx
*
floor
((
uv
.
x
/
dx
)),
dy
*
floor
((
uv
.
y
/
dy
)))
+
vec2
(
dx
*
ceil
((
uv
.
x
/
dx
)),
dy
*
ceil
((
uv
.
y
/
dy
))))
/
2
.
0
f
;
vec4
frameColor
=
texture
(
uSampler
,
sampleCoord
);
color
=
frameColor
;
if
(
uNumMasks
>
0
)
{
color1
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
if
(
uNumMasks
>
1
)
{
color2
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
if
(
uNumMasks
>
2
)
{
color3
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
}
bool
overlap
=
(
color1
.
r
>
0
.
0
f
||
color2
.
r
>
0
.
0
f
||
color3
.
r
>
0
.
0
f
);
if
(
overlap
)
{
fragColor
=
color
;
}
else
{
fragColor
=
vec4
(
0
.
0
f
);
}
}
\ No newline at end of file
demo/frontend/src/common/components/video/effects/shaders/Replace.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
lowp
float
;
in
vec2
vTexCoord
;
uniform
vec2
uSize
;
uniform
int
uNumMasks
;
uniform
sampler2D
uEmojiTexture
;
uniform
bool
uFill
;
// use all emoji texture
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
uniform
vec4
bbox0
;
uniform
vec4
bbox1
;
uniform
vec4
bbox2
;
out
vec4
fragColor
;
vec2
calculateAdjustedTexCoord
(
vec2
vTexCoord
,
vec4
bbox
,
float
aspectRatio
,
out
float
distanceFromCenter
)
{
vec2
center
=
(
bbox
.
xy
+
bbox
.
zw
)
*
0
.
5
f
;
float
radiusX
=
abs
(
bbox
.
z
-
bbox
.
x
);
float
radiusY
=
radiusX
/
aspectRatio
;
float
scale
=
1
.
25
f
;
radiusX
*=
scale
;
radiusY
*=
scale
;
vec2
adjustedTexCoord
=
(
vTexCoord
-
center
)
/
vec2
(
radiusX
,
radiusY
)
+
vec2
(
0
.
5
f
);
distanceFromCenter
=
length
((
vTexCoord
-
center
)
/
vec2
(
radiusX
*
0
.
5
f
,
radiusY
*
0
.
5
f
));
return
adjustedTexCoord
;
}
void
main
()
{
vec4
finalColor
=
vec4
(
0
.
0
f
);
float
aspectRatio
=
uSize
.
y
/
uSize
.
x
;
float
totalMaskValue
=
0
.
0
f
;
vec4
bgFill
=
vec4
(
1
.
0
f
,
0
.
0
f
,
0
.
0
f
,
1
.
0
f
);
vec4
emojiColor
;
if
(
uNumMasks
>
0
)
{
float
maskValue0
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
float
distanceFromCenter
;
vec2
adjustedTexCoord
=
calculateAdjustedTexCoord
(
vTexCoord
,
bbox0
,
aspectRatio
,
distanceFromCenter
);
if
(
maskValue0
>
0
.
0
f
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
if
(
distanceFromCenter
>
0
.
85
f
&&
!
uFill
)
{
emojiColor
=
bgFill
;
}
}
if
(
uFill
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
}
totalMaskValue
+=
maskValue0
;
}
if
(
uNumMasks
>
1
)
{
float
maskValue1
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
float
distanceFromCenter
;
vec2
adjustedTexCoord
=
calculateAdjustedTexCoord
(
vTexCoord
,
bbox1
,
aspectRatio
,
distanceFromCenter
);
if
(
maskValue1
>
0
.
0
f
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
if
(
distanceFromCenter
>
0
.
85
f
&&
!
uFill
)
{
emojiColor
=
bgFill
;
}
}
if
(
uFill
&&
emojiColor
.
a
==
0
.
0
f
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
}
totalMaskValue
+=
maskValue1
;
}
if
(
uNumMasks
>
2
)
{
float
maskValue2
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
)).
r
;
float
distanceFromCenter
;
vec2
adjustedTexCoord
=
calculateAdjustedTexCoord
(
vTexCoord
,
bbox2
,
aspectRatio
,
distanceFromCenter
);
if
(
maskValue2
>
0
.
0
f
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
if
(
distanceFromCenter
>
0
.
85
f
&&
!
uFill
)
{
emojiColor
=
bgFill
;
}
}
if
(
uFill
&&
emojiColor
.
a
==
0
.
0
f
)
{
emojiColor
=
texture
(
uEmojiTexture
,
adjustedTexCoord
);
}
totalMaskValue
+=
maskValue2
;
}
if
(
totalMaskValue
>
0
.
0
f
)
{
finalColor
=
emojiColor
;
}
else
{
finalColor
=
uFill
?
emojiColor
:
vec4
(
0
.
0
f
);
}
fragColor
=
finalColor
;
}
demo/frontend/src/common/components/video/effects/shaders/Scope.frag
0 → 100644
View file @
3af09475
#version 300 es
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
precision
mediump
float
;
in
vec2
vTexCoord
;
uniform
sampler2D
uSampler
;
uniform
vec2
uSize
;
uniform
int
uNumMasks
;
uniform
bool
uFillColor
;
uniform
bool
uLight
;
uniform
bool
uTransparency
;
uniform
sampler2D
uMaskTexture0
;
uniform
sampler2D
uMaskTexture1
;
uniform
sampler2D
uMaskTexture2
;
uniform
vec4
uMaskColor0
;
uniform
vec4
uMaskColor1
;
uniform
vec4
uMaskColor2
;
uniform
vec4
bbox0
;
uniform
vec4
bbox1
;
uniform
vec4
bbox2
;
out
vec4
fragColor
;
void
main
()
{
vec4
color
=
texture
(
uSampler
,
vTexCoord
);
float
aspectRatio
=
uSize
.
y
/
uSize
.
x
;
float
radiusThreshold
=
0
.
8
f
;
float
tickness
=
0
.
085
f
;
vec4
mask1
=
vec4
(
0
.
0
f
);
vec4
mask2
=
vec4
(
0
.
0
f
);
vec4
mask3
=
vec4
(
0
.
0
f
);
vec4
color1
=
uMaskColor0
/
255
.
0
;
vec4
color2
=
uMaskColor1
/
255
.
0
;
vec4
color3
=
uMaskColor2
/
255
.
0
;
vec4
scopedColor
=
vec4
(
0
.
0
f
);
bool
scoped
=
false
;
vec4
whiteVariation
=
uTransparency
?
vec4
(
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
)
:
vec4
(
1
.
0
);
if
(
uNumMasks
>
0
)
{
mask1
=
texture
(
uMaskTexture0
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center1
=
(
bbox0
.
xy
+
bbox0
.
zw
)
*
0
.
5
f
;
float
radiusX1
=
abs
(
bbox0
.
y
-
bbox0
.
w
)
*
0
.
5
f
;
float
radiusY1
=
radiusX1
/
aspectRatio
;
float
distX1
=
(
vTexCoord
.
x
-
center1
.
x
)
/
radiusX1
;
float
distY1
=
(
vTexCoord
.
y
-
center1
.
y
)
/
radiusY1
;
float
dist1
=
sqrt
(
pow
(
distX1
,
2
.
0
f
)
+
pow
(
distY1
,
2
.
0
f
));
if
(
uFillColor
)
{
if
(
dist1
>=
radiusThreshold
-
tickness
&&
dist1
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color1
;
}
}
else
if
(
dist1
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color1
;
}
}
if
(
uNumMasks
>
1
)
{
mask2
=
texture
(
uMaskTexture1
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center2
=
(
bbox1
.
xy
+
bbox1
.
zw
)
*
0
.
5
f
;
float
radiusX2
=
abs
(
bbox1
.
y
-
bbox1
.
w
)
*
0
.
5
f
;
float
radiusY2
=
radiusX2
/
aspectRatio
;
float
distX2
=
(
vTexCoord
.
x
-
center2
.
x
)
/
radiusX2
;
float
distY2
=
(
vTexCoord
.
y
-
center2
.
y
)
/
radiusY2
;
float
dist2
=
sqrt
(
pow
(
distX2
,
2
.
0
f
)
+
pow
(
distY2
,
2
.
0
f
));
if
(
uFillColor
)
{
if
(
dist2
>=
radiusThreshold
-
tickness
&&
dist2
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color2
;
}
}
else
if
(
dist2
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color2
;
}
}
if
(
uNumMasks
>
2
)
{
mask3
=
texture
(
uMaskTexture2
,
vec2
(
vTexCoord
.
y
,
vTexCoord
.
x
));
vec2
center3
=
(
bbox2
.
xy
+
bbox2
.
zw
)
*
0
.
5
f
;
float
radiusX3
=
abs
(
bbox2
.
y
-
bbox2
.
w
)
*
0
.
5
f
;
float
radiusY3
=
radiusX3
/
aspectRatio
;
float
distX3
=
(
vTexCoord
.
x
-
center3
.
x
)
/
radiusX3
;
float
distY3
=
(
vTexCoord
.
y
-
center3
.
y
)
/
radiusY3
;
float
dist3
=
sqrt
(
pow
(
distX3
,
2
.
0
f
)
+
pow
(
distY3
,
2
.
0
f
));
if
(
uFillColor
)
{
if
(
dist3
>=
radiusThreshold
-
tickness
&&
dist3
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color3
;
}
}
else
if
(
dist3
<=
radiusThreshold
)
{
scoped
=
true
;
scopedColor
=
uLight
?
whiteVariation
:
color3
;
}
}
bool
overlap
=
(
mask1
.
r
>
0
.
0
f
||
mask2
.
r
>
0
.
0
f
||
mask3
.
r
>
0
.
0
f
);
if
(
scoped
)
{
fragColor
=
overlap
?
color
:
scopedColor
;
fragColor
.
a
=
uTransparency
?
fragColor
.
a
:
1
.
0
;
}
else
{
fragColor
=
overlap
?
color
:
vec4
(
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
}
}
Prev
1
…
6
7
8
9
10
11
12
13
14
…
30
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment