2016-11-05 205 views
3

我正在为iPad和iOS 10编写一个应用程序。 我正在使用Objective-C和SpriteKit。绘制一个SKShapeNode线条颜色渐变从一种颜色到另一种

我需要绘制一条以一种颜色开始并以另一种颜色结束的线条(例如红色到绿色)。

这是我的Objective-C代码:

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; 
[email protected]"line"; 
SKShader *myShader=[SKShader shaderWithFileNamed:@"shader1.fsh"]; 
line1.strokeShader=myShader; 
[self addChild:line1]; 

这是着色器:

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.); 
} 

当我运行的应用程序出现错误(与金属): 失败的断言'在u_path_length [0]的索引1处缺少缓冲区绑定。'

它看起来像u_path_length和v_path_distance不iOS的10

工作,你可以帮助解决这个问题? 或者你能否提出一个不同的解决方案?

+0

不知道这是否可以以某种方式帮助,还是会在性能影响你的情况:http://stackoverflow.com/q/34422374。或者你可以看看这个:http://stackoverflow.com/a/36261550/3402095 – Whirlwind

+0

@Whirlwind感谢您的建议,但您链接的解决方案将创建一个图像,然后可以用作纹理。问题是SKShapeNode不能很好地处理纹理(不能控制纹理大小),这就是为什么我想使用着色器。 我需要在屏幕上绘制很多这些线(至少100)。目前我正在考虑使用带着色器(我认为是最好的解决方案)的SKShapeNode或带有来自资产(我已经有工作代码)的图像的SKSpriteNode。 – danyadd

+0

理想情况下,您完全不应该使用SKShapeNode,因为一个SKShapeNode需要一次绘制调用。意思是,你可能会很快遇到性能问题。与可以批量绘制的SKSpriteNode不同,SKShapeNodes不能,也不能像使用文档中指出的那样谨慎使用SKShapeNode。所以如果屏幕上同时出现超过10-15个实例,我会亲自避免它。 – Whirlwind

回答

1

如果我在Info.plist文件中添加了bool值为YES的PrefersOpenGL键,则该错误(与Metal有关)将消失。 当然这意味着我的应用程序不会使用Metal。 我想这是iOS 10中的一个bug。

我遇到了另一个问题:v_path_distance按预期工作,但u_path_length没有。 u_path_length始终为0.

要解决此问题,我必须修改我的代码。

这是我的Objective-C代码:

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; 
[email protected]"line"; 
SKShader *myShader=[SKShader shaderWithFileNamed:@"shader1.fsh"]; 
float my_length=hypotf(points[1].x-points[0].x, points[1].y-points[0].y); 
[email protected][[SKUniform uniformWithName:@"u_my_length" float:my_length]]; 
line1.strokeShader=myShader; 
[self addChild:line1]; 

这是着色器:

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); 

} 
相关问题