Reverse Sprite Masking

Hi all,

I’m trying to put together a moon phase simulator and would like to recreate the following effect:


Now, I could do this using an animation, but the number of sprites needed would make this simulator a overly large download. As such, I would like to do this by just graphically manipulating a partially transparent “shadow” over an image of the moon.

Now my first thought was to use “sprite masking” to “reveal” the shadow - essentially by reducing just the width of a circular mask to zero, thereby making the shadow appear (be unmasked) as above.

This works fine until the moon is half in shadow, but in order for the shadow to continue across the surface of the moon, I would need to reverse the action of the sprite masking - in other words, I would need the mask to reveal the shadow as its width expands again.

Does anyone know if the sprite masking tool can be re-engineered to offer a reverse effect, i.e. mask reveals the underlying “shadow” sprite rather than blocks it … or does anyone have another suggestion of how the above could be achieved,

Many thanks … Chris

I don’t even get how you achieve the first half :sweat_smile:

Have you tried the shape painter?

1 Like


I did think about shape painter, but it doesn’t give the fine control needed to constantly manipulate the shape as required, but thanks for the suggestion.

in terms of the first-half, I just used a circular mask to block out the underlying circular shadow sprite. As the width of the mask shrinks to zero, more of the shadow sprite is unmasked (revealed) in the required fashion. I just need the ability to reverse the mask action to achieve the second half.

Might have to dig into the code at some point.

The rendering engine doesn’t support reverse masking sadly

1 Like

I was just going to ask about reverse masking, like it can be done on Inkscape

Basically, in the system I am making, I need to hide an object under another only when a certain condition is met and without touching the z-order of anything at all.

I am having difficulty achieving this with regular masking, as placing and shaping the white shapes the right way without colliding with anything they shouldn’t is quite cumbersome.
With reverse masking, I would only need one black shape instead of at least four whites.

I do hope that there is some interest in implementing this.
Or the possibility to use as a mask an object that is also being masked, that could help too.
And sorry for digging up a dead discussion, I just wanted to express my interest.

edit: I wonder if it would be possible to implement it using this code


Using the forum link that @lounes provided above I was able to extend your extension with a simple “ReverseMask” function that works well:

const maskObject = eventsFunctionContext.getObjects("Mask")[0];
if (!maskObject) return;
const maskedObjects = eventsFunctionContext.getObjects("Masked");

for (const maskedObject of maskedObjects) {
    const maskedRenderer = maskedObject.getRendererObject(); 
    maskedRenderer.filters = [new PIXI.SpriteMaskFilter(undefined, `\
        varying vec2 vMaskCoord;
        varying vec2 vTextureCoord;

        uniform sampler2D uSampler;
        uniform sampler2D mask;
        uniform float alpha;
        uniform float npmAlpha;
        uniform vec4 maskClamp;

        void main(void)
            float clip = step(3.5,
                step(maskClamp.x, vMaskCoord.x) +
                step(maskClamp.y, vMaskCoord.y) +
                step(vMaskCoord.x, maskClamp.z) +
                step(vMaskCoord.y, maskClamp.w));

            vec4 original = texture2D(uSampler, vTextureCoord);
            vec4 masky = texture2D(mask, vMaskCoord);
            float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);

            original *= 1.0 - (alphaMul * masky.r * alpha * clip);

            gl_FragColor = original;
    maskedRenderer.filters[0].maskSprite = maskObject.getRendererObject();;

I think it would be a worthy addition to your extension if you so choose.

looks good to me, feel free to submit an update to the extension