将 GLSL 转换为 Godot 着色器

This document explains the differences between Godot's shading language and GLSL and gives practical advice on how to migrate shaders from other sources, such as Shadertoy and The Book of Shaders, into Godot shaders.

关于Godot的着色语言的详细信息, 请参考 Shading Language .

GLSL

Godot使用基于GLSL的着色语言, 增加了一些生活质量特征. 因此,GLSL中提供的大多数功能都可以使用Godot的着色语言.

着色器程序

在GLSL中, 每个着色器使用一个单独的程序. 你有一个用于顶点着色器的程序和一个用于片段着色器的程序. 在Godot中, 你有一个包含 vertex 和/或 fragment 函数的单一着色器. 如果你只选择写一个,Godot会提供另一个.

Godot允许通过在一个文件中定义片段和顶点着色器来共享uniform的变量和函数. 在GLSL中, 顶点和片段程序不能共享变量, 除非是使用varyings的时候.

顶点属性

In GLSL, you can pass in per-vertex information using attributes and have the flexibility to pass in as much or as little as you want. In Godot, you have a set number of input attributes, including VERTEX (position), COLOR, UV, UV2, NORMAL. Each shaders' page in the shader reference section of the documentation comes with a complete list of its vertex attributes.

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及以上版本)中, 变量是通过 inout 关键字来定义的. 一个从顶点着色器出来的变量在顶点着色器中用 out 定义, 在片段着色器中用 in 定义.

主要

在GLSL中, 每个着色器程序看起来都像是一个独立的C风格程序. 因此, 主要入口点是 main . 如果要复制顶点着色器, 请将 main 重命名为 vertex , 如果要复制片段着色器, 请将 main 重命名为 fragment .

The Godot shader preprocessor supports the following macros:

  • #define / #undef

  • #if, #elif, #else, #endif, defined(), #ifdef, #ifndef

  • #include (仅支持 .gdshaderinc 文件,最大深度为 25)

  • #pragma disable_preprocessor ,对文件剩余部分禁用预处理

变量

GLSL 有许多内置的硬编码变量。这些变量不是 uniform,因此它们不能从主程序中编辑。

变量

类型

等价物

描述

gl_FragColor

out vec4

COLOR

每个像素的输出颜色.

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 中,你可以在定义变量时将精度限定词 lowpmediumphighp 放在类型前,根据需要设置单个变量的精度。更多信息请参见着色器语言参考。

Shadertoy

Shadertoy 是一个网站, 它使编写片段着色器和创建 纯正的魔法 变得容易.

Shadertoy 并没有让用户完全控制着色器。它处理所有的输入和 uniform,只让用户编写片段着色器。

类型

Shadertoy使用的是webgl规范, 所以它运行的GLSL版本略有不同. 然而, 它仍然有常规的类型, 包括常量和宏.

mainImage

Shadertoy着色器的主要入口点是 mainImage 函数. mainImage 有两个参数, fragColorfragCoord, 分别对应Godot中的 COLORFRAGCOORD . 这些参数在Godot中是自动处理的, 所以你不需要自己把它们作为参数. 移植到Godot时, mainImage 函数中的任何内容都应复制到 fragment 函数中.

变量

为了让编写片段着色器变得简单明了,Shadertoy为你处理了从主程序传递到片段着色器中的许多有用信息. 其中有一些在Godot中没有对应的信息, 因为Godot选择不在默认情况下提供这些信息. 这没关系, 因为Godot让你有能力制作自己的 uniform。对于那些等价物被列为 "Provide with Uniform" 的变量, 用户有责任自己创建该uniform . 该描述给了读者一个提示, 告诉他们可以传入什么作为替代物.

变量

类型

等价物

描述

fragColor

out vec4

COLOR

每个像素的输出颜色.

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 提供了在网络浏览器中访问片段着色器的机会,用户可以与之互动,但只限于编写片段着色器代码,其中有一组传入的 uniform 列表,不能添加额外的 uniform。

有关将着色器移植到各种框架的进一步帮助,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

COLOR

每个像素的输出颜色.

gl_FragCoord

vec4

FRAGCOORD

用于全屏四边形. 对于较小的四边形, 使用UV.

u_resolution

vec2

1.0 / SCREEN_PIXEL_SIZE

也可以手动传递.

u_time

浮点数

TIME

着色器启动后的时间.

u_mouse

vec2

提供Uniform

鼠标在像素坐标中的位置.

坐标

Shaders使用相同的坐标系 GLSL.