问题
I'm starting to use shaders with SpriteKit on iOS. And it's quite a journey...
Right now I have some strange behaviour.
I was trying to create a outer glow shader. So my goal was to modify the color and alpha of transparent pixel to be less transparent and with a specific color, and I was unable to achieve the transparence level of it. So I dug and created the following:
- I loaded a texture with different alpha levels (mostly 0 and 1) into an
SKSpriteNode - Applied the shader.
The shader is the following:
#ifdef GL_ES precision mediump float; #endif void main() { vec4 color = texture2D(u_texture, v_tex_coord); if(color.a == 1.) { color.rgb = vec3(1.,0.,0.); }else if(color.a > .6) { color.rgb = vec3(0.,1.,0.); } else if(color.a == 0.) { color.rgb = vec3(0.,0.,1.); } color.a = .3; gl_FragColor = color; }
I change the color of the pixel depending on the alpha level and apply 0 to the alpha channel.
I expected the whole image to be transparent. But no! Everything is fully visible.
Now if I change any the color to black vec3(0.,0.,0.);, the picture result show the black color with the transparency.
Do you have any idea why this occurs? And eventually how to fix it?
Here is the code for the node creation:
let sp = SKSpriteNode(imageNamed: "EmptyCapsule")
let myShader = SKShader(fileNamed: "WIP")
sp.shader = myShader
sp.anchorPoint = CGPoint(x: 0, y: 0)
addChild(sp)
回答1:
Thanks to bg2b, I tested premultiplying alpha and the result is what's expected. I don't know if there is a preferred way to do it but what I ended up with is :
vec4 color = texture2D(u_texture, v_tex_coord);
if(color.a == 1.)
{
color.rgb = vec3(1.,0.,0.);
}else if(color.a > .6)
{
color.rgb = vec3(0.,1.,0.);
}
else if(color.a == 0.)
{
color.rgb = vec3(0.,0.,1.);
}
color.a = .9;
gl_FragColor = vec4(color.rgb*color.a, color.a);
To be noted : when I didn't premultiplied alpha, the alpha was still used to blend different objects of SpriteKit. I added another SKSpriteNode under the one I'm manipulating, and the 2 images where blended into each other but the colors of the manipulated image were "full".
Furthermore, In this exemple I didn't use SKDefaultShading(); to pick the color of the pixel. When I do, there is no difference in this case. How ever, if we change the alpha of the SKSpriteNode directly on the object the none alpha pixel keep there original color and the other one take the color used in the shader...
来源:https://stackoverflow.com/questions/61331357/shader-with-spritekit-only-register-alpha-for-black-color