I've read in other posts that SceneKit only has two blend modes though I'm still wondering how those exactly work and how to make use of them.
I'm currently trying to draw some anti-aliased circles with a fragment shader. Therefore I'd like smooth-step the edges of these circles and blur
/fade
them out to being transparent.
Using the normal blend mode (without #transparent), SceneKit's fragment shader will ignore any alpha value changes, but it will still alpha blend. The alpha blending happens according to the alpha value of the colors of the material. Hence, alpha blending is possible but can not be changed in the fragment shader.
For testing this, I've used a fragment shader addition that looks like this:
#pragma body
_output.color = vec4(1.0, 1.0, 1.0, 1.0);
This is the code to create my circles:
#define kDefaultCircleColor [UIColor colorWithRed: 0.5 green: 0.0 blue: 0.0 alpha: 0.5]
NSMutableDictionary *shaders = [NSMutableDictionary dictionary];
shaders[SCNShaderModifierEntryPointFragment] = [[NSString alloc] initWithContentsOfURL: [[NSBundle mainBundle] URLForResource: @"test" withExtension: @"shader"] encoding: NSUTF8StringEncoding error: NULL];
MLCircleNode *circNode1 = [MLCircleNode node];
circNode1.radius = 50;
circNode1.position = SCNVector3Make(100, 400, 0);
circNode1.color = kDefaultCircleColor;
circNode1.lineWidth = 15.0;
circNode1.geometry.firstMaterial.shaderModifiers = shaders;
[_baseNode addChildNode: circNode1];
MLCircleNode *circNode2 = [MLCircleNode node];
circNode2.radius = 50;
circNode2.position = SCNVector3Make(125, 400, -1);
circNode2.color = kDefaultCircleColor;
circNode2.lineWidth = 15.0;
circNode2.geometry.firstMaterial.shaderModifiers = shaders;
[_baseNode addChildNode: circNode2];
This is the result. As one can see, the fragment shader's color changes were applied, but not the alpha value change, which results in a white with 50% transparency.
I'd use the transparent blending mode by adding #transparent in the shader to achieve the wanted effect, but also here I've got some issues. The colors of transparent materials of the #transparent blend mode are different from the colors of transparent materials from the default blend mode (I guess this is due to the use of (GL_ONE, GL_ONE_MINUS_SRC_ALPHA), but I'm not sure). The results of the #opaque blend mode are different from both of these.
The difference between the following images is just adding #transparent or adding #opaque in the fragment shader modifier:
Without any additons.
With #transparent
With #opaque
Thanks for reading this long post so far, now comes the fun part, questions!
1) Where is the color in my first example being calculated? How is it possible that I set a color of (1.0, 1.0, 1.0, 1.0) in the fragment shader but what I see is a white with 50% alpha blending? I'd like to understand how the process of coloring works here, where the colors come from and where the alpha values comes from, so I know how to use it effectively.
2) Why does the color change when using non-#transparent blending and #transparent-blending? Does this mean there's a third blend mode in SceneKit?
3) How can one use the two different blending modes together? For exmaple, I'd like to have some nodes that can have their alpha value being altered in the fragment shader, hence those would use #transparent. Others should not use it, but though these should have the same color. How can one get around the change of color between these two blend modes?
4) What would you recommend to do for getting the smoothstep alpha drawing of my circles to work?