# 材质

材质 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是会添加到资源系统中的ideffect是已经注册过的效果,这两个参数是必填的。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表示只开启RA通道写入