Converting GLSL to Godot shaders
本文档解释了Godot的着色语言和GLSL之间的区别, 并提供了有关如何将着色器从其他来源(如Shadertoy和The Book of Shaders)迁移到Godot着色器的实用建议.
关于Godot的着色语言的详细信息, 请参考 Shading Language .
GLSL
Godot使用基于GLSL的着色语言, 增加了一些生活质量特征. 因此,GLSL中提供的大多数功能都可以使用Godot的着色语言.
着色器程序
在GLSL中, 每个着色器使用一个单独的程序. 你有一个用于顶点着色器的程序和一个用于片段着色器的程序. 在Godot中, 你有一个包含 vertex
和/或 fragment
函数的单一着色器. 如果你只选择写一个,Godot会提供另一个.
Godot允许通过在一个文件中定义片段和顶点着色器来共享uniform的变量和函数. 在GLSL中, 顶点和片段程序不能共享变量, 除非是使用varyings的时候.
顶点属性
在GLSL中, 你可以使用属性来传递每个顶点的信息, 并且可以灵活地传递你想要的信息, 或多或少. 在Godot中, 你有一系列的输入属性, 包括 VERTEX
(坐标), COLOR
, UV
, UV2
, NORMAL
. 完整的列表, 请参见 Shading language reference .
gl_Position
gl_Position
接收在顶点着色器中指定的顶点的最终坐标. 它是由用户在裁剪空间中指定的. 通常, 在GLSL中, 模型空间的顶点位置是通过一个名为 position
的顶点属性来传递的, 你可以手动处理从模型空间到裁剪空间的转换.
在Godot中, VERTEX
指定了 vertex
函数开始时在模型空间的顶点位置. 在用户定义的 vertex
函数运行后,Godot也会处理最终转换到裁剪空间的过程. 如果你想跳过从模型空间到视图空间的转换, 你可以将 render_mode
设置为 skip_vertex_transform
. 如果你想跳过所有的转换, 将 render_mode
设置为 skip_vertex_transform
并将 PROJECTION_MATRIX
设置为 mat4(1.0)
, 以便使从视图空间到裁剪空间的最终转换失效.
Varying
varyings是一种变量, 可以从顶点着色器传递到片段着色器. 在现代GLSL(3.0及以上版本)中, 变量是通过 in
和 out
关键字来定义的. 一个从顶点着色器出来的变量在顶点着色器中用 out
定义, 在片段着色器中用 in
定义.
主要
在GLSL中, 每个着色器程序看起来都像是一个独立的C风格程序. 因此, 主要入口点是 main
. 如果要复制顶点着色器, 请将 main
重命名为 vertex
, 如果要复制片段着色器, 请将 main
重命名为 fragment
.
常量
全局数组常量在Godot 3.x中不被支持. 你可以通过使用一个初始化为该值的uniform来伪造功能, 但你不会从使用常量所带来的速度提升中获益.
宏
为了与C的相似性,GLSL允许您使用宏. 通常 #define
用于定义常量或小段函数. 没有直接的方法将定义翻译成Godot的着色语言. 如果它是一个已定义的函数, 则用函数替换, 如果它是常量, 则用uniform替换. 对于其他宏( #if
, #ifdef
等), 没有等价物, 因为它们在编译的预处理阶段运行.
变量
GLSL有许多内置的硬编码变量. 这些变量不是uniforms, 因此它们不能从主程序中编辑.
变量 | 类型 | 等价物 | 描述 |
---|---|---|---|
gl_FragColor | out vec4 | 颜色 | 每个像素的输出颜色. |
gl_FragCoord | vec4 | FRAGCOORD | 用于全屏四边形. 对于较小的四边形, 使用UV. |
gl_Position | vec4 | VERTEX | 顶点的位置, 从顶点着色器输出. |
gl_PointSize | (单精度)浮点数 | POINT_SIZE | Point原语的大小. |
gl_PointCoord | vec2 | POINT_COORD | 绘制Point基元时在点上的位置. |
gl_FrontFacing | bool | FRONT_FACING | 如果原始的正面, 则为真. |
坐标
GLSL中的 gl_FragCoord
和Godot着色语言中的 FRAGCOORD
使用相同的坐标系. 如果在Godot中使用UV, 则y坐标将颠倒翻转.
精确
在GLSL中, 你可以用 precision
关键字在着色器的顶部定义一个给定类型的精度(float或int). 在Godot中, 你可以在定义变量时将精度限定词 lowp
, mediump
, and highp
放在类型前, 根据需要设置单个变量的精度. 更多信息, 请参见 Shading Language 参考.
Shadertoy
Shadertoy 是一个网站, 它使编写片段着色器和创建 纯正的魔法 变得容易.
Shadertoy并没有让用户完全控制着色器. 它处理所有的输入和uniforms, 只让用户编写片段着色器.
类型
Shadertoy使用的是webgl规范, 所以它运行的GLSL版本略有不同. 然而, 它仍然有常规的类型, 包括常量和宏.
mainImage
Shadertoy着色器的主要入口点是 mainImage
函数. mainImage
有两个参数, fragColor
和 fragCoord
, 分别对应Godot中的 COLOR
和 FRAGCOORD
. 这些参数在Godot中是自动处理的, 所以你不需要自己把它们作为参数. 移植到Godot时, mainImage
函数中的任何内容都应复制到 fragment
函数中.
变量
为了让编写片段着色器变得简单明了,Shadertoy为你处理了从主程序传递到片段着色器中的许多有用信息. 其中有一些在Godot中没有对应的信息, 因为Godot选择不在默认情况下提供这些信息. 这没关系, 因为Godot让你有能力制作自己的uniforms. 对于那些等价物被列为 “Provide with Uniform” 的变量, 用户有责任自己创建该uniform . 该描述给了读者一个提示, 告诉他们可以传入什么作为替代物.
变量 | 类型 | 等价物 | 描述 |
---|---|---|---|
fragColor | out vec4 | 颜色 | 每个像素的输出颜色. |
fragCoord | vec2 | FRAGCOORD.xy | 用于全屏四边形. 对于较小的四边形, 使用UV. |
iResolution | vec3 | 1.0 / SCREEN_PIXEL_SIZE | 也可以手动传递. |
iTime | (单精度)浮点数 | TIME | 着色器启动后的时间. |
iTimeDelta | (单精度)浮点数 | 提供Uniform | 渲染前一帧的时间. |
iFrame | (单精度)浮点数 | 提供Uniform | 帧号. |
iChannelTime[4] | (单精度)浮点数 | 提供Uniform | 自该特定纹理开始的时间。 |
iMouse | vec4 | 提供Uniform | 鼠标在像素坐标中的位置. |
iDate | vec4 | 提供Uniform | 当前日期, 以秒为单位表示. |
iChannelResolution[4] | vec3 | 1.0 / TEXTURE_PIXEL_SIZE | 特殊纹理的分辨率. |
iChanneli | Sampler2D | Texture (纹理) | Godot只提供一个内置;用户可以制作更多. |
坐标
fragCoord
的行为与 gl_FragCoord
相同 GLSL 和Godot中的 FRAGCOORD
.
着色之书
与Shadertoy类似, The Book of Shaders 提供了在网络浏览器中访问片段着色器的机会, 用户可以与之互动, 但只限于编写片段着色器代码, 其中有一组传入的uniforms列表, 而不能添加额外的uniforms.
有关将着色器移植到各种框架的进一步帮助,The Book of Shaders在各种框架中运行着色器时提供了一个 page .
类型
The Book of Shaders使用webgl规范, 因此它运行的GLSL略有不同. 但是, 它仍然具有常规类型, 包括常量和宏.
主要
Book of Shaders片段着色器的入口点是 main
, 就像在GLSL中一样. 使用着色器 main
函数编写的所有内容都应该复制到Godot的 fragment
函数中.
变量
着色书比Shadertoy更接近普通GLSL. 它也比Shadertoy实施更少的制服.
变量 | 类型 | 等价物 | 描述 |
---|---|---|---|
gl_FragColor | out vec4 | 颜色 | 每个像素的输出颜色. |
gl_FragCoord | vec4 | FRAGCOORD | 用于全屏四边形. 对于较小的四边形, 使用UV. |
u_resolution | vec2 | 1.0 / SCREEN_PIXEL_SIZE | 也可以手动传递. |
u_time | (单精度)浮点数 | TIME | 着色器启动后的时间. |
u_mouse | vec2 | 提供Uniform | 鼠标在像素坐标中的位置. |
坐标
Shaders使用相同的坐标系 GLSL.