Skip to content

Commit

Permalink
Frame Graph: Add TAA task + support for history textures (#15785)
Browse files Browse the repository at this point in the history
* Add TAA task to frame graph

* Fix imports for UMD

* Fix UMD build
  • Loading branch information
Popov72 authored Nov 8, 2024
1 parent 5fbce3b commit e0ef399
Show file tree
Hide file tree
Showing 19 changed files with 785 additions and 228 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// eslint-disable-next-line import/no-internal-modules
import type { NodeRenderGraphConnectionPoint, Scene, NodeRenderGraphBuildState, FrameGraph, FrameGraphTextureHandle, FrameGraphObjectList, Camera } from "core/index";
import { NodeRenderGraphBlock } from "../../nodeRenderGraphBlock";
import { NodeRenderGraphBlockConnectionPointTypes } from "../../Types/nodeRenderGraphTypes";
import { editableInPropertyPage, PropertyTypeForEdition } from "../../../../Decorators/nodeDecorator";
import type { FrameGraphObjectRendererTask } from "../../../Tasks/Rendering/objectRendererTask";

/**
* @internal
*/
export class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock {
protected override _frameGraphTask: FrameGraphObjectRendererTask;

/**
* Gets the frame graph task associated with this block
*/
public override get task() {
return this._frameGraphTask;
}

/**
* Create a new NodeRenderGraphBaseObjectRendererBlock
* @param name defines the block name
* @param frameGraph defines the hosting frame graph
* @param scene defines the hosting scene
*/
public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {
super(name, frameGraph, scene);

this.registerInput("destination", NodeRenderGraphBlockConnectionPointTypes.Texture);
this.registerInput("depth", NodeRenderGraphBlockConnectionPointTypes.TextureBackBufferDepthStencilAttachment, true);
this.registerInput("camera", NodeRenderGraphBlockConnectionPointTypes.Camera);
this.registerInput("objects", NodeRenderGraphBlockConnectionPointTypes.ObjectList);
this.registerInput("dependencies", NodeRenderGraphBlockConnectionPointTypes.Texture, true);

this.registerOutput("output", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);
this.registerOutput("outputDepth", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);

this.destination.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil);
this.depth.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment);
this.dependencies.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);

this.output._typeConnectionSource = this.destination;
this.outputDepth._typeConnectionSource = this.depth;
}

/** Indicates if depth testing must be enabled or disabled */
@editableInPropertyPage("Depth test", PropertyTypeForEdition.Boolean, "PROPERTIES")
public get depthTest() {
return this._frameGraphTask.depthTest;
}

public set depthTest(value: boolean) {
this._frameGraphTask.depthTest = value;
}

/** Indicates if depth writing must be enabled or disabled */
@editableInPropertyPage("Depth write", PropertyTypeForEdition.Boolean, "PROPERTIES")
public get depthWrite() {
return this._frameGraphTask.depthWrite;
}

public set depthWrite(value: boolean) {
this._frameGraphTask.depthWrite = value;
}

/**
* Gets the current class name
* @returns the class name
*/
public override getClassName() {
return "NodeRenderGraphBaseObjectRendererBlock";
}

/**
* Gets the destination texture input component
*/
public get destination(): NodeRenderGraphConnectionPoint {
return this._inputs[0];
}

/**
* Gets the depth texture input component
*/
public get depth(): NodeRenderGraphConnectionPoint {
return this._inputs[1];
}

/**
* Gets the camera input component
*/
public get camera(): NodeRenderGraphConnectionPoint {
return this._inputs[2];
}

/**
* Gets the objects input component
*/
public get objects(): NodeRenderGraphConnectionPoint {
return this._inputs[3];
}

/**
* Gets the dependencies input component
*/
public get dependencies(): NodeRenderGraphConnectionPoint {
return this._inputs[4];
}

/**
* Gets the output component
*/
public get output(): NodeRenderGraphConnectionPoint {
return this._outputs[0];
}

/**
* Gets the output depth component
*/
public get outputDepth(): NodeRenderGraphConnectionPoint {
return this._outputs[1];
}

