简体   繁体   中英

PixiJS: Add hole into graphics object

I'm using PixiJS library. I want to create holes in graphics object. To do that I have search and tried loads of way but could not come up with any solution.

Initially I was thinking this library would have support for non zero winding rule so I can accomplish my goal easily but it does not support winding rule so I fail on that attempt.

Meanwhile I found some strange behavior with drawing. I have posted a bug at github . I don't know whether is it related to adding hole but mentioned here because one who interested to help me out it might be helpful to investigate this case better way.

Other solution that I have come up with is that I can do it using something called opposite of Masking . I have tried this one also but don't know how to do it with graphics objects and also worry about that would it work for complex objects with thousands of cut.

Below is the simple test that I'm trying to reproduce. There is three rectangles on top of each other and top most (red rectangle) has two holes. For simple test round hole is taken but that could be in any shape.

I'm stuck at this stage and invested loads of time but still have no result. Any help would be really appreciable.

在此处输入图片说明

从Pixi.js v3开始,您现在可以将任何一个精灵用作另一个精灵的遮罩,因此您可以创建一个带有白色矩形和黑色圆圈的alpha透明png,并使用它在另一个精灵中创建“孔”。

Pixi v3.0.3

Currently there is no direct native function available to add holes inside graphics object. Indeed it can be done using mask but I have made a handy implementation for that using earcut so no more masking and sprite to create holes.

Checkout full thread here .

The WebGL built-in way to do that is to use gl.blendFunc(gl.ZERO,gl.ONE_MINUS_SRC_ALPHA); .

This blend operation creates a hole instead of stacking images. It also takes into consideration semi-transparence. It is the equivalent of the xor globalCompositeOperation on regular canvas.


In order to use gl.blendFunc(gl.ZERO,gl.ONE_MINUS_SRC_ALPHA); with PIXI, you will need to modify 1 line of PIXI source code.

In the function WebGLRenderer.prototype._mapGlModes , change

this.blendModes[CONST.BLEND_MODES.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];

into

this.blendModes[CONST.BLEND_MODES.EXCLUSION] = [gl.ZERO, gl.ONE_MINUS_SRC_ALPHA];

Then you can set mySprite.blendMode = PIXI.BLEND_MODES.EXCLUSION and it will work.


One problem with that method however is that, like regular canvas, the holes generated will be transparent. In your example, this means that the holes will be the same color than the canvas background (black) rather than green.

One way to fix that is to stack multiple webgl canvas on top of each other with the option {transparent:true} .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM