SpriteKit 着色器未与制服一起运行

Posted

技术标签:

【中文标题】SpriteKit 着色器未与制服一起运行【英文标题】:SpriteKit Shader not running with Uniforms 【发布时间】:2016-03-27 01:13:50 【问题描述】:

// 贴出来以防万一有人遇到同样的问题。

原来的问题:

将着色器移植到 OSX,并尝试为其提供制服。着色器实际上并没有运行。

这是在:XCode 7.3 ,Swift 2 。

GameScene.swift :

var myShader = SKShader();

override func didMoveToView(view: SKView) 

    //////////////////////////////////
    // Create SKShader
    let shaderContainer = SKSpriteNode(color: NSColor.grayColor(), size: CGSizeMake(300, 300));
    shaderContainer.position = CGPointMake(self.frame.width/2, self.frame.height/2);

    self.addChild(shaderContainer);

    myShader = SKShader(fileNamed: "color-wheel.fsh");
    let utest = SKUniform(name: "utest", float: 0.3);
    myShader.addUniform(utest);

    shaderContainer.shader = myShader;

color-wheel.fsh(着色器):

#define PI 3.14159265359
#define TWO_PI 6.28318530718

//  Function from Iñigo Quiles
//  https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c )
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), 6.0)-3.0)-1.0, 0.0, 1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix(vec3(1.0), rgb, c.y);


void main (void) 
    vec2 st = v_tex_coord; // SPRITEKIT SPECIFIC

    vec3 color = vec3(0.0);

    // Using Polar Coordinates instead of Cartesian
    vec2 vectorToCentre = vec2(0.5) - st;
    float angle = atan(vectorToCentre.y, vectorToCentre.x); // function is atan(y,x) , not x,y
    float distanceToCentre = length(vectorToCentre);
    float radius = distanceToCentre * 2.0;
    angle = angle + u_time*0.6 - radius*2.5;

    vec3 hue = vec3(angle/TWO_PI+0.5, radius, 1.0) * vec3(1.0, 0.4, 1.0);
    color = hsb2rgb(hue);

    gl_FragColor = vec4(color, 1.0);

【问题讨论】:

【参考方案1】:

经过一番尝试后发现。

解决方案:

在这种情况下(XCode 7.3),如果着色器使用制服,并且#defines,#defines 不能在第零行,例如;

color-wheel.fsh(着色器):

// BLANK LINE HERE
#define PI 3.14159265359
#define TWO_PI 6.28318530718

...

我想 ios 可能也需要类似的考虑。

【讨论】:

【参考方案2】:

您的问题是您从未在着色器中声明制服。在着色器中的某个地方你应该有

uniform float utest

我怀疑你对 utest 和 u_time 感到困惑,这是 ios 上内置的 glsl 统一

编辑:实际上,我错了。设置制服时不必在 ios 中声明制服。事实上,如果你这样做,它们会破坏着色器。因此,在您的情况下,错误是您声明了一个名称错误的制服(例如,着色器中未使用的制服名称)

【讨论】:

以上是关于SpriteKit 着色器未与制服一起运行的主要内容,如果未能解决你的问题,请参考以下文章

GLSL 着色器未编译,没有错误消息

Xcode 7 / iOS 9:在 SKNode 中使用 OpenGL 片段着色器未编译

顶点着色器 -> 几何着色器,错误“获取非活动制服的位置”

ThreeJS 预定义着色器属性/制服

未绑定着色器时,制服集和顶点属性值是不是保留

如何使用 Swift 将 Float 制服传递给 iOS 金属着色器?