SKShader performance slowdown

放肆的年华 提交于 2019-12-04 14:41:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!