-
Notifications
You must be signed in to change notification settings - Fork 46
/
shadow-render-pass.ts
70 lines (64 loc) · 2.08 KB
/
shadow-render-pass.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { Renderer } from "@pixi/core"
import { RenderPass } from "../pipeline/render-pass"
import { Mesh3D } from "../mesh/mesh"
import { ShadowFilter } from "./shadow-filter"
import { ShadowCastingLight } from "./shadow-casting-light"
import { ShadowRenderer } from "./shadow-renderer"
/**
* Pass used for rendering shadows.
*/
export class ShadowRenderPass implements RenderPass {
private _lights: ShadowCastingLight[] = []
private _filter: ShadowFilter
private _shadow: ShadowRenderer
/**
* Creates a new shadow render pass using the specified renderer.
* @param renderer The renderer to use.
* @param name The name for the render pass.
*/
constructor(public renderer: Renderer, public name = "shadow") {
this._filter = new ShadowFilter(renderer)
this._shadow = new ShadowRenderer(renderer)
}
/**
* Adds a shadow casting light.
* @param shadowCastingLight The light to add.
*/
addShadowCastingLight(shadowCastingLight: ShadowCastingLight) {
if (this._lights.indexOf(shadowCastingLight) < 0) {
this._lights.push(shadowCastingLight)
}
}
/**
* Removes a shadow casting light.
* @param shadowCastingLight The light to remove.
*/
removeShadowCastingLight(shadowCastingLight: ShadowCastingLight) {
const index = this._lights.indexOf(shadowCastingLight)
if (index >= 0) {
this._lights.splice(index, 1)
}
}
clear() {
for (let shadowCastingLight of this._lights) {
shadowCastingLight.clear()
}
}
render(meshes: Mesh3D[]) {
if (meshes.length === 0 || this._lights.length === 0) {
return
}
const current = this.renderer.renderTexture.current
for (let shadowCastingLight of this._lights) {
this.renderer.renderTexture.bind(shadowCastingLight.shadowTexture)
shadowCastingLight.updateLightViewProjection()
for (let mesh of meshes) {
this._shadow.render(mesh, shadowCastingLight)
}
if (shadowCastingLight.softness > 0) {
this._filter.applyGaussianBlur(shadowCastingLight)
}
}
this.renderer.renderTexture.bind(current || undefined)
}
}