Ios 在Interface Builder(Xcode)中使用来自Shadertoy的着色器
我正在尝试使用sprite工具包查看Interface Builder中的着色器的外观,并希望在中使用一些着色器。为此,我创建了一个“shader.fsh”文件,一个场景文件,并在场景中添加了一个颜色精灵,为其提供了一个自定义着色器(shader.fsh) 虽然非常基本的着色器似乎可以工作:Ios 在Interface Builder(Xcode)中使用来自Shadertoy的着色器,ios,opengl,opengl-es,interface-builder,pixel-shader,Ios,Opengl,Opengl Es,Interface Builder,Pixel Shader,我正在尝试使用sprite工具包查看Interface Builder中的着色器的外观,并希望在中使用一些着色器。为此,我创建了一个“shader.fsh”文件,一个场景文件,并在场景中添加了一个颜色精灵,为其提供了一个自定义着色器(shader.fsh) 虽然非常基本的着色器似乎可以工作: void main() { gl_FragColor = vec4(0.0,1.0,0.0,1.0); } 我从中转换着色器的任何尝试都会导致Xcode在渲染它们时立即冻结(旋转颜色球) 例如,我
void main() {
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
}
我从中转换着色器的任何尝试都会导致Xcode在渲染它们时立即冻结(旋转颜色球)
例如,我正在使用的着色器是:
我试过:
- 将mainImage()替换为main(void)(以便调用它)
- 将iXxxxx变量(iGlobalTime、iResolution)和fragCoord变量替换为它们的相关变量(基于建议)
- 正在替换某些变量(iGlobalTime)
将mainImage更改为main()并调出变量,使其在realtime tester应用程序中正常工作,而在Xcode中结果总是一样的(旋转球,冻结)。这里的任何建议都会很有帮助,因为目前关于这个主题的信息非常少。我使用SpriteKit成功地实现了这一点。到目前为止,我已经能够渲染ShaderToy中的每个着色器。唯一的例外是您必须使用
iMouse
删除任何代码,因为iOS中没有鼠标。我做了以下的
1)将着色器中的main图像
函数声明更改为
void main(void) {
...
}
ShaderToymain image
函数有一个名为fragCoord
的输入。在iOS中,它作为gl_FragCoord
全局可用,因此您的main
功能不再需要任何输入
2)执行“全部替换”,将以下内容从其ShaderToy名称更改为其iOS名称
变成fragCoord
gl\u fragCoord
变为fragColor
gl\u fragColor
变为iGlobalTime
u\u时间
iResolution
稍微复杂一些
iResolution
是视口大小(以像素为单位),转换为SpriteKit中的精灵大小。在iOS中,它以前以u\u sprite\u size
的形式提供,但已被删除。幸运的是,苹果提供了一个很好的例子,说明了如何使用它们的
然而,如ShaderToy的着色器输入
部分所述,iResolution
的类型是vec3
(x、y和z),而不是u sprite_size
,即vec2
(x和y)。我还没有看到使用iResolution
的z
值的单个着色器。因此,我们可以简单地使用z
值为零。我修改了苹果文档中的示例,为我的着色器提供了iResolution
,类型为vec3
,就像这样
let uniformBasedShader = SKShader(fileNamed: "YourShader.fsh")
let sprite = SKSpriteNode()
sprite.shader = uniformBasedShader
let spriteSize = vector_float3(
Float(sprite.frame.size.width), // x
Float(sprite.frame.size.height), // y
Float(0.0) // z - never used
)
uniformBasedShader.uniforms = [
SKUniform(name: "iResolution", vectorFloat3: spriteSize)
]
就是这样:)以下是对着色器的更改,该着色器在使用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左右会给人一种很好的感觉
第三项是大部分魔法发生的地方,这是恒星的大小和脉冲
float t = 0.9
更改为0.9,将增加初始星号向上或向下,一个很好的值是1.4,不要太大也不要太小
float t = 0.9 + 0.2
将这个等式中的第二个值更改为0.2,将使恒星的脉冲效应宽度与我喜欢的原始大小成比例地增加,1.4 a值为1.2
要将着色器添加到swift项目中,请向场景中添加屏幕大小的精灵,然后按如下方式添加着色器:
let backgroundImage = SKSpriteNode()
backgroundImage.texture = textureAtlas.textureNamed("any )
backgroundImage.size = screenSize
let shader = SKShader(fileNamed: "nightSky.fsh")
backgroundImage.shader = shader
关于这个问题有什么消息吗?@salocinx-我已经放弃了。你有相同的问题吗?不是完全相同的问题。。。我试着编译这个:正如你所建议的,我也阅读了链接页面。我还用对应的字段替换了每个未知字段,并相应地更改了main的签名。但我收到一些“非常量引用无法绑定到向量元素”错误。到目前为止,简单着色器的X代码还没有挂起,但着色器矩阵函数的实现方式似乎与WebGL着色器语言的实现方式不同。。。苹果的做法与世界其他地方不同——再一次……;-)
let backgroundImage = SKSpriteNode()
backgroundImage.texture = textureAtlas.textureNamed("any )
backgroundImage.size = screenSize
let shader = SKShader(fileNamed: "nightSky.fsh")
backgroundImage.shader = shader