我正在尝试为我正在处理的应用编写片段着色器。我将制服传递到可以工作的着色器,但它适用于整个对象。我希望能够逐像素地修改对象。所以我的代码现在是......
let shader = SKShader( fileNamed: "Shader.fsh" );
shader.addUniform( SKUniform( name: "value", float: 1.0 ) );
m_image.shader = shader;
这里统一的“值”对于所有像素都是相同的。但是,例如,假设我想在绘制一定数量的像素后将“值”更改为“0.0”。所以例如......
shader.addUniform( SKUniform( name: "value", float: 1.0 ) );
// 100 pixels are drawn
shader.addUniform( SKUniform( name: "value", float: 0.0 ) );
SKShader甚至可以实现这一点吗?这是否必须在着色器源中完成?
我想到的一个想法是使用阵列制服,但SKShader似乎不允许这样做。
感谢任何帮助提前。
答案 0 :(得分:2)
一般来说, uniform 这个词意味着不变 - 在所有情况或情况下都是相同的。这就是着色器制服的方式:即使着色器代码独立(并行)为渲染图像中的每个像素运行,输入到着色器的统一变量值在所有像素上都是相同的。
理论上,您可以将一组值传递到着色器中,表示每个像素的颜色,这与传递图像(或仅在精灵上设置纹理图像)基本相同......此时你什么都不使用着色器。
相反,你通常需要你的GLSL(ish *)代码,如果它正在根据像素位置做任何事情,找出它写入的像素坐标并根据它来计算结果。在SKShader
的着色器中,您可以从vec2 v_tex_coord
着色器变量获取像素坐标。
(This看起来像是一个体面的教程(包含其他人的链接),可以开始使用SpriteKit着色器。如果您使用other tutorials或shader code libraries来帮助您使用像素着色器做很酷的事情,您可以找到可以重复使用的想法和算法,但它们找到当前输出像素的方式会有所不同。在SpriteKit的着色器中,您通常可以安全地将gl_FragCoord
替换为v_tex_coord
。)
* SKShader
本身并不使用实际的GLSL,它实际上使用了一个GLSL子集,它自动转换为正在使用的设备/渲染器的相应GPU代码。