Skip to content

Commit a40bb34

Browse files
committed
Fix clearing without background
and optimize clear ops
1 parent 5d77a04 commit a40bb34

File tree

2 files changed

+49
-51
lines changed

2 files changed

+49
-51
lines changed

src/passes/ClearPass.ts

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ClearFlags } from "../utils/ClearFlags.js";
66
import { ClearValues } from "../utils/ClearValues.js";
77

88
const color = /* @__PURE__ */ new Color();
9+
const fv = /* @__PURE__ */ new Float32Array(4);
910

1011
/**
1112
* A clear pass.
@@ -76,36 +77,47 @@ export class ClearPass extends Pass {
7677
}
7778

7879
/**
79-
* Clears G-Buffer components.
80+
* Clears all buffer attachments with the respective clear values.
8081
*
82+
* @remarks `gl.clearBufferfv` expects 4 floats regardless of the target buffer format.
8183
* @see https://www.khronos.org/opengl/wiki/Framebuffer#Buffer_clearing
8284
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/clearBuffer
85+
* @param gl - A rendering context.
86+
* @param textureIndices - The indices of the texture attachments that should be cleared.
8387
*/
8488

85-
private clearGBuffer(): void {
89+
private clearBuffers(gl: WebGL2RenderingContext, textureIndices: Map<string, number>): void {
8690

87-
if(this.renderer === null || this.gBufferIndices === null) {
91+
const flags = this.clearFlags;
92+
const clearValues = this.clearValues.gBuffer;
8893

89-
return;
94+
for(const entry of textureIndices) {
9095

91-
}
96+
const clearValue = clearValues.get(entry[0]);
9297

93-
const flags = this.clearFlags;
94-
const values = this.clearValues;
95-
const gBufferTextureIndices = this.gBufferIndices;
96-
const gl = this.renderer.getContext() as WebGL2RenderingContext;
98+
if(!flags.gBuffer.has(entry[0]) || clearValue === undefined) {
9799

98-
for(const entry of values.gBuffer) {
100+
continue;
101+
102+
}
99103

100-
const index = gBufferTextureIndices.get(entry[0]);
104+
if(typeof clearValue === "number") {
101105

102-
if(!flags.gBuffer.has(entry[0]) || index === undefined) {
106+
fv[0] = clearValue;
107+
fv[1] = 0.0;
108+
fv[2] = 0.0;
109+
fv[3] = 1.0;
103110

104-
continue;
111+
} else {
112+
113+
fv[0] = (clearValue.length > 0) ? clearValue[0] : 0.0;
114+
fv[1] = (clearValue.length > 1) ? clearValue[1] : 0.0;
115+
fv[2] = (clearValue.length > 2) ? clearValue[2] : 0.0;
116+
fv[3] = (clearValue.length > 3) ? clearValue[3] : 1.0;
105117

106118
}
107119

108-
gl.clearBufferfv(gl.COLOR, index, entry[1]);
120+
gl.clearBufferfv(gl.COLOR, entry[1], fv);
109121

110122
}
111123

@@ -114,45 +126,29 @@ export class ClearPass extends Pass {
114126
/**
115127
* Clears the default output buffer using the current clear values.
116128
*
117-
* @param overrideClearColor - An override clear color.
129+
* @param clearColor - An override clear color.
118130
*/
119131

120-
private clear(overrideClearColor = this.clearValues.color): void {
132+
private clear(clearColor = this.clearValues.color): void {
121133

122134
const renderer = this.renderer!;
123-
const flags = this.clearFlags;
124-
const overrideClearAlpha = this.clearValues.alpha;
125-
const hasOverrideClearColor = overrideClearColor !== null;
126-
const hasOverrideClearAlpha = overrideClearAlpha !== null;
127-
const clearAlpha = renderer.getClearAlpha();
128-
129-
if(hasOverrideClearColor) {
130-
131-
renderer.getClearColor(color);
132-
renderer.setClearColor(overrideClearColor);
133-
134-
}
135-
136-
if(hasOverrideClearAlpha) {
135+
const gl = renderer.getContext() as WebGL2RenderingContext;
136+
const clearAlpha = this.clearValues.alpha ?? renderer.getClearAlpha();
137+
clearColor ??= renderer.getClearColor(color);
137138

138-
renderer.setClearAlpha(overrideClearAlpha);
139+
fv[0] = clearColor.r;
140+
fv[1] = clearColor.g;
141+
fv[2] = clearColor.b;
142+
fv[3] = clearAlpha;
139143

140-
}
141-
142-
renderer.clear(flags.color, flags.depth, flags.stencil);
143-
144-
if(hasOverrideClearColor) {
145-
146-
renderer.setClearColor(color, clearAlpha);
144+
gl.clearBufferfv(gl.COLOR, 0, fv);
147145

148-
} else if(hasOverrideClearAlpha) {
146+
if(this.gBufferIndices !== null && this.gBufferIndices.size > 1) {
149147

150-
renderer.setClearAlpha(clearAlpha);
148+
this.clearBuffers(gl, this.gBufferIndices);
151149

152150
}
153151

154-
this.clearGBuffer();
155-
156152
}
157153

158154
/**
@@ -164,20 +160,13 @@ export class ClearPass extends Pass {
164160
const scene = this.scene!;
165161
const camera = this.camera!;
166162
const renderer = this.renderer!;
167-
const flags = this.clearFlags;
168163

169164
if(scene.background instanceof Color) {
170165

171166
this.clear(scene.background);
172167

173168
} else {
174169

175-
if(flags.depth || flags.stencil) {
176-
177-
renderer.clear(false, flags.depth, flags.stencil);
178-
179-
}
180-
181170
this.background.update(scene);
182171
renderer.render(this.backgroundScene, camera);
183172

@@ -217,9 +206,16 @@ export class ClearPass extends Pass {
217206

218207
const background = this.scene?.background ?? null;
219208
const hasOverrideClearColor = this.clearValues.color !== null;
209+
const flags = this.clearFlags;
220210

221211
this.setRenderTarget(this.output.defaultBuffer?.value);
222212

213+
if(flags.depth || flags.stencil) {
214+
215+
this.renderer.clear(false, flags.depth, flags.stencil);
216+
217+
}
218+
223219
if(!hasOverrideClearColor && this.camera !== null && background !== null) {
224220

225221
this.clearWithBackground();

src/utils/ClearValues.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ export class ClearValues extends EventDispatcher<BaseEventMap> {
2525

2626
/**
2727
* A collection that maps {@link GBuffer} components to clear values.
28+
*
29+
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/clearBuffer
2830
*/
2931

30-
readonly gBuffer: Map<string, Iterable<GLfloat>>;
32+
readonly gBuffer: Map<string, GLfloat | GLfloat[]>;
3133

3234
/**
3335
* Constructs new clear values.
@@ -40,7 +42,7 @@ export class ClearValues extends EventDispatcher<BaseEventMap> {
4042
this._color = null;
4143
this._alpha = null;
4244

43-
const gBuffer = new ObservableMap<string, Iterable<GLfloat>>([
45+
const gBuffer = new ObservableMap<string, GLfloat | GLfloat[]>([
4446
[GBuffer.NORMAL, [0.0, 0.0]],
4547
[GBuffer.ORM, [1.0, 0.0, 0.0, 1.0]],
4648
[GBuffer.EMISSION, [0.0, 0.0, 0.0, 1.0]]

0 commit comments

Comments
 (0)