protected override _buildBlock(state: NodeRenderGraphBuildState) {
super._buildBlock(state);

this._frameGraphTask.name = this.name;

this.output.value = this._frameGraphTask.outputTexture; // the value of the output connection point is the "output" texture of the task

this.outputDepth.value = this._frameGraphTask.outputDepthTexture; // the value of the outputDepth connection point is the "outputDepth" texture of the task

const destinationConnectedPoint = this.destination.connectedPoint;
if (destinationConnectedPoint) {
this._frameGraphTask.destinationTexture = destinationConnectedPoint.value as FrameGraphTextureHandle;
}

const depthConnectedPoint = this.depth.connectedPoint;
if (depthConnectedPoint) {
this._frameGraphTask.depthTexture = depthConnectedPoint.value as FrameGraphTextureHandle;
}

const cameraConnectedPoint = this.camera.connectedPoint;
if (cameraConnectedPoint) {
this._frameGraphTask.camera = cameraConnectedPoint.value as Camera;
}

const objectsConnectedPoint = this.objects.connectedPoint;
if (objectsConnectedPoint) {
this._frameGraphTask.objectList = objectsConnectedPoint.value as FrameGraphObjectList;
}

this._frameGraphTask.dependencies = [];

const dependenciesConnectedPoint = this.dependencies.connectedPoint;
if (dependenciesConnectedPoint) {
this._frameGraphTask.dependencies[0] = dependenciesConnectedPoint.value as FrameGraphTextureHandle;
}
}

protected override _dumpPropertiesCode() {
const codes: string[] = [];
codes.push(`${this._codeVariableName}.depthTest = ${this.depthTest};`);
codes.push(`${this._codeVariableName}.depthWrite = ${this.depthWrite};`);
return super._dumpPropertiesCode() + codes.join("\n");
}

public override serialize(): any {
const serializationObject = super.serialize();
serializationObject.depthTest = this.depthTest;
serializationObject.depthWrite = this.depthWrite;
return serializationObject;
}

