跳转到内容

Cg 编程/Unity/最小着色器

来自维基教科书,开放的书籍,开放的世界

本教程涵盖了在 Unity 中创建最小 Cg 着色器的基本步骤。

启动 Unity 并创建一个新项目

[编辑 | 编辑源代码]

下载并启动 Unity 后,您应该创建一个新项目。选择“3D”选项,即“使用 Unity 的内置渲染器的空 3D 项目”。对于本教程,您无需导入任何包。

如果您不熟悉 Unity 的场景视图、层次结构窗口、项目窗口和检查器窗口,现在是阅读 Unity 手册 前三个部分的最佳时机 (Unity 基础资产工作流程主窗口)。

创建着色器

[编辑 | 编辑源代码]

创建 Cg 着色器并不复杂:在 **项目窗口** 中,单击“+”按钮(或在右键菜单中选择 **创建**)并选择 **着色器 > 标准表面着色器**。一个名为“NewSurfaceShader”的新文件应该出现在项目窗口中。双击它打开它(或右键单击并选择 **打开**)。一个包含默认着色器(用 Cg 语言编写)的文本编辑器应该出现。(要更改 Unity 使用的文本编辑器,从主菜单中选择 **编辑 > 首选项 ... > 外部工具**,并更改 **外部脚本编辑器** 的设置。)

现在,删除所有文本并将以下着色器复制并粘贴到此文件中

Shader "Cg basic shader" { // defines the name of the shader 
   SubShader { // Unity chooses the subshader that fits the GPU best
      Pass { // some shaders require multiple passes
         CGPROGRAM // here begins the part in Unity's Cg

         #pragma vertex vert 
            // this specifies the vert function as the vertex shader 
         #pragma fragment frag
            // this specifies the frag function as the fragment shader

         float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
            // vertex shader 
         {
            return UnityObjectToClipPos(vertexPos);
              // this line transforms the vertex input parameter 
              // and returns it as a nameless vertex output parameter 
              // (with semantic SV_POSITION)
         }

         float4 frag(void) : COLOR // fragment shader
         {
            return float4(1.0, 0.0, 0.0, 1.0); 
               // this fragment shader returns a nameless fragment
               // output parameter (with semantic COLOR) that is set to
               // opaque red (red = 1, green = 0, blue = 0, alpha = 1)
         }

         ENDCG // here ends the part in Cg 
      }
   }
}

保存着色器(通过单击保存图标或从编辑器的菜单中选择 **文件 > 保存**)。

恭喜,您刚刚在 Unity 中创建了一个着色器。如果您愿意,您可以通过单击名称、键入新名称并按回车键来重命名项目窗口中的着色器文件。(重命名后,重新打开编辑器中的着色器,以确保您正在编辑正确文件。)

不幸的是,在将着色器附加到材质之前,您什么也看不到。

创建材质并附加着色器

[编辑 | 编辑源代码]

