GLSL 编程/Unity/最小着色器
本教程介绍了在 Unity 中创建最小 GLSL 着色器的基本步骤。
下载并启动 Unity 后(Windows 用户必须使用命令行参数-force-opengl
),您可能会看到一个空项目。如果不是,您应该通过从菜单中选择文件 > 新项目...来创建一个新项目。对于本教程,您不需要导入任何包,但一些更高级的教程需要脚本和天空盒包。在 Windows 上创建新项目后,Unity 可能会在没有 OpenGL 支持的情况下启动;因此,Windows 用户应始终在创建新项目后退出 Unity 并重新启动它(使用命令行参数-force-opengl
)。然后,您可以通过从菜单中选择文件 > 打开项目...来打开新项目。
如果您不熟悉 Unity 的场景视图、层次结构视图、项目视图和检查器视图,现在是阅读 Unity 用户指南 的前两个(或三个)部分(“Unity 基础”和“构建场景”)的最佳时机。
创建 GLSL 着色器并不复杂:在项目视图中,点击创建并选择着色器。一个名为“NewShader”的新文件应出现在项目视图中。双击它打开它(或右键单击并选择打开)。将出现一个包含 Cg 中默认着色器的编辑器。删除所有文本,并将以下着色器复制并粘贴到此文件中
Shader "GLSL basic shader" { // defines the name of the shader
SubShader { // Unity chooses the subshader that fits the GPU best
Pass { // some shaders require multiple passes
GLSLPROGRAM // here begins the part in Unity's GLSL
#ifdef VERTEX // here begins the vertex shader
void main() // all vertex shaders define a main() function
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// this line transforms the predefined attribute
// gl_Vertex of type vec4 with the predefined
// uniform gl_ModelViewProjectionMatrix of type mat4
// and stores the result in the predefined output
// variable gl_Position of type vec4.
}
#endif // here ends the definition of the vertex shader
#ifdef FRAGMENT // here begins the fragment shader
void main() // all fragment shaders define a main() function
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
// this fragment shader just sets the output color
// to opaque red (red = 1.0, green = 0.0, blue = 0.0,
// alpha = 1.0)
}
#endif // here ends the definition of the fragment shader
ENDGLSL // here ends the part in GLSL
}
}
}
保存着色器(通过点击保存图标或从编辑器的菜单中选择文件 > 保存)。
恭喜您,您刚刚在 Unity 中创建了一个着色器。如果您愿意,可以通过单击名称、输入新名称并按回车键来重命名项目视图中的着色器文件。(重命名后,重新打开编辑器中的着色器以确保您正在编辑正确的文件。)
不幸的是,在将着色器附加到材质之前,您什么也看不到。
要创建材质,请返回 Unity 并通过在项目视图中点击创建并选择材质来创建一个新材质。一个名为“New Material”的新材质应出现在项目视图中。(您可以像着色器一样重命名它。)如果它没有被选中,请通过点击选择它。有关材质的详细信息现在将显示在检查器视图中。为了将着色器设置为该材质,您可以
- 将项目视图中的着色器拖放到材质上,或者
- 在项目视图中选择材质,然后在检查器视图中从标记为着色器的下拉列表中选择着色器(在本例中为“GLSL 基本着色器”,如上面的着色器代码中所指定)。
无论哪种情况,材质的检查器视图中的预览现在都应显示一个红色球体。如果它没有显示,并且 Unity 窗口底部显示错误消息,您应该重新打开着色器,并在编辑器中检查文本是否与上面给出的文本相同。Windows 用户应确保通过使用命令行参数-force-opengl
重新启动 Unity 来支持 OpenGL。
现在是玩弄着色器的好时机;特别是,您可以轻松地更改计算的片段颜色。通过打开着色器并将片段着色器替换为此代码来尝试霓虹绿色
#ifdef FRAGMENT
void main()
{
gl_FragColor = vec4(0.6, 1.0, 0.0, 1.0);
// red = 0.6, green = 1.0, blue = 0.0, alpha = 1.0
}
#endif
您必须在编辑器中保存代码并再次激活 Unity 窗口以应用新的着色器。如果您在项目视图中选择材质,检查器视图中的球体现在应为绿色。您也可以尝试修改红色、绿色和蓝色组件以找到最温暖的橙色或最深的蓝色。(实际上,有一部关于寻找最温暖的橙色的 电影 和一部关于几乎是黑色的深蓝色的 另一部 电影。)
您也可以玩弄顶点着色器,例如尝试此顶点着色器
#ifdef VERTEX
void main()
{
gl_Position = gl_ModelViewProjectionMatrix
* (vec4(1.0, 0.1, 1.0, 1.0) * gl_Vertex);
}
#endif
这将通过将 坐标乘以 来使任何输入几何体变平。(这是一个分量级的向量积;有关 GLSL 中向量和矩阵的更多信息,请参阅 “向量和矩阵运算”部分 的讨论。)
如果着色器无法编译,Unity 将在 Unity 窗口底部显示一条错误消息,并将材质显示为亮紫色。为了查看所有错误消息和警告,您应该在项目视图中选择着色器,并在检查器视图中阅读消息,其中还包括行号,您可以在文本编辑器中通过在文本编辑器菜单中选择查看 > 行号来显示这些行号。您也可以通过从菜单中选择窗口 > 控制台来打开控制台视图,但这不会显示所有错误消息,因此通常不会报告关键错误。
我们还有最后一步要走:将新材质附加到三角形网格。为此,请通过从菜单中选择游戏对象 > 创建其他 > 球体来创建一个球体(它是 Unity 的预定义游戏对象之一)。一个球体应出现在场景视图中,标签“球体”应出现在层次结构视图中。(如果它没有出现在场景视图中,请在层次结构视图中点击它,将鼠标悬停在场景视图上,然后按“f”。球体现在应该出现在场景视图的中心。)
要将材质附加到新球体,您可以
- 将项目视图中的材质拖放到层次结构视图中的球体上,或者
- 将项目视图中的材质拖放到场景视图中的球体上,或者
- 在层次结构视图中选择球体,在检查器视图中找到网格渲染器组件(如果它没有打开,请通过点击标题打开它),通过点击打开网格渲染器的材质设置。通过点击材质名称右侧的点状圆圈图标并将新材质从弹出窗口中选择,将“Default-Diffuse”材质更改为新材质。
无论哪种情况,场景视图中的球体现在都应该与材质的检查器视图中的预览具有相同的颜色。更改着色器应(在保存并切换到 Unity 后)更改场景视图中球体的外观。
还有一件事:您应该将您的工作保存在“场景”中(通常对应于游戏关卡)。选择文件 > 保存场景(或文件 > 另存为...)并在项目的“Assets”目录中选择一个文件名。场景文件应然后出现在项目视图中,并在您下次打开项目时可用。
为了避免术语混淆,有必要进行澄清。在 GLSL 中,“着色器”指的是顶点着色器或片段着色器。二者的组合被称为“程序”。
不幸的是,Unity 将这种程序称为“着色器”,而在 Unity 中,顶点着色器被称为“顶点程序”,片段着色器被称为“片段程序”。
为了避免进一步的混乱,我将使用 Unity 的术语“着色器”来指代 GLSL 程序,即顶点着色器和片段着色器的组合。但是,我将使用 GLSL 术语“顶点着色器”和“片段着色器”,而不是“顶点程序”和“片段程序”。
恭喜你已经完成了本教程!你已经了解了以下内容:
- 如何创建一个着色器。
- 如何在 Unity 中定义 GLSL 顶点着色器和片段着色器。
- 如何创建一个材质并将其与着色器绑定。
- 如何在片段着色器中操作输出颜色
gl_FragColor
。 - 如何在顶点着色器中转换输入属性
gl_Vertex
。 - 如何创建一个游戏对象并将材质与它绑定。
实际上,这些内容相当丰富。
如果你还想了解更多关于:
- 顶点着色器和片段着色器的通用知识,请阅读 章节 “OpenGL ES 2.0 Pipeline”。
- 诸如
gl_ModelViewProjectionMatrix
之类的顶点变换,请阅读 章节 “顶点变换”。 - 如何在 GLSL 中处理向量(例如
vec4
类型)和矩阵,请阅读 章节 “向量和矩阵操作”。 - 如何应用诸如
gl_ModelViewProjectionMatrix
之类的顶点变换,请阅读 章节 “应用矩阵变换”。 - 如何使用 Unity 的 ShaderLab 语言来指定着色器,请阅读 Unity 的 ShaderLab 参考。