着色器

简介

着色器是在图形处理器上运行的独特程序. 它们用于指定如何获取网格数据(顶点位置, 颜色, 法线等等)然后把它们绘制到屏幕上. 着色器并不像普通程序那样处理信息, 因为它们经过了优化, 可以在图形处理器上运行. 其结果是, 着色器在运行后不会保留数据;它们把最后一种颜色输出到屏幕上, 然后继续. 因此, 无法访问着色器上次运行时的颜色输出.

Godot使用一种与GLSL非常相似的着色语言, 增加了一些功能, 但灵活性稍差. 这样做的原因是Godot集成了内置功能, 使编写复杂着色器变得更加容易.Godot将用户编写的着色器代码封装在自己的代码中. 这样,Godot就可以处理很多用户无需担心的底层内容, 它能够解析着色器代码, 并使用它来影响渲染管道. 对于更高级的着色器, 您可以使用render_mode关闭此功能.

这个文档为您提供了一些特定于Godot的着色器的信息. 有关Godot中着色语言的详细信息, 请参见 Godot 着色语言文档.

着色器类型

Godot着色语言必须指定着色器的用途, 而不是提供通用配置给所有用途(2D, 3D, 粒子). 不同的类型支持不同的渲染模式, 内置变量, 和处理函数.

所有着色器都需要在第一行指定其类型, 格式如下:

shader_type spatial;

有效的类型有:

有关每种着色类型的详细信息, 参见相应的参考文档.

渲染模式

不同的着色器类型支持不同的渲染模式. 它们是可选的, 但如果指定, 则必须位于 shader_type 之后. 渲染模式被用于改变内置功能的处理方式. 一个比较常见的用法是, 通过使用渲染模式 unshaded 来跳过内置的光照处理函数.

渲染模式在着色器类型下面指定:

shader_type spatial;
render_mode unshaded, cull_disabled;

每种着色器类型都有不同的渲染模式列表. 有关渲染模式的完整列表, 请参阅每种着色器类型的文档.

处理器函数

根据着色器的类型, 不同的处理器功能可以被选择性地重写. 对于 "spatial" 和 "canvas_item" , 可以覆盖 vertex , fragmentlight . 对于 "particles" , 只有 vertex 可以被覆盖.

顶点处理器

在 "spatial" 和 "canvas_item" 着色器中, 每一个顶点都要调用一次 vertex 处理函数. 对于 "particles" 着色器, 它对每个粒子都调用一次.

vertex 函数用于修改每个顶点的信息, 这些信息将被传递给片段函数. 它也可以用来建立变量, 这些变量将通过使用variings(见其他文档)被发送到片段函数.

默认情况下,Godot将获取您的顶点信息, 并相应地对其进行转换以便绘制. 如果这是不可用的, 您可以使用渲染模式转换数据;查看 空间着色器文档 来获得这个示例.

片段处理器

fragment 处理函数用于设置每个像素的Godot材质参数. 该代码在对象或基本单元绘制的每个可见像素上运行. 它只在 "spatial" 和 "canvas_item" 着色器中可用.

分段函数的标准用法是设置用于计算光照的材质属性. 例如, 你可以设置 "粗糙度" , "边缘" 或 "传递" 的值, 可以告诉光照功能, 以及光照对这个片段的响应. 这使得控制复杂的着色管道成为可能, 而无需用户编写太多代码. 如果你不需要这个内置功能, 可以忽略它, 编写自己的光照处理函数,Godot会优化它. 例如, 如果你不给 "边缘" 设定一个值,Godot将不计算边缘照明. 编译期间,Godot检查是否使用了 "边缘" ;如果没有, 它将删除所有对应的代码. 因此, 您不会将计算力浪费在不使用的效果上.

光处理器

light 处理也是按像素运行的, 但也为每一个影响物体的光线而运行(如果没有光线影响物体, 则不运行). 它作为一个函数存在于 "fragment" 处理内部, 通常在 "fragment" 函数中设置的材质属性上运行.

light 处理在2D中的工作方式与在3D中的工作方式不同;关于它在每一种情况下的工作方式的描述, 请分别参阅它们的文档, CanvasItem shadersSpatial shaders .