mirror of
https://github.com/galacean/engine.git
synced 2026-05-18 02:47:16 +08:00
190 lines
6.5 KiB
Plaintext
190 lines
6.5 KiB
Plaintext
---
|
||
title: 材质的基本使用
|
||
---
|
||
|
||
## 创建材质
|
||
|
||
创建材质一般有以下 3 种方式:
|
||
|
||
### 1. 手动创建
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/b01b0ee2-317e-4acb-8c2f-e07736179d67/image-20240206163405147.png" />
|
||
|
||
### 2. 模型中的材质
|
||
|
||
参考[模型的导入和使用](/docs/graphics/model/use/)教程,我们可以先将模型导入到编辑器,一般情况下,模型已经自动绑定好材质,用户可以不用做任何操作;
|
||
|
||
#### 2.1. Remap 材质
|
||
|
||
如果想要修改模型材质,我们可以点击 `duplicate and remap` 按钮来生成一份该材质的副本,注意 Remap 会修改模型预设,如下图所有模型实例都会受到影响:
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/4a41f66e-5523-43f0-a9b5-4028b9d14cbc/2025-01-24%25252015.30.31.gif" />
|
||
|
||
#### 2.2. 增量修改
|
||
|
||
如果只想修改某个模型的材质,可以使用增量修改的功能:
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/5d2409f2-a7b2-4b5e-9e6a-9845c3358af3/2025-01-24%25252015.32.04.gif" />
|
||
|
||
|
||
### 3. 绑定材质
|
||
|
||
我们直接将材质拖到场景中即可进行绑定。
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/62d6a8cb-fd70-4c37-beab-9dacc8ae4d5b/2025-05-23%25252017.13.59.gif" />
|
||
|
||
### 4. 脚本方式
|
||
|
||
我们还可以通过脚本来创建/修改材质,我们将脚本挂载到立方体实体上,实现替换材质的一个 Demo:
|
||
|
||
```ts showLineNumbers
|
||
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 观察实时渲染效果变化。
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/cd87c11a-7a68-4cde-a19a-40cff943e878/2025-02-10%25252017.05.33.gif" />
|
||
|
||
|
||
|
||
每个 Shader 有不同的渲染效果和应用场景,更多详情参考 [内置着色器教程](/docs/graphics/material/builtinShaders/pbr/) 和 [自定义 Shader 实战教程](/docs/graphics/material/examples/shaderlab-01-basic-shader) 。
|
||
|
||
|
||
## 创建自定义 Shader
|
||
如果内置 Shader 不能满足需求,我们可以自定义一个Shader,在编辑器资产面板中,新建 Shader,选择 PBR 模板或者 Unlit 模板:
|
||
|
||
<img
|
||
src="https://gw.alipayobjects.com/zos/OasisHub/9abd1026-4e4d-4994-b36a-f964375c38cb/image-20240731105324320.png"
|
||
style={{ zoom: "50%" }}
|
||
/>
|
||
|
||
编辑器会自动帮我们创建好 Shader 文件和 [UIScript](/docs/graphics/material/shader/#uiscript-脚本系统) 文件。
|
||
|
||
<img
|
||
src="https://gw.alipayobjects.com/zos/OasisHub/6351fa81-5159-4469-bd95-8f21a8f2f4ac/image-20250124162909194.png"
|
||
style={{ zoom: "50%" }}
|
||
/>
|
||
|
||
<Callout type="info">
|
||
具体 shader 内容编写可以从 [自定义 Shader 实战教程](/docs/graphics/material/examples/shaderlab-01-basic-shader) 快速上手。
|
||
</Callout>
|
||
|
||
## Shader 数据的传输
|
||
|
||
跟别的编程语言一样,我们在写 Shader 过程中也会用到很多变量,首先引擎有很多 [内置变量](/docs/graphics/material/variables),这部分的变量我们是不需要手动设置的,可以直接在 shader 中使用。接下来我们看看如何设置和使用自定义数据。
|
||
|
||
### 声明变量
|
||
```glsl showLineNumbers
|
||
...
|
||
Pass "Forward" {
|
||
// 声明自定义变量
|
||
vec4 u_color;
|
||
|
||
// 声明引擎内置变量
|
||
mat4 renderer_MVPMat;
|
||
|
||
// 通过引入代码片段
|
||
#include "Transform.glsl"
|
||
}
|
||
...
|
||
```
|
||
|
||
|
||
### 设置数据
|
||
Shader 支持通过 [UIScript](/docs/graphics/material/shader/#uiscript-脚本系统) 帮我们自动生成可以交互的面板:
|
||
|
||
<div style={{display: "flex"}}>
|
||
|
||
<Image src="https://mdn.alipayobjects.com/huamei_aftkdx/afts/img/A*mwAxRr45kE8AAAAAAAAAAAAAeteEAQ/fmt.webp" width="435px" />
|
||
|
||
<Image src= "https://mdn.alipayobjects.com/huamei_aftkdx/afts/img/A*7MrxTIG5fpkAAAAAAAAAAAAAeteEAQ/fmt.webp" width="200px" />
|
||
|
||
</div>
|
||
|
||
|
||
<Callout type="info">
|
||
参考 [Shader Editor 模块 ](/docs/graphics/material/shader/#2-editor-模块) 使用更多类型的数据和宏。
|
||
</Callout>
|
||
|
||
当然,我们也可以通过代码设置着色器数据:
|
||
|
||
```ts showLineNumbers
|
||
// 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 中直接使用,如下:
|
||
|
||
```glsl showLineNumbers filename="test.glsl"
|
||
float test = u_float;
|
||
int test = u_int;
|
||
bool test = u_bool;
|
||
vec2 test = u_vec2;
|
||
mat4 test = u_matrix;
|
||
sampler2D test = u_sampler2D;
|
||
...
|
||
```
|
||
|
||
你也可以通过代码获取这个变量的值:
|
||
|
||
```ts showLineNumbers filename="test.ts"
|
||
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");
|
||
```
|
||
|
||
## 下一步学习
|
||
- [自定义 Shader](/docs/graphics/material/examples/shaderlab-01-basic-shader) - 从 0 开始 Shader 创作之旅
|
||
- [Shader 语法深入学习](/docs/graphics/material/shader) - 完整的语法参考
|
||
- [Shader 内置变量参考](/docs/graphics/material/variables) - 引擎提供的所有内置变量
|
||
- [Shader 内置 API 参考](/docs/graphics/material/shaderAPI) - 引擎提供的所有 Shader API
|
||
- [光照系统](/docs/graphics/light/light) - 实现更真实的光照效果 |