LYGIA Shader Library

prewitt (lygia/filter/edge/prewitt)

Adapted version of Prewitt edge detection from https://github.com/BradLarson/GPUImage2

Dependencies:

Use:

edgePrewitt(<SAMPLER_TYPE> texture, <vec2> st, <vec2> scale)

Check it on Github



#ifndef EDGEPREWITT_TYPE
#ifdef EDGE_TYPE
#define EDGEPREWITT_TYPE EDGE_TYPE
#else
#define EDGEPREWITT_TYPE float
#endif
#endif

#ifndef EDGEPREWITT_SAMPLER_FNC
#ifdef EDGE_SAMPLER_FNC
#define EDGEPREWITT_SAMPLER_FNC(TEX, UV) EDGE_SAMPLER_FNC(TEX, UV)
#else
#define EDGEPREWITT_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV).r
#endif
#endif

#ifndef FNC_EDGEPREWITT
#define FNC_EDGEPREWITT
EDGEPREWITT_TYPE edgePrewitt(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {
    // get samples around pixel
    EDGEPREWITT_TYPE tleft = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(-offset.x, offset.y));
    EDGEPREWITT_TYPE left = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(-offset.x, 0.));
    EDGEPREWITT_TYPE bleft = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(-offset.x, -offset.y));
    EDGEPREWITT_TYPE top = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(0., offset.y));
    EDGEPREWITT_TYPE bottom = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(0., -offset.y));
    EDGEPREWITT_TYPE tright = EDGEPREWITT_SAMPLER_FNC(tex, st + offset);
    EDGEPREWITT_TYPE right = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(offset.x, 0.));
    EDGEPREWITT_TYPE bright = EDGEPREWITT_SAMPLER_FNC(tex, st + vec2(offset.x, -offset.y));
    EDGEPREWITT_TYPE x = -tleft - top - tright + bleft + bottom + bright;
    EDGEPREWITT_TYPE y = -bleft - left - tleft + bright + right + tright;
    return sqrt((x * x) + (y * y));
}
#endif

Dependencies:

Use:

edgePrewitt(<SAMPLER_TYPE> texture, <float2> st, <float2> scale)

Check it on Github



#ifndef EDGEPREWITT_TYPE
#ifdef EDGE_TYPE
#define EDGEPREWITT_TYPE EDGE_TYPE
#else
#define EDGEPREWITT_TYPE float
#endif
#endif

#ifndef EDGEPREWITT_SAMPLER_FNC
#ifdef EDGE_SAMPLER_FNC
#define EDGEPREWITT_SAMPLER_FNC(TEX, UV) EDGE_SAMPLER_FNC(TEX, UV)
#else
#define EDGEPREWITT_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).r
#endif
#endif

#ifndef FNC_EDGEPREWITT
#define FNC_EDGEPREWITT
EDGEPREWITT_TYPE edgePrewitt(in SAMPLER_TYPE tex, in float2 st, in float2 offset) {
    // get samples around pixel
    EDGEPREWITT_TYPE tleft = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(-offset.x, offset.y));
    EDGEPREWITT_TYPE left = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(-offset.x, 0.));
    EDGEPREWITT_TYPE bleft = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(-offset.x, -offset.y));
    EDGEPREWITT_TYPE top = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(0., offset.y));
    EDGEPREWITT_TYPE bottom = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(0., -offset.y));
    EDGEPREWITT_TYPE tright = EDGEPREWITT_SAMPLER_FNC(tex, st + offset);
    EDGEPREWITT_TYPE right = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(offset.x, 0.));
    EDGEPREWITT_TYPE bright = EDGEPREWITT_SAMPLER_FNC(tex, st + float2(offset.x, -offset.y));
    EDGEPREWITT_TYPE x = -tleft - top - tright + bleft + bottom + bright;
    EDGEPREWITT_TYPE y = -bleft - left - tleft + bright + right + tright;
    return sqrt((x * x) + (y * y));
}
#endif

Check it on Github


fn edgePrewitt(tExample texture_2d<f32>, samp: sampler, uv: vec2f, offset: vec2f) -> vec3f {
    let top_left = textureSample(tex, samp, uv + vec2f(-offset.x, offset.y)).xyz;
    let left = textureSample(tex, samp, uv + vec2f(-offset.x, 0.)).xyz;
    let bottom_left = textureSample(tex, samp, uv + vec2f(-offset.x, -offset.y)).xyz;
    let top = textureSample(tex, samp, uv + vec2f(0., offset.y)).xyz;
    let bottom = textureSample(tex, samp, uv + vec2f(0., -offset.y)).xyz;
    let top_right = textureSample(tex, samp, uv + offset).xyz;
    let right = textureSample(tex, samp, uv + vec2f(offset.x, 0.)).xyz;
    let bottom_right = textureSample(tex, samp, uv + vec2f(offset.x, -offset.y)).xyz;
    let x = -top_left - top - top_right + bottom_left + bottom + bottom_right;
    let y = -bottom_left - left - top_left + bottom_right + right + top_right;
    return sqrt((x * x) + (y * y));
}

Examples

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository