Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw an SKShapeNode line color-gradient from one color to another

I'm writing an App for iPad and iOS 10. I'm using Objective-C and SpriteKit.

I need to draw a line that starts in one color and ends in another color (eg. red to green).

This is my Objective-C code:

CGPoint points[2];
points[0] = CGPointMake(100, 100);
points[1] = CGPointMake(160, 110);

SKShapeNode *line1=[SKShapeNode shapeNodeWithPoints:points count:2];
line1.lineWidth = 2.0;
line1.zPosition = -1;
line1.name=@"line";
SKShader *myShader=[SKShader shaderWithFileNamed:@"shader1.fsh"];
line1.strokeShader=myShader;
[self addChild:line1];

And this is the shader:

void main(){

float length = u_path_length;
float distance = v_path_distance;


gl_FragColor = vec4(1.0*(1-(distance/length)), 1.0*(distance/length), 0., 1.);
}

When I run the App I get the error (related to Metal): failed assertion 'missing buffer binding at index 1 for u_path_length[0].'

It looks like u_path_length and v_path_distance don't work in iOS 10.

Can you help solve this problem? Or can you suggest a different solution to the problem?

like image 921
danyadd Avatar asked Nov 28 '25 17:11

danyadd


1 Answers

If I add the PrefersOpenGL key with a bool value of YES in the Info.plist file, the error (related to Metal) disappears. Of course this means that my App will not use Metal. I suppose this is a bug in iOS 10.

I faced another problem: v_path_distance works as expect but u_path_length doesn't. u_path_length is always = 0.

To solve the problem I had to modify my code.

This is my Objective-C code:

CGPoint points[2]; 
points[0] = CGPointMake(100, 100); 
points[1] =  CGPointMake(160, 110);

SKShapeNode *line1=[SKShapeNode shapeNodeWithPoints:points count:2];
line1.lineWidth = 2.0; 
line1.zPosition = -1; 
line1.name=@"line"; 
SKShader *myShader=[SKShader shaderWithFileNamed:@"shader1.fsh"];   
float my_length=hypotf(points[1].x-points[0].x, points[1].y-points[0].y); 
myShader.uniforms=@[[SKUniform uniformWithName:@"u_my_length" float:my_length]];
line1.strokeShader=myShader; 
[self addChild:line1];

And this is the shader:

void main(){    

gl_FragColor=vec4(1.0*(1.0-(v_path_distance/u_my_length)),1.0*(v_path_distance/u_my_length),0.,1.0);

}
like image 104
danyadd Avatar answered Nov 30 '25 06:11

danyadd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!