Table of Contents

自定义着色器

中级 程序员

你可以在 Visual Studio 中编写自己的着色器,并在材质属性中使用它们。例如,你可以编写一个着色器,根据物体的世界位置为材质添加纹理,或者生成噪声并用它来随机化材质属性。

由于着色器是文本文件,你可以添加注释、启用和禁用代码行,并像编辑其他任何代码文件一样编辑它们。这使得它们易于维护和迭代。

你还可以使用自定义着色器创建自定义后处理效果。更多信息请参阅自定义颜色变换。

创建着色器

选项 1:使用 Visual Studio(推荐用于 Game Studio 工作流)

  1. 确保你已安装 Stride Visual Studio 扩展。这是将着色器文件从 SDSL(Stride 着色语言)转换为 .cs 文件所必需的。

  2. 在 Game Studio 的工具栏中,点击 Open in IDE(Open in IDE)在 Visual Studio 中打开你的项目。

  3. 在 Visual Studio 的 Solution Explorer 中,右键单击项目(例如 MyGame.Game)并选择 Add > New item。

    新建项

  4. 选择 Class。

    选择类

  5. 在 Name 字段中,指定一个带 .sdsl 扩展名的名称(例如 MyShader.sdsl),然后点击 Add。

    选择类

    Stride Visual Studio 扩展会自动从 .sdsl 文件生成一个 .cs 文件。Solution Explorer 会将其列为 .sdsl 文件的子项。

    我的着色器

  6. 打开 .sdsl 文件,删除现有内容,编写你的着色器。

    着色器使用基于 HLSL 的 Stride Shading Language(SDSL)编写。更多信息请参阅着色语言。

    例如,下面的着色器创建绿色(RGBA 0;1;0;1):

    namespace MyGame
    {
        shader MyShader : ComputeColor
        {
            override float4 Compute()
            {
                return float4(0, 1, 0, 1);
            }
        };
    }
    
    Note

    确保文件中的着色器名称(例如上面的 MyShader)与文件名一致。

    Note

    要能从 Game Studio 的 Property Grid 访问,着色器必须继承自 ComputeColor。 由于 ComputeColor 总是返回 float4 值,接受 float 值的属性(例如金属度和光泽度贴图)会使用 ComputeColor 返回值的第一个分量(红色分量)。

  7. 保存解决方案中的所有文件(File > Save All)。

  8. 在 Game Studio 中,重新加载程序集。

    重新加载程序集

选项 2:使用 Visual Studio Code(高级着色器开发)

要进行以着色器为中心的开发,获得增强的 IntelliSense 和继承可视化:

  1. 安装 Visual Studio Code 或 VSCodium

  2. 安装 Stride Shader Tools 扩展:

  3. 在项目的 Assets 文件夹(或 Assets 的子文件夹)中创建 .sdsl 文件

    Note

    着色器必须位于包的 Assets 文件夹中(即包含 .sdpkg 文件的文件夹)。这是 Stride 项目结构的一部分。

  4. VS Code 提供:

    • 针对继承成员、streams 和语义的上下文感知补全
    • 实时继承树可视化
    • 贯穿着色器层次结构的转到定义
    • 实时错误报告

有关使用 VS Code 开发着色器的详细信息,请参阅使用 Visual Studio Code 开发着色器。

Note

使用 VS Code 编写着色器时,你仍然需要安装带 Stride 扩展的 Visual Studio 来生成 Game Studio 所需的 .cs 文件。典型工作流是:在 VS Code 中开发和编辑着色器,然后在 Visual Studio 中打开解决方案以触发代码生成,最后在 Game Studio 中重新加载程序集。

**Asset View** 会将着色器列在与脚本相同的目录下(例如 **MyGame.Game**)。

![Asset View 中的着色器](media/shader-in-asset-view.png)

>[!Note]
>在某些情况下,Game Studio 会错误地将着色器识别为脚本,如下图所示:

>![着色器被当作脚本](media/shader-as-script-in-asset-view.png) 

