问题
I need to implement a custom shader node using SpriteKit. In simulator everything is ok. On a device (iPad 3rd gen) shader animation is smooth just for first ~30 seconds, after that shader's fps are gradually falling down until it looks like a slideshow (1 fps or even less)
It is worth noting, that SpriteKit shows 60 fps, so does Xcode. CPU is ~75% busy, but shader itself shows ~1fps.
I own only 3rd generation iPad and I currently don't have an opportunity to test it on other devices Shader code is taken from wwdc session, but the issue is reproduced with any animated shaders I've tried.
Shader itself:
void main(void)
{
float currTime = u_time;
vec2 uv = v_tex_coord;
vec2 circleCenter = vec2(0.5, 0.5);
vec3 circleColor = vec3(0.8, 0.5, 0.7);
vec3 posColor = vec3(uv, 0.5+0.5 * sin(currTime)) * circleColor;
float illu = pow(1. - distance(uv, circleCenter), 4.) * 1.2;
illu *= (2. + abs(0.4 + cos(currTime * -20. + 50. * distance(uv, circleCenter))/1.5));
gl_FragColor = vec4(posColor * illu * 2.0, illu * 2.0);
}
GameScene:
import SpriteKit
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
addChild(shaderSprite(view.center))
}
func shaderSprite(position: CGPoint) -> SKSpriteNode {
let sprite = SKSpriteNode(texture: SKTexture(imageNamed: "dummy"), color: nil, size: CGSizeMake(100, 100))
sprite.shader = SKShader(fileNamed: "wwdc")
sprite.position = position
return sprite
}
}
Result in simulator or first ~30 seconds on iPad3:

Result on iPad3 after ~2 minutes:

Please point my mistake or just build the project on any other device to check if it's a device-specific issue. Thanks in advance.
Test project: https://github.com/alexburtnik/SKShaderTest
回答1:
This is an issue with the u_time uniform, I got around it by adding my own uniform float and using it instead of using u_time
Shader
void main(void)
{
float currTime = myUniform;
...
}
Update
override func update(currentTime: CFTimeInterval) {
let shadedNode = self.childNodeWithName("shadedNode") as SKSpriteNode
let uniform = shadedNode.shader!.uniformNamed("myUniform")
uniform!.floatValue = Float(currentTime)
}
回答2:
Gelan Almagro's answer above works perfectly. I'm adding the Objective-C code for the update:
method.
SKSpriteNode *shadedNode = (SKSpriteNode*)[self childNodeWithName:@"shadedNode"];
SKUniform *uniform = [shadedNode.shader uniformNamed:@"myUniform"];
uniform.floatValue = (float)currentTime;
来源:https://stackoverflow.com/questions/25824414/skshader-performance-slowdown