gpt4 book ai didi

ios - 在 Interface Builder (Xcode) 中使用来自 Shadertoy 的着色器

转载 作者:可可西里 更新时间:2023-11-01 05:20:03 39 4
gpt4 key购买 nike

我正在尝试使用 sprite 套件查看 Interface Builder 中的着色器,并希望使用 ShaderToy 中的一些着色器。 .为此,我创建了一个“shader.fsh”文件,一个场景文件,并向场景添加了一个颜色 Sprite ,为其提供了一个自定义着色器 (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);
}

我试过:

  • 用 main(void) 替换 mainImage()(以便调用它)
  • 用相关变量替换 iXxxxx 变量(iGlobalTime、iResolution)和 fragCoord 变量(基于建议 here )
  • 替换一些变量 (iGlobalTime)...

在将 mainImage 更改为 main() 并换出变量时,它可以在 TinyShading 中无错误地工作实时测试器应用程序 - Xcode 中的结果始终相同(旋转球、卡住)。这里的任何建议都会有所帮助,因为目前关于该主题的可用信息少得惊人。

最佳答案

我设法使用 SKShader 在 SpriteKit 中实现了这个功能.到目前为止,我已经能够从 ShaderToy 渲染每个着色器。唯一的异常(exception)是您必须使用 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 是视口(viewport)大小(以像素为单位),在 SpriteKit 中转换为 Sprite 大小。这曾经在 iOS 中作为 u_sprite_size 提供,但已被删除。幸运的是,Apple 提供了一个很好的示例,说明如何使用 uniforms 将其注入(inject)到着色器中。在他们的 SKShader documentation .

但是,正如ShaderToy的Shader Inputs部分所述,iResolution的类型是vec3(x , y 和 z) 与 u_sprite_size 相反,它是 vec2(x 和 y)。我还没有看到使用 iResolutionz 值的单个 ShaderToy。因此,我们可以简单地使用零值的 z。我修改了 Apple 文档中的示例,为我的着色器提供类型为 vec3iResolution,就像这样...

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

就是这样:)

关于ios - 在 Interface Builder (Xcode) 中使用来自 Shadertoy 的着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33244362/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com