Pass 可选配置参数

Pass 中的参数主要分两个部分:

  • 开发者可自定义的 属性检查器 面板参数 properties
  • 引擎提供的用于控制渲染管线状态的 PipelineStates

Properties

properties 用于将 Shader 中定义的 uniform 进行别名映射。这个映射可以是某个 uniform 的完整映射,也可以是具体某个分量的映射(使用 target 参数),代码示例如下:

  1. properties:
  2. albedo: { value: [1, 1, 1, 1] } # uniform vec4 albedo
  3. roughness: { value: 0.8, target: pbrParams.g } # uniform vec4 pbrParams
  4. offset: { value: [0, 0], target: tilingOffset.zw } # uniform vec4 tilingOffset
  5. # say there is another uniform, vec4 emissive, that doesn't appear here
  6. # so it will be assigned a default value of [0, 0, 0, 0] and will not appear in the inspector

默认情况下,properties 中定义的属性参数会暴露并显示在编辑器的 属性检查器 面板中,方便进行可视化控制。

如果不想显示在 属性检查器 面板上,可在定义属性时加上 editor: { visible: false },代码示例如下:

  1. properties:
  2. factor: { value: 1.0, editor: { visible: false } }

在 TypeScript 中可以使用 Material 类的 setProperty 方法以及 PasssetUniform 方法进行设置,代码示例如下:

  1. mat.setProperty('emissive', Color.GREY); // 直接设置对应的 Uniform 变量
  2. mat.setProperty('albedo', Color.RED);
  3. mat.setProperty('roughness', 0.2); // 仅设置对应的分量
  4. const h = mat.passes[0].getHandle('offset'); // 获取对应的 Uniform 的句柄
  5. mat.passes[0].setUniform(h, new Vec2(0.5, 0.5)); // 使用 ‘Pass.setUniform’ 设置 Uniform 属性

注意:在 Shader 中定义的 uniform 也可以使用上述代码进行设置,即使没有在 properties 中定义。

未指定的 uniform,引擎将会在运行时根据自动分析出的数据类型给予默认值。更多关于默认值的内容,请参考下文说明。

为方便声明各 property 子属性,可以直接在 properties 内声明 __metadata__ 项,所有 property 都会继承它声明的内容,如:

  1. properties:
  2. __metadata__: { editor: { visible: false } }
  3. a: { value: [1, 1, 0, 0] }
  4. b: { editor: { type: color } }
  5. c: { editor: { visible: true } }

这样 uniform ab 已声明的各项参数都不会受到影响,但都不会显示在 属性检查器 中(visible 为 false),而 uniform c 仍会正常显示。

Property 参数列表

Property 中可配置的参数如下表所示,任何可配置的字段如果和默认值相同都可以省掉。

参数默认值可选项备注
targetundefinedundefined任意有效的 uniform 通道,可指定连续的单个或多个,但不可随机重排
value详见下文 Default Values 部分的介绍
sampler.
minFilter
linearnone, point, linear, anisotropic
sampler.
magFilter
linearnone, point, linear, anisotropic
sampler.
mipFilter
nonenone, point, linear, anisotropic
sampler.
addressU
wrapwrap, mirror, clamp, border
sampler.
addressV
wrapwrap, mirror, clamp, border
sampler.
addressW
wrapwrap, mirror, clamp, border
sampler.
maxAnisotropy
1616
sampler.
cmpFunc
nevernever, less, equal, less_equal, greater, not_equal, greater_equal, always
sampler.
borderColor
[0, 0, 0, 0][0, 0, 0, 0]
sampler.
minLOD
00
sampler.
maxLOD
00如果允许 mipmap 则要根据贴图修改最大 mip 值
sampler.
mipLODBias
00
editor.
displayName
property nameproperty name任意字符串
editor.
type
vectorvector, color
editor.
visible
truetrue, false
editor.
tooltip
property nameproperty name任意字符串
editor.
range
undefinedundefined, [ min, max, [step] ]
editor.
deprecated
falsetrue, falsedeprecated 标记的数据表示在导入时已更新或在当前版本已废弃,其内容在保存时会被自动删除

