我试图使用精灵工具包在Interface Builder中查看着色器的样子,并想在ShaderToy使用一些着色器。为此,我创建了一个" shader.fsh"文件,场景文件,并在场景中添加了一个颜色精灵,为它提供了一个自定义着色器(shader.fsh)
虽然非常基本的着色器似乎有效:
void main() {
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
}
我试图从ShaderToy转换着色器会导致Xcode在尝试渲染时立即冻结(旋转彩球)。
我正在使用的着色器是this one:
#define M_PI 3.1415926535897932384626433832795
float rand(vec2 co)
{
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float size = 30.0;
float prob = 0.95;
vec2 pos = floor(1.0 / size * fragCoord.xy);
float color = 0.0;
float starValue = rand(pos);
if (starValue > prob)
{
vec2 center = size * pos + vec2(size, size) * 0.5;
float t = 0.9 + 0.2 * sin(iGlobalTime + (starValue - prob) / (1.0 - prob) * 45.0);
color = 1.0 - distance(fragCoord.xy, center) / (0.5 * size);
color = color * t / (abs(fragCoord.y - center.y)) * t / (abs(fragCoord.x - center.x));
}
else if (rand(fragCoord.xy / iResolution.xy) > 0.996)
{
float r = rand(fragCoord.xy);
color = r * (0.25 * sin(iGlobalTime * (r * 5.0) + 720.0 * r) + 0.75);
}
fragColor = vec4(vec3(color), 1.0);
}
我试过了:
将mainImage更改为main()并交换变量使其在TinyShading实时测试器应用程序中无错误地工作 - 结果在Xcode(旋转球,冻结)中始终相同。这里的任何建议都会有所帮助,因为目前有关该主题的信息量非常少。
答案 0 :(得分:5)
我设法使用SKShader在SpriteKit中使用它。我已经能够渲染ShaderToy的每个着色器,这是迄今为止我尝试过的。唯一的例外是您必须使用iMouse
删除任何代码,因为iOS中没有鼠标。我做了以下......
1)将ShaderToy中的mainImage
函数声明更改为...
void main(void) {
...
}
ShaderToy mainImage
函数有一个名为fragCoord
的输入。在iOS中,这是gl_FragCoord
全局可用,因此您的main
函数不再需要任何输入。
2)执行全部替换,将ShaderToy名称中的以下内容更改为iOS名称...
fragCoord
变为gl_FragCoord
fragColor
变为gl_FragColor
iGlobalTime
变为u_time
注意:还有更多我还没有遇到过。我会像我一样更新
3)提供iResolution
稍微复杂一些......
iResolution
是视口大小(以像素为单位),转换为SpriteKit中的精灵大小。以前这在iOS中可用作u_sprite_size
,但已被删除。幸运的是,Apple提供了一个很好的示例,说明如何使用uniforms中的SKShader documentation将其注入着色器。
然而,如ShaderToy的Shader Inputs
部分所述,iResolution
的类型为vec3
(x,y和z),而不是{{ 1}},即u_sprite_size
(x和y)。我还没有看到使用vec2
z
值的单个ShaderToy。因此,我们可以简单地使用零iResolution
值。我修改了Apple文档中的示例,为我的着色器提供z
类型iResolution
,如此...
vec3
就是这样:))
答案 1 :(得分:2)
以下是使用swift加载为着色器时着色器的更改:
#define M_PI 3.1415926535897932384626433832795
float rand(vec2 co);
float rand(vec2 co)
{
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
float size = 50.0; //Item 1:
float prob = 0.95; //Item 2:
vec2 pos = floor(1.0 / size * gl_FragCoord.xy);
float color = 0.0;
float starValue = rand(pos);
if (starValue > prob)
{
vec2 center = size * pos + vec2(size, size) * 0.5;
float t = 0.9 + 0.2 * sin(u_time + (starValue - prob) / (1.0 - prob) * 45.0); //Item 3:
color = 1.0 - distance(gl_FragCoord.xy, center) / (0.9 * size);
color = color * t / (abs(gl_FragCoord.y - center.y)) * t / (abs(gl_FragCoord.x - center.x));
}
else if (rand(v_tex_coord) > 0.996)
{
float r = rand(gl_FragCoord.xy);
color = r * (0.25 * sin(u_time * (r * 5.0) + 720.0 * r) + 0.75);
}
gl_FragColor = vec4(vec3(color), 1.0);
}
玩物品1:增加天空中的星星数量越小数字越多我喜欢的数字大约为50不太密集 第2项:改变随机性或恒星出现的距离1 =无,0.1 =并排在0.75附近给人一种不错的感觉。
第3项是大多数魔法发生的地方,这就是恒星的大小和脉冲。
float t = 0.9
改变0.9,会增加初始星形符号的上升或下降一个好的值是1.4不太大而不是太小。
float t = 0.9 + 0.2
更改此等式0.2中的第二个值,将增加星形的脉冲效果宽度,与原始尺寸成比例,我喜欢1.4值1.2。
要将着色器添加到swift项目中,请将精灵添加到屏幕大小的场景中,然后像这样添加着色器:
let backgroundImage = SKSpriteNode()
backgroundImage.texture = textureAtlas.textureNamed("any )
backgroundImage.size = screenSize
let shader = SKShader(fileNamed: "nightSky.fsh")
backgroundImage.shader = shader