要创建材质,请返回 Unity 并通过单击 **项目窗口** 中的“+”按钮(或在右键菜单中选择 **创建**)并选择 **材质**(不是 (!)“物理材质”)来创建一个新材质。一个新材质(默认情况下称为“New Material”)应该出现在项目窗口中。(您可以像着色器一样重命名它。)如果它没有被选中,请通过单击选择它。有关材质的详细信息现在出现在检查器窗口中。为了将着色器设置为此材质,您可以

  • 将 **项目窗口** 中的着色器拖放到材质上,或者
  • 在 **项目窗口** 中选择材质,然后在 **检查器窗口** 中从标记为 **着色器** 的下拉列表中选择着色器(在本例中为着色器代码中指定的“Cg basic shader”。

无论哪种情况,材质的检查器窗口中的预览现在都应该显示一个红色球体;如果没有,您可能需要单击检查器窗口底部的灰色条才能显示它。如果没有预览或球体为亮洋红色,则应该在 Unity 窗口底部显示错误消息。在这种情况下,您应该重新打开着色器并在编辑器中检查文本是否与上面给出的相同。

交互式编辑着色器

[编辑 | 编辑源代码]

现在是玩弄着色器的最佳时机;特别是,您可以轻松地更改计算的片段颜色。尝试使用霓虹绿,方法是打开着色器并将 frag 函数中的片段着色器替换为以下代码

         float4 frag(void) : COLOR // fragment shader
         {
            return float4(0.6, 1.0, 0.0, 1.0); 
               // (red = 0.6, green = 1.0, blue = 0.0, alpha = 1.0)
         }

您必须在编辑器中保存代码并重新激活 Unity 窗口以应用新的着色器。如果您在项目窗口中选择材质,检查器窗口中的球体现在应该是绿色的。您还可以尝试修改红色、绿色和蓝色组件以找到最温暖的橙色或最深的蓝色。(实际上,有一部关于寻找最温暖的橙色的电影,还有一部关于几乎为黑色的深蓝色的电影。)

您还可以玩弄 vert 函数中的顶点着色器,例如尝试以下顶点着色器

         float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
            // vertex shader 
         {
            return UnityObjectToClipPos(float4(1.0, 0.1, 1.0, 1.0) * vertexPos);
         }

这通过将 坐标乘以 来使任何输入几何体变平。(这是一个分量级的向量积;有关 Cg 中向量和矩阵的更多信息,请参见 “向量和矩阵运算”部分 的讨论。)

如果着色器无法编译,Unity 将在 Unity 窗口底部显示一条错误消息,并将材质显示为亮洋红色。为了查看所有错误消息和警告,您应该在 **项目窗口** 中选择着色器,并在 **检查器窗口** 中阅读消息,其中还包括行号。您还可以通过从菜单中选择 **窗口 > 常规 > 控制台** 来打开控制台窗口,但这有时不会显示所有错误消息,因此有时不会报告关键错误。

将材质附加到游戏对象

[编辑 | 编辑源代码]

我们还有一个重要的步骤要完成:将新材质附加到三角形网格。为此,请通过从菜单中选择 **游戏对象 > 3D 对象 > 球体** 来创建一个球体(它是 Unity 的预定义游戏对象之一)。一个球体应该出现在场景视图中,标签“Sphere”应该出现在层次结构窗口中。(如果它没有出现在场景视图中,请在层次结构窗口中单击它,将鼠标悬停在场景视图上并按“f”。球体现在应该以居中的方式出现在场景视图中。)

要将材质附加到新球体,您可以

  • 将 **项目窗口** 中的材质拖放到 **层次结构窗口** 中的球体上,或者
  • 将 **项目窗口** 中的材质拖放到 **场景视图** 中的球体上,或者
  • 在 **层次结构窗口** 中选择球体,在 **检查器窗口** 中找到 **网格渲染器** 组件(如果它没有打开,请单击标题打开它),通过单击打开网格渲染器的 **材质** 设置。通过单击“元素 0”插槽右侧的点状圆圈图标并将弹出窗口中选择新的材质来将“Default-Material”材质更改为新的材质。(或者将新的材质拖放到“元素 0”插槽中。)

无论哪种情况,场景视图中的球体现在应该与材质的检查器窗口中的预览具有相同的颜色。更改着色器应该(在保存并切换到 Unity 后)更改场景视图中球体的外观。

在场景中保存您的工作

[编辑 | 编辑源代码]

还有一件事:您应该将您的工作保存在“场景”中(通常对应于游戏关卡)。选择文件>保存(或文件>另存为...)并在项目“资源”目录中选择一个文件名。场景文件应该出现在“项目窗口”中,并在您下次打开项目时可用。

关于术语的另外说明

[编辑 | 编辑源代码]

澄清一下术语可能会有所帮助。在一些 API 中,“着色器”要么是顶点着色器,要么是片段着色器。两者的组合被称为“程序”。在其他 API 中,则刚好相反:“程序”要么是顶点程序,要么是片段程序,两者的组合被称为“着色器”。不幸的是,Unity 的文档将这两种约定混合使用。为了简单起见,我们在这里尽量避免使用术语“程序”,而是使用术语“着色器”来表示顶点着色器和片段着色器的组合。

恭喜您,您已经完成了本教程。您已经了解了一些内容,包括:

  • 如何创建着色器。
  • 如何在 Unity 中定义 Cg 顶点和片段着色器。
  • 如何创建材质并将着色器附加到材质。
  • 如何使用片段着色器中的语义 COLOR 操作片段输出参数。
  • 如何使用顶点着色器中的语义 POSITION 变换顶点输入参数。
  • 如何创建游戏对象并将材质附加到它。

事实上,这已经涵盖了很多内容。

进一步阅读

[编辑 | 编辑源代码]

如果您想了解更多信息,

< Cg 编程/Unity

除非另有说明,否则本页面上的所有示例源代码均授予公有领域。
华夏公益教科书