迁移到Godot着色语言
简介
本文档解释了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)
,以便使从视图空间到裁剪空间的最终转换失效.
Varyings
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
放在类型前,根据需要设置单个变量的精度.更多信息,请参见 :ref:`Shading Language <doc_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``相同 :ref:`GLSL <glsl_coordinates>` 和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.