SpriteKit 中的默认混合是如何工作的?
How does the default blending in SpriteKit work?
我第一次开始修改 SpriteKit (Xcode 7.1 iOS9),我看到了一些意想不到的结果(在设备和模拟器上)。
我希望能够通过着色器将 sprite 中的像素设置为完全透明,但由于某些原因,这并没有像我预期的那样工作。
这是一个例子ViewController:
class ViewController: UIViewController {
@IBOutlet var sceneView: SKView!
private var scene = SKScene()
override func viewDidLoad() {
super.viewDidLoad()
sceneView.showsDrawCount = true
sceneView.showsNodeCount = true
sceneView.showsFPS = true
scene.scaleMode = .ResizeFill
scene.backgroundColor = UIColor.redColor()
let node = SKSpriteNode()
node.size = CGSizeMake(64, 64)
node.position = CGPointMake(64, 64)
node.shader = SKShader(fileNamed: "Test")
scene.addChild(node)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.view.layoutIfNeeded()
sceneView.presentScene(scene)
}
}
这是一个示例着色器:
void main()
{
if (v_tex_coord.x < 0.5) {
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
} else {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
}
使用 SKBlendModeAlpha 的默认混合模式,我希望看到精灵的左半边是完全透明的(显示红色背景),右半边是绿色。但是,这就是我所看到的:
SKBlendModeAlpha 的混合公式不应该是:
R = (D * (1 - A)) + (S * A)
在这种情况下应该导致:
D A S R
R 1 0 0 1
G 0 0 1 0
B 0 0 0 0
D A S R
R 1 1 0 0
G 0 1 1 1
B 0 1 0 0
(左边红色,右边绿色)
我试过在节点上手动设置混合模式,但没有任何区别。
这是一个错误,还是我在这里遗漏了一些明显的东西?
感谢您的帮助。
当然,我的问题有一个简单的解释。 gl_FragColor 中返回的颜色预期具有预乘 alpha。因此,与其返回颜色值:
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
我应该返回一个颜色值:
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
我错误地认为零 alpha 意味着颜色分量被忽略。
我第一次开始修改 SpriteKit (Xcode 7.1 iOS9),我看到了一些意想不到的结果(在设备和模拟器上)。
我希望能够通过着色器将 sprite 中的像素设置为完全透明,但由于某些原因,这并没有像我预期的那样工作。
这是一个例子ViewController:
class ViewController: UIViewController {
@IBOutlet var sceneView: SKView!
private var scene = SKScene()
override func viewDidLoad() {
super.viewDidLoad()
sceneView.showsDrawCount = true
sceneView.showsNodeCount = true
sceneView.showsFPS = true
scene.scaleMode = .ResizeFill
scene.backgroundColor = UIColor.redColor()
let node = SKSpriteNode()
node.size = CGSizeMake(64, 64)
node.position = CGPointMake(64, 64)
node.shader = SKShader(fileNamed: "Test")
scene.addChild(node)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.view.layoutIfNeeded()
sceneView.presentScene(scene)
}
}
这是一个示例着色器:
void main()
{
if (v_tex_coord.x < 0.5) {
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
} else {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
}
使用 SKBlendModeAlpha 的默认混合模式,我希望看到精灵的左半边是完全透明的(显示红色背景),右半边是绿色。但是,这就是我所看到的:
SKBlendModeAlpha 的混合公式不应该是: R = (D * (1 - A)) + (S * A)
在这种情况下应该导致:
D A S R
R 1 0 0 1
G 0 0 1 0
B 0 0 0 0
D A S R
R 1 1 0 0
G 0 1 1 1
B 0 1 0 0
(左边红色,右边绿色)
我试过在节点上手动设置混合模式,但没有任何区别。
这是一个错误,还是我在这里遗漏了一些明显的东西?
感谢您的帮助。
当然,我的问题有一个简单的解释。 gl_FragColor 中返回的颜色预期具有预乘 alpha。因此,与其返回颜色值:
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
我应该返回一个颜色值:
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
我错误地认为零 alpha 意味着颜色分量被忽略。