Property 默认值

对于 Property 的默认值, Cocos Effect 做出了如下的规定:

类型默认值可选项
int0
ivec2[0, 0]
ivec3[0, 0, 0]
ivec4[0, 0, 0, 0]
float0
vec2[0, 0]
vec3[0, 0, 0]
vec4[0, 0, 0, 0]
sampler2Ddefaultblack, grey, white, normal, default
samplerCubedefault-cubeblack-cube, white-cube, default-cube

对于 defines

  • boolean 类型默认值为 false。
  • number 类型默认值为 0,默认取值范围为 [0, 3]。
  • string 类型默认值为 options 数组第一个元素。

PipelineStates

以下为 PipelineStates 相关参数,所有参数不区分大小写。

参数名说明默认值备注
switch指定这个 pass 的执行依赖于哪个 define。可以是任意有效的宏名称,但不应与使用到的 shader 中定义的任何 define 重名未定义这个字段默认是不存在的,意味着这个 pass 是无条件执行的
priority指定这个 pass 的渲染优先级,数值越小渲染优先级越高,取值范围为 0 ~ 255128可结合四则运算符指定相对值
stage指定这个 pass 归属于管线的哪个 stage。可以是运行时管线中任何注册的 Stage 名称default对于默认的 forward 管线,只有 default 一个 stage
phase指定这个 pass 归属于管线的哪个 phase。可以是运行时管线中任何注册的 Phase 名称default对于默认的 forward 管线,可以是 defaultforward-add 或者 shadow-caster
propertyIndex指定这个 pass 运行时的 uniform 属性数据要和哪个 pass 保持一致,例如 forward add 等 pass 需要和 base pass 一致才能保证正确的渲染效果。可以是任意有效的 pass 索引未定义一旦指定了此参数,材质面板上就不会再显示这个 pass 的任何属性
embeddedMacros指定在这个 pass 的 shader 基础上额外定义的常量宏,可以是一个包含任意宏键值对的对象未定义只有当宏定义不同时才能在多个 pass 中使用此参数来复用 shader 资源
propertiesProperties 存储着这个 pass 中需要显示在 属性检查器 上的可定制的参数详见上文 Properties 部分的内容
migrations迁移旧的材质数据详见下文 Migrations 部分的介绍
primitive创建材质顶点数据triangle_list可选项包括:point_list、line_list、line_strip、line_loop
triangle_list、triangle_strip、triangle_fan
line_list_adjacency、line_strip_adjacency
triangle_list_adjacency、triangle_strip_adjacency
triangle_patch_adjacency、quad_patch_list、iso_line_list
RasterizerState光栅化时的可选渲染状态详见下文 RasterizerState 部分的介绍
DepthStencilState深度和模板缓存的测试与状态详见下文 DepthStencilState 部分的介绍
BlendState材质混合状态false详见下文 BlendState 部分的介绍

Migrations

一般情况下,在使用材质资源时都希望底层的 effect 接口能始终向前兼容,但有时面对新的需求最好的解决方案依然是含有一定 breaking change 的,这时为了保持项目中已有的材质资源数据不受影响,或者至少能够更平滑地升级,就可以使用 effect 的迁移系统。

在 effect 导入成功后会 立即更新工程内所有 依赖于此 effect 的材质资源,对每个材质资源,会尝试寻找所有指定的旧参数数据(包括 property宏定义 两类),然后将其复制或迁移到新属性中。

注意:使用迁移功能前请一定先备份好项目工程,以免丢失数据!

对于一个现有的 effect,迁移字段声明如下:

  1. migrations:
  2. # macros: # macros follows the same rule as properties, without the component-wise features
  3. # USE_MIAN_TEXTURE: { formerlySerializedAs: USE_MAIN_TEXTURE }
  4. properties:
  5. newFloat: { formerlySerializedAs: oldVec4.w }

