Skip to content

Commit a2dd6ed

Browse files
Popov72RolandCsibrei
authored andcommitted
1 parent 86b93cd commit a2dd6ed

30 files changed

+511
-156
lines changed

packages/dev/core/src/Engines/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ export class Constants {
666666
*/
667667
public static readonly PREPASS_COLOR_TEXTURE_TYPE = 4;
668668
/**
669-
* Constant used to retrieve depth index in the textures array in the prepass
669+
* Constant used to retrieve (camera view) depth index in the textures array in the prepass
670670
* using the getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)
671671
*/
672672
public static readonly PREPASS_DEPTH_TEXTURE_TYPE = 5;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// eslint-disable-next-line import/no-internal-modules
2+
import type { NodeRenderGraphConnectionPoint, Scene, NodeRenderGraphBuildState, FrameGraphTextureHandle, FrameGraph } from "core/index";
3+
import { RegisterClass } from "../../../../Misc/typeStore";
4+
import { NodeRenderGraphBlockConnectionPointTypes } from "../../Types/nodeRenderGraphTypes";
5+
import { editableInPropertyPage, PropertyTypeForEdition } from "../../../../Decorators/nodeDecorator";
6+
import { FrameGraphMotionBlurTask } from "core/FrameGraph/Tasks/PostProcesses/motionBlurTask";
7+
import { ThinMotionBlurPostProcess } from "core/PostProcesses/thinMotionBlurPostProcess";
8+
import { NodeRenderGraphBasePostProcessBlock } from "./basePostProcessBlock";
9+
10+
/**
11+
* Block that implements the motion blur post process
12+
*/
13+
export class NodeRenderGraphMotionBlurPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {
14+
protected override _frameGraphTask: FrameGraphMotionBlurTask;
15+
16+
/**
17+
* Gets the frame graph task associated with this block
18+
*/
19+
public override get task() {
20+
return this._frameGraphTask;
21+
}
22+
23+
/**
24+
* Create a new NodeRenderGraphMotionBlurPostProcessBlock
25+
* @param name defines the block name
26+
* @param frameGraph defines the hosting frame graph
27+
* @param scene defines the hosting scene
28+
*/
29+
public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {
30+
super(name, frameGraph, scene);
31+
32+
this.registerInput("geomVelocity", NodeRenderGraphBlockConnectionPointTypes.TextureVelocity, true);
33+
this.registerInput("geomViewDepth", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth, true);
34+
35+
this._finalizeInputOutputRegistering();
36+
37+
this._frameGraphTask = new FrameGraphMotionBlurTask(this.name, frameGraph, new ThinMotionBlurPostProcess(name, frameGraph.scene));
38+
}
39+
40+
/** Defines how much the image is blurred by the movement. */
41+
@editableInPropertyPage("Strength", PropertyTypeForEdition.Float, "PROPERTIES")
42+
public get motionStrength(): number {
43+
return this._frameGraphTask.postProcess.motionStrength;
44+
}
45+
46+
public set motionStrength(value: number) {
47+
this._frameGraphTask.postProcess.motionStrength = value;
48+
}
49+
50+
/** Gets the number of iterations that are used for motion blur quality. */
51+
@editableInPropertyPage("Samples", PropertyTypeForEdition.Float, "PROPERTIES")
52+
public get motionBlurSamples(): number {
53+
return this._frameGraphTask.postProcess.motionBlurSamples;
54+
}
55+
56+
public set motionBlurSamples(value: number) {
57+
this._frameGraphTask.postProcess.motionBlurSamples = value;
58+
}
59+
60+
/** Gets whether or not the motion blur post-process is in object based mode. */
61+
@editableInPropertyPage("Object based", PropertyTypeForEdition.Boolean, "PROPERTIES")
62+
public get isObjectBased(): boolean {
63+
return this._frameGraphTask.postProcess.isObjectBased;
64+
}
65+
66+
public set isObjectBased(value: boolean) {
67+
this._frameGraphTask.postProcess.isObjectBased = value;
68+
}
69+
70+
/**
71+
* Gets the current class name
72+
* @returns the class name
73+
*/
74+
public override getClassName() {
75+
return "NodeRenderGraphMotionBlurPostProcessBlock";
76+
}
77+
78+
/**
79+
* Gets the geometry velocity input component
80+
*/
81+
public get geomVelocity(): NodeRenderGraphConnectionPoint {
82+
return this._inputs[2];
83+
}
84+
85+
/**
86+
* Gets the geometry view depth input component
87+
*/
88+
public get geomViewDepth(): NodeRenderGraphConnectionPoint {
89+
return this._inputs[3];
90+
}
91+
92+
protected override _buildBlock(state: NodeRenderGraphBuildState) {
93+
super._buildBlock(state);
94+
95+
this._frameGraphTask.velocityTexture = this.geomVelocity.connectedPoint?.value as FrameGraphTextureHandle;
96+
this._frameGraphTask.depthTexture = this.geomViewDepth.connectedPoint?.value as FrameGraphTextureHandle;
97+
}
98+
99+
protected override _dumpPropertiesCode() {
100+
const codes: string[] = [];
101+
codes.push(`${this._codeVariableName}.motionStrength = ${this.motionStrength};`);
102+
codes.push(`${this._codeVariableName}.motionBlurSamples = ${this.motionBlurSamples};`);
103+
codes.push(`${this._codeVariableName}.isObjectBased = ${this.isObjectBased};`);
104+
return super._dumpPropertiesCode() + codes.join("\n");
105+
}
106+
107+
public override serialize(): any {
108+
const serializationObject = super.serialize();
109+
serializationObject.motionStrength = this.motionStrength;
110+
serializationObject.motionBlurSamples = this.motionBlurSamples;
111+
serializationObject.isObjectBased = this.isObjectBased;
112+
return serializationObject;
113+
}
114+
115+
public override _deserialize(serializationObject: any) {
116+
super._deserialize(serializationObject);
117+
this.motionStrength = serializationObject.motionStrength;
118+
this.motionBlurSamples = serializationObject.motionBlurSamples;
119+
this.isObjectBased = serializationObject.isObjectBased;
120+
}
121+
}
122+
123+
RegisterClass("BABYLON.NodeRenderGraphMotionBlurPostProcessBlock", NodeRenderGraphMotionBlurPostProcessBlock);

packages/dev/core/src/FrameGraph/Node/Blocks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export * from "./PostProcesses/extractHighlightsPostProcessBlock";
1919
export * from "./PostProcesses/fxaaPostProcessBlock";
2020
export * from "./PostProcesses/grainPostProcessBlock";
2121
export * from "./PostProcesses/imageProcessingPostProcessBlock";
22+
export * from "./PostProcesses/motionBlurPostProcessBlock";
2223
export * from "./PostProcesses/passPostProcessBlock";
2324
export * from "./PostProcesses/ssrPostProcessBlock";
2425

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ export class FrameGraphRenderPass extends FrameGraphPass<FrameGraphRenderContext
6161
* Adds dependencies to the render pass.
6262
* @param dependencies The dependencies to add.
6363
*/
64-
public addDependencies(dependencies: FrameGraphTextureHandle | FrameGraphTextureHandle[]) {
64+
public addDependencies(dependencies?: FrameGraphTextureHandle | FrameGraphTextureHandle[]) {
65+
if (!dependencies) {
66+
return;
67+
}
68+
6569
if (Array.isArray(dependencies)) {
6670
for (const dependency of dependencies) {
6771
this._dependencies.add(dependency);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// eslint-disable-next-line import/no-internal-modules
2+
import type { FrameGraph, FrameGraphTextureHandle, FrameGraphRenderPass } from "core/index";
3+
import { FrameGraphPostProcessTask } from "./postProcessTask";
4+
import { ThinMotionBlurPostProcess } from "core/PostProcesses/thinMotionBlurPostProcess";
5+
6+
/**
7+
* Task which applies a motion blur post process.
8+
*/
9+
export class FrameGraphMotionBlurTask extends FrameGraphPostProcessTask {
10+
/**
11+
* The velocity texture to use for the motion blur effect.
12+
* Needed for object-based motion blur.
13+
*/
14+
public velocityTexture?: FrameGraphTextureHandle;
15+
16+
/**
17+
* The (view) depth texture to use for the motion blur effect.
18+
* Needed for screen-based motion blur.
19+
*/
20+
public depthTexture?: FrameGraphTextureHandle;
21+
22+
public override readonly postProcess: ThinMotionBlurPostProcess;
23+
24+
/**
25+
* Constructs a new motion blur task.
26+
* @param name The name of the task.
27+
* @param frameGraph The frame graph this task belongs to.
28+
* @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.
29+
*/
30+
constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinMotionBlurPostProcess) {
31+
super(name, frameGraph, thinPostProcess || new ThinMotionBlurPostProcess(name, frameGraph.scene));
32+
}
33+
34+
public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {
35+
if (this.sourceTexture === undefined) {
36+
throw new Error(`FrameGraphMotionBlurTask "${this.name}": sourceTexture is required`);
37+
}
38+
39+
const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {
40+
if (this.velocityTexture) {
41+
context.bindTextureHandle(this._postProcessDrawWrapper.effect!, "velocitySampler", this.velocityTexture);
42+
} else if (this.postProcess.isObjectBased) {
43+
throw new Error(`FrameGraphMotionBlurTask "${this.name}": velocityTexture is required for object-based motion blur`);
44+
}
45+
46+
if (this.depthTexture) {
47+
context.bindTextureHandle(this._postProcessDrawWrapper.effect!, "depthSampler", this.depthTexture);
48+
} else if (!this.postProcess.isObjectBased) {
49+
throw new Error(`FrameGraphMotionBlurTask "${this.name}": depthTexture is required for screen-based motion blur`);
50+
}
51+
});
52+
53+
pass.addDependencies(this.velocityTexture);
54+
pass.addDependencies(this.depthTexture);
55+
56+
this.postProcess.textureWidth = this._sourceWidth;
57+
this.postProcess.textureHeight = this._sourceHeight;
58+
59+
return pass;
60+
}
61+
}

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export interface IFrameGraphGeometryRendererTextureDescription {
3838
textureFormat: number;
3939
}
4040

41-
const ClearColors: Color4[] = [new Color4(0, 0, 0, 0), new Color4(1, 1, 1, 1), new Color4(1e8, 1e8, 1e8, 1e8)];
41+
const ClearColors: Color4[] = [new Color4(0, 0, 0, 0), new Color4(1, 1, 1, 1), new Color4(0, 0, 0, 0)];
4242

4343
/**
4444
* Task used to render geometry to a set of textures.
@@ -262,6 +262,33 @@ export class FrameGraphGeometryRendererTask extends FrameGraphTask {
262262
return MaterialHelperGeometryRendering.GetConfiguration(this._renderer.renderPassId).excludedSkinnedMesh;
263263
}
264264

265+
/**
266+
* Excludes the given skinned mesh from computing bones velocities.
267+
* Computing bones velocities can have a cost. The cost can be saved by calling this function and by passing the skinned mesh to ignore.
268+
* @param skinnedMesh The mesh containing the skeleton to ignore when computing the velocity map.
269+
*/
270+
public excludeSkinnedMeshFromVelocityTexture(skinnedMesh: AbstractMesh): void {
271+
if (skinnedMesh.skeleton) {
272+
const list = this.excludedSkinnedMeshFromVelocityTexture;
273+
if (list.indexOf(skinnedMesh) === -1) {
274+
list.push(skinnedMesh);
275+
}
276+
}
277+
}
278+
279+
/**
280+
* Removes the given skinned mesh from the excluded meshes to integrate bones velocities while rendering the velocity map.
281+
* @param skinnedMesh The mesh containing the skeleton that has been ignored previously.
282+
* @see excludeSkinnedMesh to exclude a skinned mesh from bones velocity computation.
283+
*/
284+
public removeExcludedSkinnedMeshFromVelocityTexture(skinnedMesh: AbstractMesh): void {
285+
const list = this.excludedSkinnedMeshFromVelocityTexture;
286+
const index = list.indexOf(skinnedMesh);
287+
if (index !== -1) {
288+
list.splice(index, 1);
289+
}
290+
}
291+
265292
public override isReady() {
266293
return this._renderer.isReadyForRendering(this._textureWidth, this._textureHeight);
267294
}
@@ -295,6 +322,8 @@ export class FrameGraphGeometryRendererTask extends FrameGraphTask {
295322

296323
pass.setRenderTarget(outputTextureHandle);
297324

325+
let needPreviousWorldMatrices = false;
326+
298327
for (let i = 0; i < this.textureDescriptions.length; i++) {
299328
const description = this.textureDescriptions[i];
300329
const handle = outputTextureHandle[i];
@@ -328,13 +357,17 @@ export class FrameGraphGeometryRendererTask extends FrameGraphTask {
328357
break;
329358
case Constants.PREPASS_VELOCITY_TEXTURE_TYPE:
330359
this._frameGraph.textureManager.resolveDanglingHandle(this.geometryVelocityTexture, handle);
360+
needPreviousWorldMatrices = true;
331361
break;
332362
case Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE:
333363
this._frameGraph.textureManager.resolveDanglingHandle(this.geometryLinearVelocityTexture, handle);
364+
needPreviousWorldMatrices = true;
334365
break;
335366
}
336367
}
337368

369+
this._scene.needsPreviousWorldMatrices = needPreviousWorldMatrices;
370+
338371
pass.setRenderTargetDepth(this.depthTexture);
339372

340373
pass.setExecuteFunc((context) => {

packages/dev/core/src/FrameGraph/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export * from "./Passes/renderPass";
1313
export * from "./Tasks/Layers/glowLayerTask";
1414
export * from "./Tasks/Layers/highlightLayerTask";
1515

16+
export * from "./Tasks/Misc/cullObjectsTask";
1617
export * from "./Tasks/Misc/executeTask";
1718

1819
export * from "./Tasks/PostProcesses/anaglyphTask";
@@ -26,6 +27,7 @@ export * from "./Tasks/PostProcesses/extractHighlightsTask";
2627
export * from "./Tasks/PostProcesses/fxaaTask";
2728
export * from "./Tasks/PostProcesses/grainTask";
2829
export * from "./Tasks/PostProcesses/imageProcessingTask";
30+
export * from "./Tasks/PostProcesses/motionBlurTask";
2931
export * from "./Tasks/PostProcesses/passTask";
3032
export * from "./Tasks/PostProcesses/postProcessTask";
3133
export * from "./Tasks/PostProcesses/ssrRenderingPipelineTask";
@@ -36,7 +38,6 @@ export * from "./Tasks/Texture/copyToTextureTask";
3638
export * from "./Tasks/Texture/generateMipMapsTask";
3739

3840
export * from "./Tasks/Rendering/csmShadowGeneratorTask";
39-
export * from "./Tasks/Misc/cullObjectsTask";
4041
export * from "./Tasks/Rendering/geometryRendererTask";
4142
export * from "./Tasks/Rendering/objectRendererTask";
4243
export * from "./Tasks/Rendering/shadowGeneratorTask";

packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,6 @@ export class SSRRenderingPipeline extends PostProcessRenderPipeline {
747747
!this._useScreenspaceDepth,
748748
"SSRBackDepth"
749749
);
750-
if (!this._useScreenspaceDepth) {
751-
this._depthRenderer.clearColor.r = 1e8; // "infinity": put a big value because we use the storeCameraSpaceZ mode
752-
}
753750
this._depthRenderer.reverseCulling = true; // we generate depth for the back faces
754751
this._depthRenderer.forceDepthWriteTransparentMeshes = this.backfaceForceDepthWriteTransparentMeshes;
755752

packages/dev/core/src/PostProcesses/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export * from "./thinExtractHighlightsPostProcess";
4444
export * from "./thinFXAAPostProcess";
4545
export * from "./thinGrainPostProcess";
4646
export * from "./thinImageProcessingPostProcess";
47+
export * from "./thinMotionBlurPostProcess";
4748
export * from "./thinPassPostProcess";
4849

4950
// Postprocess

0 commit comments

Comments
 (0)