Skip to content

Commit e721b03

Browse files
authored
FrameGraph: improved support for MSAA (resolve) textures + renaming of CullPass to ObjectListPass (#17447)
I also added the ability to set an `InternalTexture` texture in `ShaderMaterial`, to avoid wrapping it to a `BaseTexture`.
1 parent dd94d9e commit e721b03

File tree

17 files changed

+207
-37
lines changed

17 files changed

+207
-37
lines changed

packages/dev/core/src/Decorators/nodeDecorator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export const enum PropertyTypeForEdition {
1717
Vector3,
1818
/** property is a list of values */
1919
List,
20+
/** property is a Color3 */
21+
Color3,
2022
/** property is a Color4 */
2123
Color4,
2224
/** property (int) should be edited as a combo box with a list of sampling modes */

packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,26 @@ export class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock
246246
this._createFrameGraphObjectWithState(this.doNotChangeAspectRatio, value);
247247
}
248248

249+
/** If true, MSAA color textures will be resolved at the end of the render pass (default: true) */
250+
@editableInPropertyPage("Resolve MSAA colors", PropertyTypeForEdition.Boolean, "PROPERTIES")
251+
public get resolveMSAAColors() {
252+
return this._frameGraphTask.resolveMSAAColors;
253+
}
254+
255+
public set resolveMSAAColors(value: boolean) {
256+
this._frameGraphTask.resolveMSAAColors = value;
257+
}
258+
259+
/** If true, MSAA depth texture will be resolved at the end of the render pass (default: false) */
260+
@editableInPropertyPage("Resolve MSAA depth", PropertyTypeForEdition.Boolean, "PROPERTIES")
261+
public get resolveMSAADepth() {
262+
return this._frameGraphTask.resolveMSAADepth;
263+
}
264+
265+
public set resolveMSAADepth(value: boolean) {
266+
this._frameGraphTask.resolveMSAADepth = value;
267+
}
268+
249269
/**
250270
* Gets the current class name
251271
* @returns the class name
@@ -358,6 +378,8 @@ export class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock
358378
codes.push(`${this._codeVariableName}.enableOutlineRendering = ${this.enableOutlineRendering};`);
359379
codes.push(`${this._codeVariableName}.disableShadows = ${this.disableShadows};`);
360380
codes.push(`${this._codeVariableName}.renderInLinearSpace = ${this.renderInLinearSpace};`);
381+
codes.push(`${this._codeVariableName}.resolveMSAAColors = ${this.resolveMSAAColors};`);
382+
codes.push(`${this._codeVariableName}.resolveMSAADepth = ${this.resolveMSAADepth};`);
361383
return super._dumpPropertiesCode() + codes.join("\n");
362384
}
363385

@@ -373,6 +395,8 @@ export class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock
373395
serializationObject.enableOutlineRendering = this.enableOutlineRendering;
374396
serializationObject.disableShadows = this.disableShadows;
375397
serializationObject.renderInLinearSpace = this.renderInLinearSpace;
398+
serializationObject.resolveMSAAColors = this.resolveMSAAColors;
399+
serializationObject.resolveMSAADepth = this.resolveMSAADepth;
376400
return serializationObject;
377401
}
378402

@@ -388,5 +412,7 @@ export class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock
388412
this.enableOutlineRendering = serializationObject.enableOutlineRendering ?? true;
389413
this.disableShadows = serializationObject.disableShadows;
390414
this.renderInLinearSpace = !!serializationObject.renderInLinearSpace;
415+
this.resolveMSAAColors = serializationObject.resolveMSAAColors ?? true;
416+
this.resolveMSAADepth = serializationObject.resolveMSAADepth ?? false;
391417
}
392418
}

packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,26 @@ export class NodeRenderGraphGeometryRendererBlock extends NodeRenderGraphBlock {
202202
this._frameGraphTask.dontRenderWhenMaterialDepthWriteIsDisabled = value;
203203
}
204204

205+
/** If true, MSAA color textures will be resolved at the end of the render pass (default: true) */
206+
@editableInPropertyPage("Resolve MSAA colors", PropertyTypeForEdition.Boolean, "PROPERTIES")
207+
public get resolveMSAAColors() {
208+
return this._frameGraphTask.resolveMSAAColors;
209+
}
210+
211+
public set resolveMSAAColors(value: boolean) {
212+
this._frameGraphTask.resolveMSAAColors = value;
213+
}
214+
215+
/** If true, MSAA depth texture will be resolved at the end of the render pass (default: false) */
216+
@editableInPropertyPage("Resolve MSAA depth", PropertyTypeForEdition.Boolean, "PROPERTIES")
217+
public get resolveMSAADepth() {
218+
return this._frameGraphTask.resolveMSAADepth;
219+
}
220+
221+
public set resolveMSAADepth(value: boolean) {
222+
this._frameGraphTask.resolveMSAADepth = value;
223+
}
224+
205225
// View depth
206226
@editableInPropertyPage("View depth format", PropertyTypeForEdition.TextureFormat, "GEOMETRY BUFFERS")
207227
public viewDepthFormat = Constants.TEXTUREFORMAT_RED;
@@ -509,6 +529,8 @@ export class NodeRenderGraphGeometryRendererBlock extends NodeRenderGraphBlock {
509529
codes.push(`${this._codeVariableName}.velocityType = ${this.velocityType};`);
510530
codes.push(`${this._codeVariableName}.linearVelocityFormat = ${this.linearVelocityFormat};`);
511531
codes.push(`${this._codeVariableName}.linearVelocityType = ${this.linearVelocityType};`);
532+
codes.push(`${this._codeVariableName}.resolveMSAAColors = ${this.resolveMSAAColors};`);
533+
codes.push(`${this._codeVariableName}.resolveMSAADepth = ${this.resolveMSAADepth};`);
512534
return super._dumpPropertiesCode() + codes.join("\n");
513535
}
514536

@@ -542,6 +564,8 @@ export class NodeRenderGraphGeometryRendererBlock extends NodeRenderGraphBlock {
542564
serializationObject.velocityType = this.velocityType;
543565
serializationObject.linearVelocityFormat = this.linearVelocityFormat;
544566
serializationObject.linearVelocityType = this.linearVelocityType;
567+
serializationObject.resolveMSAAColors = this.resolveMSAAColors;
568+
serializationObject.resolveMSAADepth = this.resolveMSAADepth;
545569
return serializationObject;
546570
}
547571

@@ -575,6 +599,8 @@ export class NodeRenderGraphGeometryRendererBlock extends NodeRenderGraphBlock {
575599
this.velocityType = serializationObject.velocityType;
576600
this.linearVelocityFormat = serializationObject.linearVelocityFormat;
577601
this.linearVelocityType = serializationObject.linearVelocityType;
602+
this.resolveMSAAColors = serializationObject.resolveMSAAColors ?? true;
603+
this.resolveMSAADepth = serializationObject.resolveMSAADepth ?? false;
578604
}
579605
}
580606

