Sprite kit 为什么SpriteKit不更新着色器’;谁的制服?

Sprite kit 为什么SpriteKit不更新着色器’;谁的制服?,sprite-kit,shader,Sprite Kit,Shader,我在我的项目中添加了两个着色器,一个是WWDC 2014示例中的同一个着色器,另一个具有相同的代码,但添加了自定义制服。问题是,当应用程序运行时,带有自定义制服的精灵呈现为静态,并且在Xcode的SpriteKit编辑器上呈现为黑色 具有自定义均匀性的着色器位于下方,u\u speed用于控制波的移动速度 void main() { float currTime = u_time * u_speed; vec2 uv = v_tex_coord; vec2 circl

我在我的项目中添加了两个着色器,一个是WWDC 2014示例中的同一个着色器,另一个具有相同的代码,但添加了自定义制服。问题是,当应用程序运行时,带有自定义制服的精灵呈现为静态,并且在Xcode的SpriteKit编辑器上呈现为黑色

具有自定义均匀性的着色器位于下方,
u\u speed
用于控制波的移动速度

void main()
{
    float currTime = u_time * u_speed;

    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., illu * 2.) * v_color_mix.a;
}

这是一个项目,我只使用了着色器和两个精灵来显示问题。

据我所知,您的代码没有问题。GameSecene.sks将自定义着色器统一传递到着色器中的方式似乎存在错误,导致着色器为0,动画冻结

如果您在代码中而不是在UI生成器中初始化所有内容,那么它可以正常工作。将此粘贴到您的
didMoveToView:
以了解我的意思

SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(100, 100)];
sprite.position = CGPointMake(self.size.width/2, self.size.height/2);
[self addChild:sprite];
SKShader* spin2x = [SKShader shaderWithFileNamed:@"Shader2"];

spin2x.uniforms = @[
                         [SKUniform uniformWithName:@"u_speed" float:(2.0)],
                         ];
sprite.shader = spin2x;

didMoveToView:
中添加类似于下面代码的内容成功了,不知怎的,制服在那里,但着色器无法读取,这些值的“刷新”确实使其正常工作

for (SKSpriteNode *sprite in self.children) {
    if ([sprite isKindOfClass:[SKSpriteNode class]]) {
        for (SKUniform *uniform in sprite.shader.uniforms) {
            if (uniform.uniformType == SKUniformTypeFloat) {
                uniform.floatValue = uniform.floatValue;
            }
        }
    }
}

我找到了另一个线程,它提到了一个类似的问题并解释了这个问题。不能直接在着色器中使用传递的一致性,必须首先将它们指定给变量。在您的制服中,只需添加:float userSpeed=u_speed;然后将u_时间乘以userSpeed,而不是u_速度。这将使它与您的接口生成器定义的统一工作。这里有一个线程对此进行了一些讨论:我认为这是rraallvv在下面处理的同一个问题,即获取您正在传递的实际统一值。如果您想要对统一进行动态更新,则通常需要比在didMoveToView中更新得更多。在更新函数中执行此操作后,我能够获得着色器的更新。遗憾的是,我们似乎无法通过引用统一传递变量,但所有变量都是通过值传递的。