SKDefaultShading with Metal-based SceneKit

On iOS 8, this code (Swift) worked:


let shaderString = "void main()" +
                               "{" +
                                   "gl_FragColor = SKDefaultShading().bgra;" +
                               "}"
let shader = SKShader(source: shaderString)


Now on iOS 9, with Metal under the covers, I get this error message:


2015-06-09 18:36:39.497 TestVideoCam[550:63920] Jet: Error Domain=MTLLibraryErrorDomain Code=3 "Compilation failed:
program_source:6:321: error: use of undeclared identifier 'SKDefaultShading'
    fragment float4 SKShader_FragFunc(    texture2d<float>  u_texture         [[texture(0)]],     const device float *u_time           [[buffer(0)]],     const device float2 *u_sprite_size   [[buffer(1)]],     const device float *u_path_length    [[buffer(2)]],  SKShader_VertexOut interpolated     [[stage_in]]){return SKDefaultShading().bgra;}
                                                                                                                                                                                                                                                                                                                                ^
" UserInfo=0x156e50c10 {NSLocalizedDescription=Compilation failed:
program_source:6:321: error: use of undeclared identifier 'SKDefaultShading'
    fragment float4 SKShader_FragFunc(    texture2d<float>  u_texture         [[texture(0)]],     const device float *u_time           [[buffer(0)]],     const device float2 *u_sprite_size   [[buffer(1)]],     const device float *u_path_length    [[buffer(2)]],  SKShader_VertexOut interpolated     [[stage_in]]){return SKDefaultShading().bgra;}
                                                                                                                                                                                                                                                                                                                                ^
}


At first glance, it looks like SKDefaultShading is not known to SpriteKit with Metal instead of OpenGL ES under the covers.

Having a similar problem, in iOS 8 this worked:


_fontShader = [SKShader shaderWithFileNamed:@"TheShader"]; // ios9 compatibility problem
_fontUniform = [SKUniform uniformWithName:@"labelBase" float:0];
[self.fontShader addUniform:self.fontUniform]; // ios9 compatibility problem
  
_fontEffects = [SKEffectNode node];
self.fontEffects.shader = self.fontShader; // ios9 compatibility problem
 


And on iOS 9 the console is spewing out a constant stream of this garbage:

2015-07-12 22:43:17.717 ReconInForce[599:110531] Jet: Error Domain=MTLLibraryErrorDomain Code=3 "Compilation failed: 
program_source:8:18: error: use of undeclared identifier 'gl_FragCoord'
    float yPos = gl_FragCoord.y - labelBase[0];
                 ^
program_source:11:18: error: use of undeclared identifier 'SKDefaultShading'
    vec4 color = SKDefaultShading(); / 
                 ^
" UserInfo=0x158c084b0 {NSLocalizedDescription=Compilation failed: 
program_source:8:18: error: use of undeclared identifier 'gl_FragCoord'
    float yPos = gl_FragCoord.y - labelBase[0];
                 ^
program_source:11:18: error: use of undeclared identifier 'SKDefaultShading'
    vec4 color = SKDefaultShading(); / 
                 ^
}

Edit: I forgot to mention that if I comment out the lines above that say "// ios9 compatibility problem" then the problem is resolved but I lose the shaders in my App.


It repeats over and over, slowing the device down to an absolute crawl. Any help would be apprecited...

This is still a problem in the release version of iOS 9.0.1. Did anyone find a workaround?

When will Apple pay attention to SpriteKit, my games are all broken in iOS9, im receiving bad reviews, and its not my fault. This is terible.

This is still happening in Xcode 7.1/Swift 2.1. No word from Apple? 😢

Instead of SKDefaultShading() you can use this code as a workaround:

vec4 color = texture2D(u_texture, v_tex_coord);

Thanks, it's a bit more complex than that.

I think when I'm using a TextureAtlas the alpha gets premultiplied, but when I load an image directly, it is not... Is that correct?

Also, I need to apply the vertex color, etc.

I wasn't using SKDefaultShading at the beginning, but I didn't manage to properly reverse-engineer all the combinations and that's why I switched to use SKDefaultShading in the end.


Of course if there's no word from Apple, we'll have to give up on this, but I want to hear the official version.

I posted feedback in the documentation page, let's see if they update it. If the function is deprecated, they should at least mention it,


https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKShader_Ref/index.html

Yes it is definitely a bigger issue. I only used some simple shaders which I could fix by using texture2D instead of SKDefaultShading() but they broke a lot of other things too.

One thing you could try is turning on PrefersOpenGL(Add the PrefersOpenGL/YES value to your Info.plist) as long as there is no fix from Apple(But I didn't try it)

Oh. Good luck! I've posted feedback on maybe 50 pages of documentation, a couple of times even writing long winded examples of how to better explain and present things.


Never a single word of reply, nor acknowledgement.


However one day I did notice that some of my ideas about how to better comunicate Protocols and Delegates had been taken on board, years later. But they were just common sense, so there's no certainty that they read my input.

Yup, Apple will only acknowledge you when they need you to do the work of isolating a bug and providing example scenes. They will happily ask you to do their work for free and provide nothing in return. Feels great.

Hi jonmarimba,


Have you filed a bug report? I can can file a bug report for you if you haven't, so that we can track this issue.


As Nightmare_82 stated above, a valid workaround is to sample from u_texture via v_tex_coord. To address the issues endavid is seeing, make sure to multiply the color by v_color_mix:

vec4 color = v_color_mix * texture2D(u_texture, v_tex_coord);


We will let you know as soon as a fix is available for you.


Thank you.

Definitely giving up on SKDefaultShading(). It's causing lots of random issues, including Xcode crashes.

Having SKDefaultShading() in my custom shader seems to be causing a problem with my project. I have to erase my scene and recreate it without the custom shader, otherwise Xcode will keep hanging every time I select that scene… And because it hangs when you select the scene, every time you start Xcode it will remember the last file you selected and immediately hang unless you delete your project.xcworkspace/xcuserdata/ and xcuserdata/.

Really annoying. It used to work fine but this shader is now causing major nightmares.

Is any of this fixed as of now? Including the latest iOS 9.3 betas?


I am constantly selecting between technologies, and seeing a lot of these issues does not make SpriteKit look very favorable.

Sorry for a late bump but I'm working on a likely related issue. Things work (i.e. Work on iOS 10 and iOS 9 which are the versions i need to support now) if I load sprite images from outside an atlas. If I load a sprite from an atlas things work only on iOS 9. On iOS 10 shaders that use those atlas images do NOT work and behave very differently, I suspect there is a discrepancy with how 9 and 10 handles alpha for images loaded from atlases or just from an assets folder (or resources).

SKDefaultShading with Metal-based SceneKit
 
 
Q