迁移到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 (坐标)、 COLORUVUV2NORMAL .完整的列表,请参见 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及以上版本)中,变量是通过 inout 关键字来定义的.一个从顶点着色器出来的变量在顶点着色器中用 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 有两个参数, fragColorfragCoord,分别对应Godot中的 COLORFRAGCOORD .这些参数在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.