对于一个依赖于这个 effect,并在对应 pass 中持有属性的材质:

  1. {
  2. "oldVec4": {
  3. "__type__": "cc.Vec4",
  4. "x": 1,
  5. "y": 1,
  6. "z": 1,
  7. "w": 0.5
  8. }
  9. }

在 effect 导入成功后,这些数据会被立即转换成:

  1. {
  2. "oldVec4": {
  3. "__type__": "cc.Vec4",
  4. "x": 1,
  5. "y": 1,
  6. "z": 1,
  7. "w": 0.5
  8. },
  9. "newFloat": 0.5
  10. }

编辑器 内重新编辑并保存这个材质资源后会变成(假设 effect 和 property 数据本身并没有改变):

  1. {
  2. "newFloat": 0.5
  3. }

当然如果希望在导入时就直接删除旧数据,可以再加一条迁移信息来专门指定这点:

  1. oldVec4: { removeImmediately: true }

这对于在项目有大量旧材质,又能够确定这个属性的数据已经完全冗余时会比较有用。

更多地,注意这里的通道指令只是简单的取 w 分量,事实上还可以做任意的 shuffle:

  1. newColor: { formerlySerializedAs: someOldColor.yxx }

甚至基于某个宏定义:

  1. occlusion: { formerlySerializedAs: pbrParams.<OCCLUSION_CHANNEL|z> }

这里声明了新的 occlusion 属性会从旧的 pbrParams 中获取,而具体的分量取决于 OCCLUSION_CHANNEL 宏定义。并且如果材质资源中未定义这个宏,则默认取 z 通道。
但如果某个材质在迁移升级前就已经存着 newFloat 字段的数据,则不会对其做任何修改,除非指定为强制更新模式:

  1. newFloat: { formerlySerializedAs: oldVec4.w! }

强制更新模式会强制更新所有材质的属性,无论这个操作是否会覆盖数据。

注意:强制更新操作会在编辑器的每次资源事件中都执行(几乎对应每一次鼠标点击,相对高频),因此只是一个快速测试和调试的手段,一定不要将处于强制更新模式的 effect 提交到版本控制。

再次总结一下为防止数据丢失所设置的相关规则:

  • 为避免有效旧数据丢失,只要没有显式指定 removeImmediately 规则,就不会在导入时自动删除旧数据;
  • 为避免有效的新数据被覆盖,如果没有指定为强制更新模式,对于那些既有旧数据,又有对应的新数据的材质,不会做任何迁移操作。

RasterizerState

参数名说明默认值可选项
isDiscard引擎预留falsetrue, false
polygonMode多边形绘制模式fillpoint,line,fill
shadeModel着色模型flatflat, gourand
cullMode光栅化时剔除模式backfront, back, none
isFrontFaceCCW是否逆时针(CCW)前向truetrue,false
depthBias深度偏移0
depthBiasSlop深度偏差斜率0
depthBiasClamp深度截断0
isDepthClip允许深度剪裁操作
Vulkan 专用
truetrue, false
isMultisample是否开启多重采样falsetrue, false
lineWidth线宽1

DepthStencilState

