# 材质
材质 Material 基于 效果 Effect,提供了修改渲染状态、Uniforms的接口,真正决定了物体最后的渲染方式,体现为物体表面的外观。
# 创建一个材质
创建材质有两种方式,一般我们会优先在wxml中进行创建。
# 在wxml中创建
在xml中创建需要用到xr-asset-material标签:
<xr-asset-material asset-id="mat" effect="standard" uniforms:"u_baseColorMap: waifu" states="alphaMode:BLEND" renderQueue="2500" />
其中asset-id是会添加到资源系统中的id,effect是已经注册过的效果,这两个参数是必填的。uniforms类型是dict,用于覆盖效果中定义的那些属性,会根据那些属性的type来进行解析,比如Vector2对应1 1这样的数组;states类型也是dict,用于覆盖效果中定义的那些渲染状态(需要效果中开启useMaterialStates);最后的renderQueue用于覆盖效果中的默认渲染顺序,大于等于2500为透明物体。
# 用代码创建
有时候我们需要用代码创建材质,也很简单:
// 第一个参数是效果实例的引用,第二个参数是默认`uniforms`
const mat = scene.createMaterial(
// 使用内置的 Standard 效果
scene.assets.getAsset('effect', 'standard'),
{u_baseColorMap: scene.assets.getAsset('texture', 'waifu')}
);
// 可以将其添加到资源系统中备用
scene.assets.addAsset('material', 'test-mat', mat);
创建完,接下来就是使用了。
# 使用材质
材质和其他资源一样,可以通过在组件schema中设定数据类型为material,然后在xml中通过资源id索引,或者用setData直接使用。目前使用了材质的组件只有网格,详见对应章节。
除了被引用外,材质也提供了一些方法来对其进行修改:
// 一系列修改Uniforms的接口
material.setFloat(key, value);
material.setVector(key, vec);
material.setMaterial(key, mat);
material.setTexture(key, texture);
// 修改渲染状态
material.setRenderState(key, value);
// 修改宏
material.setMacros({key: value});
// 重置图片,同时关闭对应的宏
material.resetTexture(key);
// 重置状态
materia.clearRenderState(key);
# 材质支持渲染状态列表
| 状态名称 | 说明 | 类型 |
|---|---|---|
| renderQueue | 渲染顺序 | number |
| cullOn | 是否开启剔除 | bool |
| depthTestOn | 是否开启深度测试 | bool |
| depthTestWrite | 是否开启深度写入 | bool |
| alphaMode | 透明模式 | 'OPAQUE' 'BLEND' 'MASK' |
| alphaCutOff | 是否开启透明剔除 | bool |
| depthTestComp | 深度测试方法 | number, ECompareFunc对应的值 |
| stencilTestOn | 是否开启模板测试 | boolean |
| stencilComp | 模板测试相关 | number, ECompareFunc对应的值 |
| stencilRef | 模板测试相关 | number |
| stencilReadMask | 模板测试相关 | number |
| stencilWriteMask | 模板测试相关 | number |
| stencilPass | 模板测试相关 | number, EStencilOp对应的值 |
| stencilFail | 模板测试相关 | number, EStencilOp对应的值 |
| stencilZFail | 模板测试相关 | number, EStencilOp对应的值 |
| colorWrite | 颜色通道写入掩码,基础库v2.31.1开始支持 | number, 一个4bits的mask,由高到低为ABGR四个通道,比如0b1001表示只开启R和A通道写入 |