使用SKShader

时间:2016-09-06 10:21:34

标签: ios swift opengl-es shader

我已经看过SKShader在应用程序中获得一些水效果,其中一些精灵正在四处移动。基于这个教程Making a Pixel Shader for iOS8 with Sprite Kit,我创建了一个效果,但我的帧速率在模拟器中下降了,我在iPhone 5s中出现内存问题。

我的代码如下所示 来自GameScene:

override func didMoveToView(view: SKView) {
        super.didMoveToView(view)

        // MARK: BACKGROUND IMAGE & SHADER

        let backgroundImage = SKSpriteNode(imageNamed: "Background")
        backgroundImage.size.width = frame.size.width
        backgroundImage.size.height = frame.size.height
        backgroundImage.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
        backgroundImage.zPosition = -1000
        addChild(backgroundImage)

        let shaderContainer = SKSpriteNode(color: SKColor(red: 1, green: 1, blue: 1, alpha: 0), size: (CGSizeMake(frame.width, frame.height)))
        shaderContainer.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2)
        shaderContainer.zPosition = 1000
        addChild(shaderContainer)

        let shader = SKShader(fileNamed: "shader_water.fsh")
        shader.uniforms = [
            SKUniform(name: "size", floatVector3:GLKVector3Make(Float(self.frame.size.width), Float(self.frame.size.height), 0)),
        ]
        shaderContainer.shader = shader

.fsh文件直接来自教程。

void main( void )
{
    float time = u_time * .5;
    vec2 sp = gl_FragCoord.xy / size.xy;
    vec2 p = sp * 6.0 - 20.0;
    vec2 i = p;
    float c = 1.0;
    float inten = .05;

    for (int n = 0; n < 5; n++)
    {
        float t = time * (1.0 - (3.5 / float(n+1)));
        i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
        c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
    }

    c /= float(5);
    c = 1.55-sqrt(c);
    vec3 colour = vec3(pow(abs(c), 15.0));

    gl_FragColor = vec4(clamp(colour + vec3(0.0, 0.17, 0.3), 0.0, .5), 0.3);
}

有谁知道可能会发生什么以及如何让着色器更有效地工作?

1 个答案:

答案 0 :(得分:2)

片段着色器中的整个计算基于u_time&amp; gl_FragCoord表示可以将相同的计算移动到顶点着色器。一些提高着色器性能的基本技巧。

  • 对每个顶点进行所有计算并避免每个片段计算
  • 在着色器中避免循环(在你的情况下为循环),GPU不擅长 循环