参数名说明默认值可选项
depthTest是否开启深度测试truetrue,false
depthWrite是否开启深度缓存写入truetrue, false
depthFunc深度缓存比较方法lessnever, less, equal, less_equal, greater, not_equal, greater_equal, always
stencilTestFront是否开启正面模板缓存测试falsetrue, false
stencilFuncFront正面模板缓存比较方法alwaysnever, less, equal, less_equal, greater, not_equal, greater_equal, always
stencilReadMaskFront正面模板缓存读取掩码0xffffffff0xffffffff, [1, 1, 1, 1]
stencilWriteMaskFront正面模板缓存写入掩码0xffffffff0xffffffff, [1, 1, 1, 1]
stencilFailOpFront正面模板缓存测试失败时,如何处理缓冲区的值keepkeep, zero, replace, incr, incr_wrap, decr, decr_wrap, invert
stencilZFailOpFront正面模板缓存深度测试失败时,如何处理缓冲区的值keepkeep, zero, replace, incr, incr_wrap, decr, decr_wrap, invert
stencilPassOpFront正面模板缓存测试通过时,如何处理缓冲区的值keepkeep, zero, replace, incr, incr_wrap, decr, decr_wrap, invert
stencilRefFront正面模板缓存中的比较函数用于比较的值11, [0, 0, 0, 1]
stencilTestBack是否开启背面模板缓存测试falsetrue, false
stencilFuncBack背面模板缓存比较方法alwaysnever, less, equal, less_equal, greater, not_equal, greater_equal, always
stencilReadMaskBack背面模板缓存读取掩码0xffffffff0xffffffff, [1, 1, 1, 1]
stencilWriteMaskBack背面模板缓存写入掩码0xffffffff0xffffffff, [1, 1, 1, 1]
stencilFailOpBack背面模板缓存测试失败时,如何处理缓冲区的值keepkeep, zero, replace, incr, incr_wrap, decr, decr_wrap, invert
stencilZFailOpBack背面模板缓存深度测试失败时,如何处理缓冲区的值keepkeep, zero, replace, incr, incr_wrap, decr, decr_wrap, invert
stencilRefBack背面模板缓存中的比较函数用于比较的值11, [0, 0, 0, 1]

BlendState

参数名说明默认值可选项
isA2C是否开启半透明反锯齿(Alpha To Coverage)falsetrue,false
isIndependRGB 和 Alpha 是否分开混合falsetrue,false
blendColor指定混合颜色00, [0, 0, 0, 0]
targets混合配置,请参考下方的 targets[]

Targets

参数名说明默认值可选项
Targets[i].
blend
是否开启 混合falsetrue, false
Targets[i].
blendEq
指定 混合源混合目标 的 RGB 的混合方程addadd, sub, rev_sub
Targets[i].
blendSrc
指定 混合源 的 RGB 混合因子oneone, zero, src_alpha_saturate,
src_alpha, one_minus_src_alpha,
dst_alpha, one_minus_dst_alpha,
src_color, one_minus_src_color,
dst_color, one_minus_dst_color,
constant_color, one_minus_constant_color,
constant_alpha, one_minus_constant_alpha
Targets[i].
blendDst
指定 混合目标 的 RGB 混合因子zeroone, zero, src_alpha_saturate,
src_alpha, one_minus_src_alpha,
dst_alpha, one_minus_dst_alpha,
src_color, one_minus_src_color,
dst_color, one_minus_dst_color,
constant_color, one_minus_constant_color,
constant_alpha, one_minus_constant_alpha
Targets[i].
blendSrcAlpha
指定 混合源 的 Alpha 混合因子oneone, zero, src_alpha_saturate,
src_alpha, one_minus_src_alpha,
dst_alpha, one_minus_dst_alpha,
src_color, one_minus_src_color,
dst_color, one_minus_dst_color,
constant_color, one_minus_constant_color,
constant_alpha, one_minus_constant_alpha
Targets[i].
blendDstAlpha
指定 混合目标 的 Alpha 混合因子zeroone, zero, src_alpha_saturate,
src_alpha, one_minus_src_alpha,
dst_alpha, one_minus_dst_alpha,
src_color, one_minus_src_color,
dst_color, one_minus_dst_color,
constant_color, one_minus_constant_color,
constant_alpha, one_minus_constant_alpha
Targets[i].
blendAlphaEq
指定 混合源混合目标 的 Alpha 混合方法addadd, sub, rev_sub
Targets[i].
blendColorMask
指定是否可将 RGB,Alpha 分量写入帧缓存allall, none, r, g, b, a, rg, rb, ra, gb, ga, ba, rgb, rga, rba, gba
dynamics可动态更新的管线状态[]LINE_WIDTH, DEPTH_BIAS, BLEND_CONSTANTS, DEPTH_BOUNDS, STENCIL_WRITE_MASK, STENCIL_COMPARE_MASK