效果语言
在 C# 中创建着色器
你可以在运行时使用 @'Stride.Shaders.ShaderSource' 对象创建着色器。着色器有三种类型:
- @'Stride.Shaders.ShaderClassSource' 对应一个唯一的着色器类
- @'Stride.Shaders.ShaderMixinSource' 混合多个 @'Stride.Shaders.ShaderSource',设置预处理器值,定义组合
- @'Stride.Shaders.ShaderArraySource' 用于组合的数组
这种方法在运行时生成着色器。然而,许多平台不支持 HLSL,也无法在运行时编译着色器。此外,这种方式无法受益于混入(mixin)的可复用性。
Stride Effects(SDFX)
许多着色器都是已有着色器的变体或组合。例如,有些网格投射阴影,有些接收阴影,还有些需要蒙皮。为了复用代码,通过条件(例如"需要蒙皮")来选择使用哪些部分是个好办法。这通常由"超级着色器(uber shaders)"解决:由一组预处理器参数配置的整体式着色器。
Stride 提供了同样类型的控制方式,同时兼顾可扩展性和可复用性。着色器类定义的简单代码块可以由着色器混合器混合在一起。这个过程可以使用更复杂的逻辑,这些逻辑描述在 Stride Effect(*.sdfx)文件中。
基本语法
.sdfx 文件是一个用于生成着色器变体的小程序。它接收一组参数(集合中的键和值),并产出一个可编译的 ShaderMixinSource。
一个 .sdfx 文件示例:
using Stride.Effects.Data;
namespace StrideEffects
{
params MyParameters
{
bool EnableSpecular = true;
};
effect BasicEffect
{
using params MaterialParameters;
using params MyParameters;
mixin ShaderBase;
mixin TransformationWAndVP;
mixin NormalVSStream;
mixin PositionVSStream;
mixin BRDFDiffuseBase;
mixin BRDFSpecularBase;
mixin LightMultiDirectionalShadingPerPixel<2>;
mixin TransparentShading;
mixin DiscardTransparent;
if (MaterialParameters.AlbedoDiffuse != null)
{
mixin compose DiffuseColor = ComputeBRDFDiffuseLambert;
mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse;
}
if (MaterialParameters.AlbedoSpecular != null)
{
mixin compose SpecularColor = ComputeBRDFColorSpecularBlinnPhong;
mixin compose albedoSpecular = MaterialParameters.AlbedoSpecular;
}
};
}
添加混入
要添加混入(mixin),使用 mixin <mixin_name>。
使用参数
语法与 C# 类似。另加以下规则:
使用参数键时,用
params <shader_name>添加它们。否则,键会被当作变量处理。你无需告诉程序去哪里查找键背后的值,直接使用该键即可。
using params MaterialParameters;
if (MaterialParameters.AlbedoDiffuse != null)
{
mixin MaterialParameters.AlbedoDiffuse;
}
参数的行为与普通变量一样。你可以读写它们的值、比较它们的值,以及设置模板参数。由于某些参数存储的是混入,它们也可以用于组合和继承。
自定义参数
你可以使用结构体定义语法创建自己的参数集。
Note
即使它们定义在 SDFX 文件中,使用时也不要忘记 using 语句。
params MyParameters
{
bool EnableSpecular = true; // true 是默认值
}
组合
要添加组合,请使用以下语法将组合变量赋值给你的混入。
// albedoSpecular 是混入中组合变量的名称
mixin compose albedoSpecular = ComputeColorTexture;
或
mixin compose albedoSpecular = MaterialParameters.AlbedoSpecular;
局部效果
你也可以使用以下语法将代码拆分为子混入,以便在其他地方复用。
partial effect MyPartialEffect
{
mixin ComputeColorMultiply;
mixin compose color1 = ComputeColorStream;
mixin compose color2 = ComputeColorFixed;
}
// 使用它
mixin MyPartialEffect;
mixin compose myComposition = MyPartialEffect;
你可以在代码中像使用任何其他混入一样使用 MyPartialEffect 混入。