-
effectAsset 或 effectName:effect 资源引用,指定使用哪个 EffectAsset 所描述的流程进行渲染。(必备)
-
technique:指定使用 EffectAsset 中的第几个 technique,默认为第 0 个。
-
defines:宏定义列表,指定开启哪些宏定义,默认全部关闭。
-
states:管线状态重载列表,指定对渲染管线状态(深度模板透明混合等)有哪些重载,默认与 effect 声明一致。
import { _decorator, Component, Node, Sprite, Material, SpriteFrame, gfx, Texture2D, EffectAsset } from 'cc';
const { ccclass, property } = _decorator;
const { BlendFactor, CullMode } = gfx;
@ccclass('Example')
export class Example extends Component {
@property(EffectAsset)
foo: EffectAsset = null!;
@property(Texture2D)
dissolveMap: Texture2D = null!;
start () {
const sprite = this.getComponent(Sprite);
const mat = new Material();
// effect name 适用于内置 shader,可以通过 EffectAsset.get('effect name') 方式获取,判断
mat.initialize({
effectAsset: this.foo,
defines: {
USE_TEXTURE: true,
},
states: {
blendState:{
targets: [
{
blend: true,
blendSrc: BlendFactor.SRC_ALPHA,
blendDst: BlendFactor.ONE_MINUS_SRC_ALPHA,
blendDstAlpha: BlendFactor.ONE_MINUS_SRC_ALPHA
}
]
},
rasterizerState: {
cullMode: CullMode.NONE,
}
}
});
sprite.customMaterial = mat;
mat.setProperty('u_dissolveMap', this.dissolveMap!);
mat.setProperty('dissolveThreshold', 0.3);
}
}
// 所有带有材质的组件上都可以获取材质,通过 comp.material 获取出来的材质通常都是材质实例 MaterialInstance
// 材质 Material 和材质实例 MaterialInstance 的区别在于,MaterialInstance 从挂载的那一刻就一直属于唯一的组件,且只对该组件模型生效,而 Material 则无此限制,可以属于多个同类型组件或者不同类型组件
// 只有 MaterialInstance 可以运行时动态修改 defines 和 states
const sprite = this.getComponent(Sprite);
const mat = new Material();
mat.initialize({
effectAsset: this.foo,
});
const matInst = sprite.material;
matInst.recompileShaders({ USE_TEXTURE: true });
matInst.overridePipelineStates({
blendState:{
targets: [
{
blend: true,
blendSrc: BlendFactor.SRC_ALPHA,
blendDst: BlendFactor.ONE_MINUS_SRC_ALPHA,
blendDstAlpha: BlendFactor.ONE_MINUS_SRC_ALPHA
}
]
},
rasterizerState: {
cullMode: CullMode.NONE,
}
});
matInst.setProperty('u_dissolveMap', this.dissolveMap!);
matInst.setProperty('dissolveThreshold', 0.3);
-
可以存储更多的 uniform 类型变量
-
可以简化大量 uniform 变量设置的流程
-
可以通过切换不同的 UBO 绑定,在单一着色语言程序中迅速更新程序中的 uniform 类型变量的值
-
可以在不同的着色语言程序中通过更新 UBO 中的数据实现所有 uniform 类型变量的更新
// 普通 uniform 声明
uniform float dissolveThreshold;
// UBO 形式声明
uniform Dissolve{
float dissolveThreshold;
};
-
不应该出现 vec3 成员。
-
对于数组类型的成员,每个元素的 size 不能小于 vec4
-
不允许任何会引入 padding 的成员声明顺序
-
所有 vec3 成员都会补齐至 vec4
uniform ControversialType {
vec3 v3_1; // offset 0, length 16 [IMPLICIT PADDING!]
}; // total of 16 bytes
-
任意长度小于 vec4 类型的数组和结构体,都会将元素补齐至 vec4
uniform ProblematicArrays {
float f4_1[4]; // offset 0, stride 16, length 64 [IMPLICIT PADDING!]
}; // total of 64 bytes
-
所有成员在 UBO 内的实际偏移都会按自身所占字节数对齐
uniform IncorrectUBOOrder {
float f1_1; // offset 0, length 4 (aligned to 4 bytes)
vec2 v2; // offset 8, length 8 (aligned to 8 bytes) [IMPLICIT PADDING!]
float f1_2; // offset 16, length 4 (aligned to 4 bytes)
}; // total of 32 bytes
// 可以看到,上面这种声明方式, v2 由于对齐的是 vec2,也就是起始计算偏移了两个 float,也就是是 8 字节。所以浪费了 4-7 之间的 4 个字节
// 又由于 f1_1 和 v2 已经占用了一个 vec4 的存储空间,因此,f1_2 需要开启一个新的 vec4 内存空间
//因此,正确的方式如下
uniform CorrectUBOOrder {
float f1_1; // offset 0, length 4 (aligned to 4 bytes)
float f1_2; // offset 4, length 4 (aligned to 4 bytes)
vec2 v2; // offset 8, length 8 (aligned to 8 bytes)
}; // total of 16 bytes
-
DONT_CLEAR:不执行任何绘制清除
-
DEPTH_ONLY:只执行深度清除
-
SOLID_COLOR:清空颜色、深度和模版缓冲
-
SKYBOX:启用天空盒,只清空深度