如何在 XCode 中编写 OpenGL ES 片段着色器?
How to write OpenGL ES fragment shaders in XCode?
我正在尝试让我自己的着色器用作 SKSpriteNode 的 SKShader,但我只是不知道正确的方法。我想要的只是一种编写具有自动完成功能的着色器代码并查看着色器而无需等待一些巨大的程序来编译它的方法,但这似乎比我想象的更难。
我已经安装了 GLFW3 和其他一些奇怪的东西,因为大多数教程都建议这样使用 OpenGL,但它似乎更适合整个 OpenGL,而不仅仅是一种特定类型的着色器。
TL;DR:有谁知道一种快速简单的方法来编写着色器以在 SpriteKit 中用作 SKShaders?
让我们从您的角色开始
let spaceship = SKSpriteNode(imageNamed: "Spaceship")
SKShader 对象
您需要将它连接到一个 SKShader
对象
spaceship.shader = SKShader(fileNamed: "MyShader.fsh")
着色器代码
接下来您可以创建 MyShader.fsh
文件并在其中写入片段着色器的逻辑。
在下面的示例中,我将每个像素的 blue
分量设置为 0
void main() {
vec4 color = texture2D(u_texture, v_tex_coord);
color.b = 0.0;
gl_FragColor = color;
}
可以在我的 blog post 上找到一个非常简单的工作 spritekit 着色器。您应该从现有示例着手,而不是从头开始。包含许多指向着色器信息的有用链接。
如果您真的想要自动完成功能,我认为您无法在 Xcode 中实现,但还有其他选择。例如对于 Atom:
https://atom.io/packages/autocomplete-glsl
还有其他东西。虽然自动完成会有所帮助,但还有很多其他方法会导致编译问题。就像通过 Xcode 为 ObjC/Swift 进行正常编码一样......您已经正确地自动完成了代码。但它仍然可以打破。你最好花精力想出一条优化的路径来排除错误并测试你的着色器。
如果您正在试验着色器,您可以设置一个简单的应用程序来进行测试,或者在您的游戏中设置一些隔离模式来执行此操作(我就是这样做的)。
请记住,您不会一直对着色器进行编程。在构建游戏的过程中,这些往往很少而且相差甚远(假设您正在做游戏,如果不是,那么此声明可能无效)。
使用 Xcode 中的 SpriteKit 场景编辑器。当您将着色器源文件与检查器中的节点相关联时,场景视图会立即为您提供该着色器的实时预览效果。
然后您可以使用 Xcode 的辅助编辑器窗格来查看和编辑与场景中当前 selected 节点关联的着色器源 - 完成任何实时预览着色器中的动画(来自 u_time
输入)。
这会让您突出显示语法,但不会自动完成。 Xcode 的完成引擎似乎仅限于它的主要编译器工具链——让它支持一般的着色器对 file a bug 来说当然是一件好事。
编辑着色器源应该更新实时预览,但似乎至少有一些 Xcode 版本你必须重新 select 检查器中的自定义着色器才能进行更改影响。 (这可能也值得 filing a bug...)
上例中的着色器代码(由 Shadertoy via Endless Wave blog 提供):
void main(void) {
vec2 uv = v_tex_coord;
uv.y += (cos((uv.y + (u_time * 0.04)) * 45.0) * 0.0019) +
(cos((uv.y + (u_time * 0.5)) * 10.0) * 0.002);
uv.x += (sin((uv.y + (u_time * 0.07)) * 15.0) * 0.0029) +
(sin((uv.y + (u_time * 0.5)) * 15.0) * 0.002);
gl_FragColor = texture2D(u_texture, uv);
}
我正在尝试让我自己的着色器用作 SKSpriteNode 的 SKShader,但我只是不知道正确的方法。我想要的只是一种编写具有自动完成功能的着色器代码并查看着色器而无需等待一些巨大的程序来编译它的方法,但这似乎比我想象的更难。
我已经安装了 GLFW3 和其他一些奇怪的东西,因为大多数教程都建议这样使用 OpenGL,但它似乎更适合整个 OpenGL,而不仅仅是一种特定类型的着色器。
TL;DR:有谁知道一种快速简单的方法来编写着色器以在 SpriteKit 中用作 SKShaders?
让我们从您的角色开始
let spaceship = SKSpriteNode(imageNamed: "Spaceship")
SKShader 对象
您需要将它连接到一个 SKShader
对象
spaceship.shader = SKShader(fileNamed: "MyShader.fsh")
着色器代码
接下来您可以创建 MyShader.fsh
文件并在其中写入片段着色器的逻辑。
在下面的示例中,我将每个像素的 blue
分量设置为 0
void main() {
vec4 color = texture2D(u_texture, v_tex_coord);
color.b = 0.0;
gl_FragColor = color;
}
可以在我的 blog post 上找到一个非常简单的工作 spritekit 着色器。您应该从现有示例着手,而不是从头开始。包含许多指向着色器信息的有用链接。
如果您真的想要自动完成功能,我认为您无法在 Xcode 中实现,但还有其他选择。例如对于 Atom:
https://atom.io/packages/autocomplete-glsl
还有其他东西。虽然自动完成会有所帮助,但还有很多其他方法会导致编译问题。就像通过 Xcode 为 ObjC/Swift 进行正常编码一样......您已经正确地自动完成了代码。但它仍然可以打破。你最好花精力想出一条优化的路径来排除错误并测试你的着色器。
如果您正在试验着色器,您可以设置一个简单的应用程序来进行测试,或者在您的游戏中设置一些隔离模式来执行此操作(我就是这样做的)。
请记住,您不会一直对着色器进行编程。在构建游戏的过程中,这些往往很少而且相差甚远(假设您正在做游戏,如果不是,那么此声明可能无效)。
使用 Xcode 中的 SpriteKit 场景编辑器。当您将着色器源文件与检查器中的节点相关联时,场景视图会立即为您提供该着色器的实时预览效果。
然后您可以使用 Xcode 的辅助编辑器窗格来查看和编辑与场景中当前 selected 节点关联的着色器源 - 完成任何实时预览着色器中的动画(来自 u_time
输入)。
这会让您突出显示语法,但不会自动完成。 Xcode 的完成引擎似乎仅限于它的主要编译器工具链——让它支持一般的着色器对 file a bug 来说当然是一件好事。
编辑着色器源应该更新实时预览,但似乎至少有一些 Xcode 版本你必须重新 select 检查器中的自定义着色器才能进行更改影响。 (这可能也值得 filing a bug...)
上例中的着色器代码(由 Shadertoy via Endless Wave blog 提供):
void main(void) {
vec2 uv = v_tex_coord;
uv.y += (cos((uv.y + (u_time * 0.04)) * 45.0) * 0.0019) +
(cos((uv.y + (u_time * 0.5)) * 10.0) * 0.002);
uv.x += (sin((uv.y + (u_time * 0.07)) * 15.0) * 0.0029) +
(sin((uv.y + (u_time * 0.5)) * 15.0) * 0.002);
gl_FragColor = texture2D(u_texture, uv);
}