以下是一种使用着色器为您生成maskNode的方法:
func generateMaskNode(from mask:SKNode) -> SKNode
{
var returningNode : SKNode!
autoreleasepool
{
let view = SKView()
let texture = view.texture(from: mask)
let node = SKSpriteNode(texture:texture)
node.shader = SKShader(fileNamed: "shader.fsh")
let texture2 = view.texture(from: node)
returningNode = SKSpriteNode(texture:texture2)
}
return returningNode
}
您需要创建一个名为shader.fsh的文件,其中代码如下:
void main() {
vec4 val = texture2D(u_texture, v_tex_coord);
if (val.r == 0.0 && val.g == 0.0 && val.b == 0.0) {
gl_FragColor = vec4(0.0,0.0,0.0,0.0);
}
else {
gl_FragColor = val;
}
}
要使用它,需要使用黑色像素代替alpha通道来确定被裁剪的内容,因此您的代码应该如下所示:
var cropNode = SKCropNode()
var shape = SKShapeNode(rectOf: CGSize(width:100,height:100))
shape.fillColor = SKColor.orange
var shape2 = SKShapeNode(rectOf: CGSize(width:25,height:25))
shape2.fillColor = SKColor.orange
shape2.blendMode = .subtract
shape.addChild(shape2)
let mask = generateMaskNode(from:shape)
cropNode.addChild(shape)
cropNode.position = CGPoint(x:150,y:170)
cropNode.maskNode=mask
container.addChild(cropNode)
模拟器上的减法能够正常工作,而设备上不能是因为模拟器会减去阿尔法通道的值,而设备不会。事实上,设备的表现是正确的,因为阿尔法通道不应该被减去,而应该被忽略。
请注意,您不必选择黑色作为裁剪颜色,您可以更改着色器以允许选择任何颜色,只需更改以下行:
if (val.r == 0.0 && val.g == 0.0 && val.b == 0.0)
将颜色修改为您想要的颜色(比如在你的情况下,你可以说r = 0 g = 1 b = 0只剪裁绿色部分)。
上述代码在设备上的结果
编辑:我想指出减法混合不是必需的,这也可以工作:
var cropNode = SKCropNode()
var shape = SKShapeNode(rectOf: CGSize(width:100,height:100))
shape.fillColor = SKColor.orange
var shape2 = SKShapeNode(rectOf: CGSize(width:25,height:25))
shape2.fillColor = SKColor.black
shape2.blendMode = .replace
shape.addChild(shape2)
let mask = generateMaskNode(from:shape)
cropNode.addChild(shape)
cropNode.position = CGPoint(x:150,y:170)
cropNode.maskNode=mask
container.addChild(cropNode)
现在有一个问题,我无法测试,那么我的功能是否还需要呢?
理论上下面的代码应该可以工作,因为它正在用上面的像素替换底层像素,所以理论上alpha值应该会传递过来。如果有人能够测试这个,请让我知道它是否有效。
var cropNode = SKCropNode()
var shape = SKShapeNode(rectOf: CGSize(width:100,height:100))
shape.fillColor = SKColor.orange
var shape2 = SKShapeNode(rectOf: CGSize(width:25,height:25))
shape2.fillColor = SKColor(red:0,green:0,blue:0,alpha:0)
shape2.blendMode = .replace
shape.addChild(shape2)
cropNode.addChild(shape)
cropNode.position = CGPoint(x:150,y:170)
cropNode.maskNode= shape.copy() as! SKNode
container.addChild(cropNode)
replace仅替换颜色而不是透明度。