创建材质一般有以下 3 种方式:

参考模型的导入和使用教程,我们可以先将模型导入到编辑器,一般情况下,模型已经自动绑定好材质,用户可以不用做任何操作;
如果想要修改模型材质,我们可以点击 duplicate and remap 按钮来生成一份该材质的副本,注意 Remap 会修改模型预设,如下图所有模型实例都会受到影响:

如果只想修改某个模型的材质,可以使用增量修改的功能:

我们直接将材质拖到场景中即可进行绑定。

我们还可以通过脚本来创建/修改材质,我们将脚本挂载到立方体实体上,实现替换材质的一个 Demo:
export default class extends Script {
onStart() {
// 获取所有 renderer
const renderers = [];
this.entity.getComponentsIncludeChildren(MeshRenderer, renderers);
const renderer = renderers[0];
// 直接修改材质
const material = renderer.getMaterial();
material.baseColor.set(1, 0, 0, 1);
// 或者替换材质
const pbrMaterial = new PBRMaterial(engine);
const material = renderer.setMaterial(material);
}
}可以在编辑器中选中材质,切换 shader 观察实时渲染效果变化。

每个 Shader 有不同的渲染效果和应用场景,更多详情参考 内置着色器教程 和 自定义 Shader 实战教程 。
如果内置 Shader 不能满足需求,我们可以自定义一个Shader,在编辑器资产面板中,新建 Shader,选择 PBR 模板或者 Unlit 模板:
编辑器会自动帮我们创建好 Shader 文件和 UIScript 文件。
具体 shader 内容编写可以从 自定义 Shader 实战教程 快速上手。
跟别的编程语言一样,我们在写 Shader 过程中也会用到很多变量,首先引擎有很多 内置变量,这部分的变量我们是不需要手动设置的,可以直接在 shader 中使用。接下来我们看看如何设置和使用自定义数据。
...
Pass "Forward" {
// 声明自定义变量
vec4 u_color;
// 声明引擎内置变量
mat4 renderer_MVPMat;
// 通过引入代码片段
#include "Transform.glsl"
}
...Shader 支持通过 UIScript 帮我们自动生成可以交互的面板:


参考 Shader Editor 模块 使用更多类型的数据和宏。
当然,我们也可以通过代码设置着色器数据:
// shaderData 可以分别保存在 scene 、camera 、renderer、 material 中。
const shaderData = material.shaderData;
// 上传不同类型的着色器数据
shaderData.setFloat("u_float", 1.5);
shaderData.setInt("u_int", 1);
shaderData.setInt("u_bool", 1);
shaderData.setVector2("u_vec2", new Vector2(1, 1));
shaderData.setVector3("u_vec3", new Vector3(1, 1, 1));
shaderData.setVector4("u_vec4", new Vector4(1, 1, 1, 1));
shaderData.setMatrix("u_matrix", new Matrix());
shaderData.setIntArray("u_intArray", new Int32Array(10));
shaderData.setFloatArray("u_floatArray", new Float32Array(10));
shaderData.setTexture("u_sampler2D", texture2D);
shaderData.setTexture("u_samplerCube", textureCube);
shaderData.setTextureArray("u_samplerArray", [texture2D, textureCube]);
// 开启宏开关
shaderData.enableMacro("DISCARD");
// 关闭宏开关
shaderData.disableMacro("DISCARD");
// 开启变量宏
shaderData.enableMacro("LIGHT_COUNT", "3");
// 切换变量宏。这里底层会自动 disable 上一个宏,即 “LIGHT_COUNT 3”
shaderData.enableMacro("LIGHT_COUNT", "2");
// 关闭变量宏
shaderData.disableMacro("LIGHT_COUNT");当你设置完数据后,你已经可以在 Shader 中直接使用,如下:
float test = u_float;
int test = u_int;
bool test = u_bool;
vec2 test = u_vec2;
mat4 test = u_matrix;
sampler2D test = u_sampler2D;
...你也可以通过代码获取这个变量的值:
const test = shaderData.getFloat("u_float");
const test = shaderData.getInt("u_int");
const test = shaderData.getVector2("u_vec2");
const test = shaderData.getMatrix("u_matrix");
const test = shaderData.getTexture("u_sampler2D");