packages/dev/core/src/FrameGraph/Node/Blocks/Textures/clearBlock.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ export class NodeRenderGraphClearBlock extends NodeRenderGraphBlock {
135135
protected override _buildBlock(state: NodeRenderGraphBuildState) {
136136
super._buildBlock(state);
137137

138-
this._propagateInputValueToOutput(this.target, this.output);
139-
this._propagateInputValueToOutput(this.depth, this.outputDepth);
138+
this.output.value = this._frameGraphTask.outputTexture;
139+
this.outputDepth.value = this._frameGraphTask.outputDepthTexture;
140140

141141
this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;
142142
this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;

packages/dev/core/src/FrameGraph/Node/Blocks/Textures/generateMipmapsBlock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class NodeRenderGraphGenerateMipmapsBlock extends NodeRenderGraphBlock {
6060
protected override _buildBlock(state: NodeRenderGraphBuildState) {
6161
super._buildBlock(state);
6262

63-
this._propagateInputValueToOutput(this.target, this.output);
63+
this.output.value = this._frameGraphTask.outputTexture;
6464

6565
this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;
6666
}

packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ export class NodeRenderGraph {
162162
this._frameGraph.name = name;
163163

164164
if (options.rebuildGraphOnEngineResize) {
165-
this._resizeObserver = this._engine.onResizeObservable.add(() => {
165+
this._resizeObserver = this._engine.onResizeObservable.add(async () => {
166166
this.build();
167+
168+
await this.whenReadyAsync();
167169
});
168170
}
169171
}

packages/dev/core/src/FrameGraph/Passes/cullPass.ts renamed to packages/dev/core/src/FrameGraph/Passes/objectListPass.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@ import type { Nullable, AbstractEngine, IFrameGraphPass, FrameGraphContext, Fram
22
import { FrameGraphPass } from "./pass";
33

44
/**
5-
* Cull pass used to filter objects that are not visible.
5+
* Object list pass used to generate a list of objects.
66
*/
7-
export class FrameGraphCullPass extends FrameGraphPass<FrameGraphContext> {
7+
export class FrameGraphObjectListPass extends FrameGraphPass<FrameGraphContext> {
88
protected readonly _engine: AbstractEngine;
99
protected _objectList: FrameGraphObjectList;
1010

1111
/**
12-
* Checks if a pass is a cull pass.
12+
* Checks if a pass is an object list pass.
1313
* @param pass The pass to check.
14-
* @returns True if the pass is a cull pass, else false.
14+
* @returns True if the pass is an object list pass, else false.
1515
*/
16-
public static IsCullPass(pass: IFrameGraphPass): pass is FrameGraphCullPass {
17-
return (pass as FrameGraphCullPass).setObjectList !== undefined;
16+
public static IsObjectListPass(pass: IFrameGraphPass): pass is FrameGraphObjectListPass {
17+
return (pass as FrameGraphObjectListPass).setObjectList !== undefined;
1818
}
1919

2020
/**
21-
* Gets the object list used by the cull pass.
21+
* Gets the object list used by the pass.
2222
*/
2323
public get objectList(): FrameGraphObjectList {
2424
return this._objectList;
2525
}
2626

2727
/**
28-
* Sets the object list to use for culling.
29-
* @param objectList The object list to use for culling.
28+
* Sets the object list to use for the pass.
29+
* @param objectList The object list to use for the pass.
3030
*/
3131
public setObjectList(objectList: FrameGraphObjectList) {
3232
this._objectList = objectList;

packages/dev/core/src/FrameGraph/Passes/renderPass.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,26 @@ export class FrameGraphRenderPass extends FrameGraphPass<FrameGraphRenderContext
2121
}
2222

2323
/**
24-
* Gets the render target(s) used by the render pass.
24+
* Gets the handle(s) of the render target(s) used by the render pass.
2525
*/
2626
public get renderTarget(): FrameGraphTextureHandle | FrameGraphTextureHandle[] | undefined {
2727
return this._renderTarget;
2828
}
2929

3030
/**
31-
* Gets the render target depth used by the render pass.
31+
* Gets the handle of the render target depth used by the render pass.
3232
*/
3333
public get renderTargetDepth(): FrameGraphTextureHandle | undefined {
3434
return this._renderTargetDepth;
3535
}
3636

37+
/**
38+
* Gets the frame graph render target used by the render pass.
39+
*/
40+
public get frameGraphRenderTarget(): FrameGraphRenderTarget | undefined {
41+
return this._frameGraphRenderTarget;
42+
}
43+
3744
/**
3845
* If true, the depth attachment will be read-only (may allow some optimizations in WebGPU)
3946
*/
@@ -121,6 +128,13 @@ export class FrameGraphRenderPass extends FrameGraphPass<FrameGraphRenderContext
121128
super._execute();
122129

123130
this._context._flushDebugMessages();
131+
132+
const renderTargetWrapper = this._frameGraphRenderTarget.renderTargetWrapper;
133+
if (renderTargetWrapper && (renderTargetWrapper.resolveMSAAColors || renderTargetWrapper.resolveMSAADepth || renderTargetWrapper.resolveMSAAStencil)) {
134+
// Unbinding the render target will trigger resolving MSAA textures.
135+
this._context.bindRenderTarget(undefined, `frame graph render pass - ${this.name} - resolve MSAA`, true);
136+
this._context._flushDebugMessages();
137+
}
124138
}
125139

126140
/** @internal */

packages/dev/core/src/FrameGraph/Tasks/Misc/cullObjectsTask.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class FrameGraphCullObjectsTask extends FrameGraphTask {
4646
this.outputObjectList.meshes = this.objectList.meshes;
4747
this.outputObjectList.particleSystems = this.objectList.particleSystems;
4848

49-
const pass = this._frameGraph.addCullPass(this.name);
49+
const pass = this._frameGraph.addObjectListPass(this.name);
5050

5151
pass.setObjectList(this.outputObjectList);
5252
pass.setExecuteFunc((_context) => {
@@ -82,7 +82,7 @@ export class FrameGraphCullObjectsTask extends FrameGraphTask {
8282
}
8383
});
8484

85-
const passDisabled = this._frameGraph.addCullPass(this.name + "_disabled", true);
85+
const passDisabled = this._frameGraph.addObjectListPass(this.name + "_disabled", true);
8686

8787
passDisabled.setObjectList(this.outputObjectList);
8888
passDisabled.setExecuteFunc((_context) => {

packages/dev/core/src/FrameGraph/Tasks/Rendering/geometryRendererTask.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ export class FrameGraphGeometryRendererTask extends FrameGraphTask {
115115
*/
116116
public dontRenderWhenMaterialDepthWriteIsDisabled = true;
117117

118+
/**
119+
* If true, the output geometry texture(s) will be resolved at the end of the render pass, if samples is greater than 1 (default: true)
120+
*/
121+
public resolveMSAAColors = true;
122+
123+
/**
124+
* If true, depthTexture will be resolved at the end of the render pass, if this texture is provided and samples is greater than 1 (default: true)
125+
*/
126+
public resolveMSAADepth = false;
127+
118128
/**
119129
* The list of texture descriptions used by the geometry renderer task.
120130
*/
@@ -403,6 +413,9 @@ export class FrameGraphGeometryRendererTask extends FrameGraphTask {
403413
this._renderer.renderList = this.objectList.meshes;
404414
this._renderer.particleSystemList = this.objectList.particleSystems;
405415

416+
pass.frameGraphRenderTarget!.renderTargetWrapper!.resolveMSAAColors = this.resolveMSAAColors;
417+
pass.frameGraphRenderTarget!.renderTargetWrapper!.resolveMSAADepth = this.resolveMSAADepth;
418+
406419
context.setDepthStates(this.depthTest && depthEnabled, this.depthWrite && depthEnabled);
407420

408421
this._clearAttachmentsLayout.forEach((layout, clearType) => {

0 commit comments

Comments
 (0)