SKShader表现放缓

时间:2014-09-13 15:00:03

标签: performance opengl-es sprite-kit shader ios8

我需要使用SpriteKit实现自定义着色器节点。 在模拟器中一切都很好。在设备(iPad第3代)上,着色器动画在前30秒内平滑,之后着色器的fps逐渐下降,直到它看起来像幻灯片(1 fps甚至更低)

值得注意的是,SpriteKit显示60 fps,Xcode也是如此。 CPU约占75%,但着色器本身显示~1fps。

我只拥有第3代iPad,目前我还没有机会在其他设备上测试它 着色器代码取自wwdc会话,但问题是使用我尝试的任何动画着色器重现的。

Shader本身:

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
    }
}

模拟器中的结果或iPad3上的前~30秒:

enter image description here

约2分钟后iPad3上的结果:

enter image description here

请指出我的错误或只是在任何其他设备上构建项目,以检查它是否是特定于设备的问题。提前谢谢。

测试项目:https://github.com/alexburtnik/SKShaderTest

2 个答案:

答案 0 :(得分:3)

这是 u_time 制服的问题,我通过添加自己的制服浮动并使用它来代替使用 u_time

来解决它

着色

void main(void)
     {
        float currTime = myUniform;
        ...
    }

更新

 override func update(currentTime: CFTimeInterval) {
        let shadedNode = self.childNodeWithName("shadedNode") as SKSpriteNode
        let uniform = shadedNode.shader!.uniformNamed("myUniform")
        uniform!.floatValue = Float(currentTime)
    }

答案 1 :(得分:0)

Gelan Almagro上面的答案非常有效。我正在为update:方法添加Objective-C代码。

SKSpriteNode *shadedNode = (SKSpriteNode*)[self childNodeWithName:@"shadedNode"];
SKUniform *uniform = [shadedNode.shader uniformNamed:@"myUniform"];
uniform.floatValue = (float)currentTime;