2019-10-08 19:20:12 +08:00
|
|
|
|
# MultiPassRenderer 实现
|
|
|
|
|
|
|
|
|
|
每个 Layer 渲染时都需要经历多个流程,从最简单的清屏、拾取到各种各样的后处理。我们希望把复杂渲染流程中每个步骤都抽象出来,让 L7 内部以及用户能够方便的扩展,进行渲染流程的自定义。其中的每一个步骤称作 Pass,负责串联调用各个 Pass 的渲染器称作 MultiPassRenderer。
|
|
|
|
|
|
|
|
|
|
![](./screenshots/blurpass.png)
|
|
|
|
|
|
|
|
|
|
## 接口设计
|
|
|
|
|
|
|
|
|
|
目前我们将 Pass 分成两类:
|
|
|
|
|
1. 渲染相关。例如 ClearPass、RenderPass、PickingPass、ShadowPass
|
|
|
|
|
2. 后处理相关。例如 CopyPass、BlurPass
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
export enum PassType {
|
|
|
|
|
Normal = 'normal',
|
|
|
|
|
PostProcessing = 'post-processing',
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
每个 Pass 定义两个生命周期节点,初始化和渲染,并将当前 Layer 作为参数传入。因此 Pass 中可以访问 Layer 上的属性及方法:
|
|
|
|
|
```typescript
|
|
|
|
|
export interface IPass {
|
|
|
|
|
getType(): PassType;
|
|
|
|
|
init(layer: ILayer): void;
|
|
|
|
|
render(layer: ILayer): void;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
其中后处理相关的 Pass 比较特殊,例如最后一个 PostProcessingPass 需要自动切换 renderTarget 为屏幕:
|
|
|
|
|
```typescript
|
|
|
|
|
export interface IPostProcessingPass extends IPass {
|
|
|
|
|
setRenderToScreen(renderToScreen: boolean): void;
|
|
|
|
|
isEnabled(): boolean;
|
|
|
|
|
setEnabled(enabled: boolean): void;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
具体实现依赖 `@l7/renderer` 实现,目前使用 regl 实现 IFramebuffer 等接口。
|
|
|
|
|
|
|
|
|
|
## 内置 Pass
|
|
|
|
|
|
|
|
|
|
目前我们仅对外开放 PostProcessing 后处理相关 Pass 的配置。在 L7 内部我们使用如下流程:
|
|
|
|
|
```
|
|
|
|
|
ClearPass -> RenderPass -> [ ...其他后处理 Pass ] -> CopyPass
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
目前各内置 Pass 说明如下:
|
2019-10-08 20:25:39 +08:00
|
|
|
|
|
2019-10-08 19:20:12 +08:00
|
|
|
|
| Pass 名称 | 类型 | 参数 | 说明 |
|
|
|
|
|
| -------- | --- | ------------- | --------- |
|
|
|
|
|
| ClearPass | normal | 无 | 清除 framebuffer,clearColor 为 [0, 0, 0, 0] |
|
|
|
|
|
| RenderPass | normal | 无 | 渲染到 framebuffer,作为后续后处理的输入 |
|
2019-10-30 15:21:13 +08:00
|
|
|
|
| PickingPass | normal | 无 | 负责拾取,[详见](./PixelPickingEngine.md) |
|
|
|
|
|
| TAAPass | normal | 无 | [详见](./TAA.md) |
|
2019-10-08 19:20:12 +08:00
|
|
|
|
| CopyPass | post-processing | 无 | 作为后处理最后一个 Pass,负责拷贝 framebuffer 到屏幕输出 |
|
|
|
|
|
|
2019-10-30 15:21:13 +08:00
|
|
|
|
剩余后处理效果见最后一节。
|
2019-10-08 19:20:12 +08:00
|
|
|
|
后续待实现 Pass 如下:
|
2019-10-08 20:25:39 +08:00
|
|
|
|
|
|
|
|
|
- [ ] ShadowPass 负责生成 shadowMap,供 PCF、CSM 等实时阴影技术使用
|
2019-10-08 19:20:12 +08:00
|
|
|
|
|
|
|
|
|
## 使用方法
|
|
|
|
|
|
|
|
|
|
在每个 Layer 中,通过 `enableMultiPassRenderer` 开启之后,可以配置各个 Pass 的参数。配置方法类似 babel 插件:
|
|
|
|
|
```typescript
|
|
|
|
|
const layer = new PolygonLayer({
|
|
|
|
|
enableMultiPassRenderer: true,
|
|
|
|
|
passes: [
|
|
|
|
|
'blurH', // 使用 BlurHPass
|
|
|
|
|
[
|
|
|
|
|
'blurV', // 使用 BlurVPass
|
|
|
|
|
{
|
|
|
|
|
blurRadius: 20, // 设置模糊半径
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
});
|
2019-10-08 20:25:39 +08:00
|
|
|
|
```
|
2019-10-30 15:21:13 +08:00
|
|
|
|
|
|
|
|
|
## 内置后处理效果
|
|
|
|
|
|
|
|
|
|
参考了 [glfx](https://github.com/evanw/glfx.js) 中的一些常用图像处理效果。可以按照名称引用,顺序决定了各个效果的应用次序。例如我们想依次应用噪声和模糊效果:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
const layer = new PolygonLayer({
|
|
|
|
|
passes: [
|
|
|
|
|
[
|
|
|
|
|
'noise', // 使用 NoisePass
|
|
|
|
|
{
|
|
|
|
|
amount: 0.5,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
'blurH', // 使用 BlurHPass
|
|
|
|
|
'blurV', // 使用 BlurVPass
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
下面详细介绍各个后处理效果及其参数,在 DEMO 中也可以通过 GUI 任意调节参数。
|
|
|
|
|
|
|
|
|
|
### 高斯模糊
|
|
|
|
|
|
|
|
|
|
采用 [高斯模糊 blur9](https://github.com/Jam3/glsl-fast-gaussian-blur/blob/master/9.glsl)。
|
|
|
|
|
|
|
|
|
|
名称:`blurH/blurV`
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
* `blurRadius` 水平/垂直方向模糊半径,默认值为 `8.0`
|
|
|
|
|
|
|
|
|
|
效果如下:
|
|
|
|
|
|
|
|
|
|
![](./screenshots/blurpass.png)
|
|
|
|
|
|
|
|
|
|
### ColorHalftone
|
|
|
|
|
|
|
|
|
|
CMYK halftone 效果
|
|
|
|
|
|
|
|
|
|
名称:`colorHalftone`
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
* `angle` pattern 旋转角度,默认值为 0
|
|
|
|
|
* `size` pattern 大小,默认值为 8
|
|
|
|
|
* `center` `[x, y]` pattern 的中心,默认值为 `[0, 0]`
|
|
|
|
|
|
|
|
|
|
效果如下:
|
|
|
|
|
|
|
|
|
|
![](./screenshots/halftone.png)
|
|
|
|
|
|
|
|
|
|
### 噪声
|
|
|
|
|
|
|
|
|
|
噪声效果。
|
|
|
|
|
|
|
|
|
|
名称:`noise`
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
* `amount` 噪声程度,范围 `[0, 1]`,默认值为 `0.5`
|
|
|
|
|
|
|
|
|
|
效果如下:
|
|
|
|
|
|
|
|
|
|
![](./screenshots/noise.png)
|
|
|
|
|
|
|
|
|
|
### 六边形像素化处理
|
|
|
|
|
|
|
|
|
|
六边形像素化处理。
|
|
|
|
|
|
|
|
|
|
名称:`hexagonalPixelate`
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
* `scale` 六边形大小,默认值为 `10`
|
|
|
|
|
* `center` `[x, y]` pattern 的中心,默认值为 `[0.5, 0.5]`
|
|
|
|
|
|
|
|
|
|
效果如下:
|
|
|
|
|
|
|
|
|
|
![](./screenshots/hexagonalPixelate.png)
|
|
|
|
|
|
|
|
|
|
### Sepia
|
|
|
|
|
|
|
|
|
|
Sepia 颜色映射。
|
|
|
|
|
|
|
|
|
|
名称:`sepia`
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
* `amount` 程度,范围 `[0, 1]`,默认值为 `0.5`
|
|
|
|
|
|
|
|
|
|
效果如下:
|
|
|
|
|
|
|
|
|
|
![](./screenshots/sepia.png)
|