>如果出现这种情况,请重启 Game Studio(**File > Reload project**)。

使用自定义着色器

你可以在任何材质属性中使用自定义着色器。

  1. 在 Asset View 中,选择你想使用该着色器的材质。

  2. 在 Property Grid 中,于你想用着色器控制的属性旁边,点击 蓝色箭头按钮(Change)并选择 Shader。

    选择 Shader

  3. 在字段中输入你的着色器名称(例如 MyShader)。

    输入着色器

    该属性将使用你指定的着色器。

Tip

当你在 Visual Studio 中修改 .sdsl 文件并保存时,Game Studio 会自动将你的更改更新到项目中。如果没有发生这种情况,请重启 Game Studio(File > Reload project)。

Note

如果你从项目资产中删除了着色器,为防止出错,请确保同时从使用它的材质属性中移除它。

参数与实参

模板实参

模板实参(泛型)在运行时不会改变。不过,不同的材质可以使用该着色器的不同实例,并带有不同的值。

编译着色器时,Stride 会用你在 Property Grid 中设置的值替换模板实参。

例如,下面的代码定义并使用了模板实参 Frequency:

shader ComputeColorWave<float Frequency> : ComputeColor, Texturing
{
    override float4 Compute()
   {           
        return sin((Global.Time) * 2 * 3.14 * Frequency);
    }
};

模板实参

参数

参数可以在运行时更改。

例如,下面的代码定义并使用了动态参数 Frequency:

shader ComputeColorWave: ComputeColor, Texturing
{
    cbuffer PerMaterial
    {
        stage float Frequency = 1.0f;
    }

    override float4 Compute()
    {
        return sin(( Global.Time ) * 2 * 3.14 * Frequency);
    }
};

要在运行时修改该值,请在材质参数集合中访问并设置它。例如,要更改 Frequency,请使用:

myMaterial.Passes[myPassIndex].Parameters.Set(ComputeColorWaveKeys.Frequency, MyFrequency);
Note

ComputeColorWaveKeys.Frequency 由 Stride Visual Studio 扩展从着色器文件生成。

组合

这个组合让你可以在 Game Studio 的 Property Grid 中设置 Frequency:

shader ComputeColorWave : ComputeColor, Texturing
{
    compose ComputeColor Frequency;

    override float4 Compute()
    {
        return sin(( Global.Time ) * 2 * 3.14 * Frequency.Compute().r);
    }
};

然后你就可以在材质属性中设置该值了:

选择着色器

故障排查

你可以通过 Game Studio 调试窗口的 EffectCompilerCache 标签页(Ctrl+Shift+D 或 Help>Show debug window)查看着色器的编译日志。

启动器内置了一个专门用于语法高亮和错误提示的 Visual Studio 扩展,你可能希望使用它。有关带有增强 IntelliSense 的高级着色器开发,请参阅使用 Visual Studio Code 开发着色器。

引擎源码也是学习如何编写着色器的良师益友。Stride.ShaderExplorer 是一个出色的独立工具,可用于浏览和探索完整的着色器库及其继承关系。

你可能会遇到的一个常见问题是:

E1202: The mixin X in Y dependency is not in the module

该错误通常是由于缺失或格式错误的 Generics 和 Composition 节点导致的。 出现这种情况时,你有两个选择:

  • 要么通过材质的 Yaml 文件手动填写这些节点。
  • 要么将着色器移除后再重新添加。

在这两种情况下,你都需要先关闭 Game Studio 再执行这些操作:前者是为了确保资产从磁盘重新加载;后者是因为 Property Grid 使用的缓存需要重建。

我们目前正在重建着色器系统的后端,希望能消除这些不便。

自定义着色器示例

有关自定义着色器的示例,请参阅 Stride 自带的 custom material shader 示例项目。

示例项目

在该项目中,ComputeColorWaveNormal 着色器被用于 displacement map 和 surface 材质属性。

另请参阅