-
-
Notifications
You must be signed in to change notification settings - Fork 241
Expand file tree
/
Copy pathDepthDownsamplingPass.ts
More file actions
116 lines (75 loc) · 2.45 KB
/
DepthDownsamplingPass.ts
File metadata and controls
116 lines (75 loc) · 2.45 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { FloatType, NearestFilter, WebGLRenderTarget } from "three";
import { TextureResource } from "../core/io/TextureResource.js";
import { Pass } from "../core/Pass.js";
import { GBuffer } from "../enums/GBuffer.js";
import { DepthDownsamplingMaterial } from "../materials/DepthDownsamplingMaterial.js";
/**
* A downsampling pass that picks the most representative depth (and normal) in 2x2 texel neighborhoods.
*
* @category Passes
*/
export class DepthDownsamplingPass extends Pass<DepthDownsamplingMaterial> {
/**
* Identifies the depth output buffer.
*/
private static readonly BUFFER_DEPTH = "BUFFER_DEPTH";
/**
* Constructs a new depth downsampling pass.
*/
constructor() {
super("DepthDownsamplingPass");
this.fullscreenMaterial = new DepthDownsamplingMaterial();
this.input.gBuffer.add(GBuffer.DEPTH);
this.input.gBuffer.add(GBuffer.NORMAL);
this.output.setBuffer(
DepthDownsamplingPass.BUFFER_DEPTH,
new WebGLRenderTarget(1, 1, {
minFilter: NearestFilter,
magFilter: NearestFilter,
depthBuffer: false,
type: FloatType
})
);
}
/**
* The depth render target.
*/
private get renderTarget(): WebGLRenderTarget {
return this.output.getBuffer(DepthDownsamplingPass.BUFFER_DEPTH)!;
}
/**
* The output texture.
*/
get texture(): TextureResource {
return this.output.buffers.get(DepthDownsamplingPass.BUFFER_DEPTH)!.texture;
}
protected override onInputChange(): void {
this.fullscreenMaterial.depthBuffer = this.input.getBuffer(GBuffer.DEPTH);
this.fullscreenMaterial.normalBuffer = this.input.getBuffer(GBuffer.NORMAL);
this.onResolutionChange();
}
protected override onResolutionChange(): void {
// Use the resolution of the input buffer to calculate the depth/normal buffer texel size.
const inputBuffer = this.input.defaultBuffer?.value ?? null;
if(inputBuffer === null) {
return;
}
const imgData = inputBuffer.source.data as ImageData;
const { width, height } = imgData;
this.fullscreenMaterial.setSize(width, height);
}
override checkRequirements(): void {
if(this.renderer === null) {
return;
}
const gl = this.renderer.getContext();
const renderable = gl.getExtension("EXT_color_buffer_float") ?? gl.getExtension("EXT_color_buffer_half_float");
if(!renderable) {
throw new Error("Rendering to a float texture is not supported");
}
}
override render(): void {
this.setRenderTarget(this.renderTarget);
this.renderFullscreen();
}
}