public override _deserialize(serializationObject: any) {
super._deserialize(serializationObject);
this.depthTest = serializationObject.depthTest;
this.depthWrite = serializationObject.depthWrite;
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
// eslint-disable-next-line import/no-internal-modules
import type { NodeRenderGraphConnectionPoint, Scene, NodeRenderGraphBuildState, FrameGraph, FrameGraphTextureHandle, FrameGraphObjectList, Camera } from "core/index";
import { NodeRenderGraphBlock } from "../../nodeRenderGraphBlock";
import type { Scene, FrameGraph } from "core/index";
import { RegisterClass } from "../../../../Misc/typeStore";
import { NodeRenderGraphBlockConnectionPointTypes } from "../../Types/nodeRenderGraphTypes";
import { editableInPropertyPage, PropertyTypeForEdition } from "../../../../Decorators/nodeDecorator";
import { FrameGraphObjectRendererTask } from "../../../Tasks/Rendering/objectRendererTask";
import { NodeRenderGraphBaseObjectRendererBlock } from "./baseObjectRendererBlock";

/**
* Block that render objects to a render target
*/
export class NodeRenderGraphObjectRendererBlock extends NodeRenderGraphBlock {
protected override _frameGraphTask: FrameGraphObjectRendererTask;

/**
* Gets the frame graph task associated with this block
*/
public override get task() {
return this._frameGraphTask;
}

export class NodeRenderGraphObjectRendererBlock extends NodeRenderGraphBaseObjectRendererBlock {
/**
* Create a new NodeRenderGraphObjectRendererBlock
* @param name defines the block name
Expand All @@ -28,158 +17,16 @@ export class NodeRenderGraphObjectRendererBlock extends NodeRenderGraphBlock {
public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {
super(name, frameGraph, scene);

this.registerInput("destination", NodeRenderGraphBlockConnectionPointTypes.Texture);
this.registerInput("depth", NodeRenderGraphBlockConnectionPointTypes.TextureBackBufferDepthStencilAttachment, true);
this.registerInput("camera", NodeRenderGraphBlockConnectionPointTypes.Camera);
this.registerInput("objects", NodeRenderGraphBlockConnectionPointTypes.ObjectList);
this.registerInput("dependencies", NodeRenderGraphBlockConnectionPointTypes.Texture, true);

this.registerOutput("output", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);
this.registerOutput("outputDepth", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);

this.destination.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil);
this.depth.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment);
this.dependencies.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);

this.output._typeConnectionSource = this.destination;
this.outputDepth._typeConnectionSource = this.depth;

this._frameGraphTask = new FrameGraphObjectRendererTask(this.name, frameGraph, scene);
}

/** Indicates if depth testing must be enabled or disabled */
@editableInPropertyPage("Depth test", PropertyTypeForEdition.Boolean, "PROPERTIES")
public get depthTest() {
return this._frameGraphTask.depthTest;
}

public set depthTest(value: boolean) {
this._frameGraphTask.depthTest = value;
}

/** Indicates if depth writing must be enabled or disabled */
@editableInPropertyPage("Depth write", PropertyTypeForEdition.Boolean, "PROPERTIES")
public get depthWrite() {
return this._frameGraphTask.depthWrite;
}

public set depthWrite(value: boolean) {
this._frameGraphTask.depthWrite = value;
}

/**
* Gets the current class name
* @returns the class name
*/
public override getClassName() {
return "NodeRenderGraphObjectRendererBlock";
}

/**
* Gets the destination texture input component
*/
public get destination(): NodeRenderGraphConnectionPoint {
return this._inputs[0];
}

/**
* Gets the depth texture input component
*/
public get depth(): NodeRenderGraphConnectionPoint {
return this._inputs[1];
}

/**
* Gets the camera input component
*/
public get camera(): NodeRenderGraphConnectionPoint {
return this._inputs[2];
}

/**
* Gets the objects input component
*/
public get objects(): NodeRenderGraphConnectionPoint {
return this._inputs[3];
}

/**
* Gets the dependencies input component
*/
public get dependencies(): NodeRenderGraphConnectionPoint {
return this._inputs[4];
}

/**
* Gets the output component
*/
public get output(): NodeRenderGraphConnectionPoint {
return this._outputs[0];
}

/**
* Gets the output depth component
*/
public get outputDepth(): NodeRenderGraphConnectionPoint {
return this._outputs[1];
}

protected override _buildBlock(state: NodeRenderGraphBuildState) {
super._buildBlock(state);

this._frameGraphTask.name = this.name;

this.output.value = this._frameGraphTask.outputTexture; // the value of the output connection point is the "output" texture of the task

this.outputDepth.value = this._frameGraphTask.outputDepthTexture; // the value of the outputDepth connection point is the "outputDepth" texture of the task

const destinationConnectedPoint = this.destination.connectedPoint;
if (destinationConnectedPoint) {
this._frameGraphTask.destinationTexture = destinationConnectedPoint.value as FrameGraphTextureHandle;
}

const depthConnectedPoint = this.depth.connectedPoint;
if (depthConnectedPoint) {
this._frameGraphTask.depthTexture = depthConnectedPoint.value as FrameGraphTextureHandle;
}

const cameraConnectedPoint = this.camera.connectedPoint;
if (cameraConnectedPoint) {
this._frameGraphTask.camera = cameraConnectedPoint.value as Camera;
}

const objectsConnectedPoint = this.objects.connectedPoint;
if (objectsConnectedPoint) {
this._frameGraphTask.objectList = objectsConnectedPoint.value as FrameGraphObjectList;
}

this._frameGraphTask.dependencies = [];

const dependenciesConnectedPoint = this.dependencies.connectedPoint;
if (dependenciesConnectedPoint) {
this._frameGraphTask.dependencies[0] = dependenciesConnectedPoint.value as FrameGraphTextureHandle;
}
}

protected override _dumpPropertiesCode() {
const codes: string[] = [];
codes.push(`${this._codeVariableName}.depthTest = ${this.depthTest};`);
codes.push(`${this._codeVariableName}.depthWrite = ${this.depthWrite};`);
return super._dumpPropertiesCode() + codes.join("\n");
}

public override serialize(): any {
const serializationObject = super.serialize();
serializationObject.depthTest = this.depthTest;
serializationObject.depthWrite = this.depthWrite;
return serializationObject;
}

public override _deserialize(serializationObject: any) {
super._deserialize(serializationObject);
this.depthTest = serializationObject.depthTest;
this.depthWrite = serializationObject.depthWrite;
}
}

RegisterClass("BABYLON.NodeRenderGraphObjectRendererBlock", NodeRenderGraphObjectRendererBlock);
Loading

0 comments on commit e0ef399

Please sign in to comment.