Skip to content

Commit

Permalink
Add debug Node to GS, procedural, particles and PP (#16138)
Browse files Browse the repository at this point in the history
Co-authored-by: David Catuhe <david@catuhe.com>
  • Loading branch information
deltakosh and David Catuhe authored Feb 3, 2025
1 parent 8536ece commit b284c8e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { NodeMaterialBuildState } from "../../nodeMaterialBuildState";
import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets";
import type { NodeMaterialConnectionPoint } from "../../nodeMaterialBlockConnectionPoint";
import { RegisterClass } from "../../../../Misc/typeStore";
import { ShaderLanguage } from "core/Materials/shaderLanguage";

/**
* Block used for the particle ramp gradient section
Expand Down Expand Up @@ -68,17 +69,19 @@ export class ParticleRampGradientBlock extends NodeMaterialBlock {
state._emit2DSampler("rampSampler", "RAMPGRADIENT");
state._emitVaryingFromString("remapRanges", NodeMaterialBlockConnectionPointTypes.Vector4, "RAMPGRADIENT");

const varyingString = state.shaderLanguage === ShaderLanguage.GLSL ? "" : "fragmentInputs.";

state.compilationString += `
#ifdef RAMPGRADIENT
${state._declareLocalVar("baseColor", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.color.associatedVariableName};
${state._declareLocalVar("alpha", NodeMaterialBlockConnectionPointTypes.Float)} = ${this.color.associatedVariableName}.a;
${state._declareLocalVar("remappedColorIndex", NodeMaterialBlockConnectionPointTypes.Float)} = clamp((alpha - remapRanges.x) / remapRanges.y, 0.0, 1.0);
${state._declareLocalVar("remappedColorIndex", NodeMaterialBlockConnectionPointTypes.Float)} = clamp((alpha - ${varyingString}remapRanges.x) / ${varyingString}remapRanges.y, 0.0, 1.0);
${state._declareLocalVar("rampColor", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${state._generateTextureSample("vec2(1.0 - remappedColorIndex, 0.)", "rampSampler")};
// Remapped alpha
${state._declareOutput(this.rampColor)} = vec4${state.fSuffix}(baseColor.rgb * rampColor.rgb, clamp((alpha * rampColor.a - remapRanges.z) / remapRanges.w, 0.0, 1.0));
${state._declareOutput(this.rampColor)} = vec4${state.fSuffix}(baseColor.rgb * rampColor.rgb, clamp((alpha * rampColor.a - ${varyingString}remapRanges.z) / ${varyingString}remapRanges.w, 0.0, 1.0));
#else
${state._declareOutput(this.rampColor)} = ${this.color.associatedVariableName};
#endif
Expand Down
9 changes: 9 additions & 0 deletions packages/dev/core/src/Materials/Node/Blocks/debugBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { NodeMaterialConnectionPoint } from "../nodeMaterialBlockConnection
import { NodeMaterialBlockTargets } from "../Enums/nodeMaterialBlockTargets";
import { ShaderLanguage } from "core/Materials/shaderLanguage";
import type { Scene } from "core/scene";
import { editableInPropertyPage, PropertyTypeForEdition } from "core/Decorators/nodeDecorator";

/**
* Block used to render intermediate debug values
Expand All @@ -15,6 +16,10 @@ import type { Scene } from "core/scene";
export class NodeMaterialDebugBlock extends NodeMaterialBlock {
private _isActive = false;

/** Gets or sets a boolean indicating if we want to render alpha when using a rgba input*/
@editableInPropertyPage("Render Alpha", PropertyTypeForEdition.Boolean, undefined)
public renderAlpha = false;

/**
* Gets or sets a boolean indicating that the block is active
*/
Expand Down Expand Up @@ -90,6 +95,8 @@ export class NodeMaterialDebugBlock extends NodeMaterialBlock {
state.compilationString += `${outputString} = vec4${state.fSuffix}(${debug.associatedVariableName}, 0., 1.0);\n`;
} else if (debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Color3 || debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector3) {
state.compilationString += `${outputString} = vec4${state.fSuffix}(${debug.associatedVariableName}, 1.0);\n`;
} else if (this.renderAlpha) {
state.compilationString += `${outputString} =${debug.associatedVariableName};\n`;
} else {
state.compilationString += `${outputString} = vec4${state.fSuffix}(${debug.associatedVariableName}.rgb, 1.0);\n`;
}
Expand All @@ -100,13 +107,15 @@ export class NodeMaterialDebugBlock extends NodeMaterialBlock {
public override serialize(): any {
const serializationObject = super.serialize();
serializationObject.isActive = this._isActive;
serializationObject.renderAlpha = this.renderAlpha;
return serializationObject;
}

public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
super._deserialize(serializationObject, scene, rootUrl);

this.isActive = serializationObject.isActive;
this.renderAlpha = serializationObject.renderAlpha;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
delete allBlocks["PBR"];
delete allBlocks["GaussianSplatting"];
allBlocks.Output_Nodes.splice(allBlocks.Output_Nodes.indexOf("PrePassOutputBlock"), 1);
allBlocks.Misc.splice(allBlocks.Misc.indexOf("DebugBlock"), 1);
break;
case NodeMaterialModes.ProceduralTexture:
delete allBlocks["Animation"];
Expand All @@ -504,7 +503,6 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
delete allBlocks["PBR"];
delete allBlocks["GaussianSplatting"];
allBlocks.Output_Nodes.splice(allBlocks.Output_Nodes.indexOf("PrePassOutputBlock"), 1);
allBlocks.Misc.splice(allBlocks.Misc.indexOf("DebugBlock"), 1);
break;
case NodeMaterialModes.Particle:
delete allBlocks["Animation"];
Expand All @@ -517,7 +515,6 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
allBlocks.Scene.splice(allBlocks.Scene.indexOf("FogBlock"), 1);
allBlocks.Scene.splice(allBlocks.Scene.indexOf("FogColorBlock"), 1);
allBlocks.Output_Nodes.splice(allBlocks.Output_Nodes.indexOf("PrePassOutputBlock"), 1);
allBlocks.Misc.splice(allBlocks.Misc.indexOf("DebugBlock"), 1);
break;
case NodeMaterialModes.GaussianSplatting:
delete allBlocks["Animation"];
Expand All @@ -529,7 +526,6 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
allBlocks.Scene.splice(allBlocks.Scene.indexOf("FogBlock"), 1);
allBlocks.Scene.splice(allBlocks.Scene.indexOf("FogColorBlock"), 1);
allBlocks.Output_Nodes.splice(allBlocks.Output_Nodes.indexOf("PrePassOutputBlock"), 1);
allBlocks.Misc.splice(allBlocks.Misc.indexOf("DebugBlock"), 1);
break;
}

Expand Down
25 changes: 23 additions & 2 deletions packages/tools/nodeEditor/src/components/preview/previewManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export class PreviewManager {

public async _initAsync(targetCanvas: HTMLCanvasElement) {
if (this._nodeMaterial.shaderLanguage === ShaderLanguage.WGSL) {
this._engine = new WebGPUEngine(targetCanvas);
this._engine = new WebGPUEngine(targetCanvas, { enableAllFeatures: true });
await (this._engine as WebGPUEngine).initAsync();
} else {
this._engine = new Engine(targetCanvas);
Expand Down Expand Up @@ -218,20 +218,28 @@ export class PreviewManager {
};
canvas.addEventListener("drop", onDrop, false);
}
this._refreshPreviewMesh();

// Adding a rtt to read from
this._globalState.previewTexture = new RenderTargetTexture("rtt", 256, this._scene, false);
this._globalState.pickingTexture = new RenderTargetTexture("rtt2", 256, this._scene, false, true, Constants.TEXTURETYPE_FLOAT);
this._globalState.previewTexture.renderList = null;
this._globalState.pickingTexture.renderList = null;
this._globalState.previewTexture.particleSystemList = null;
this._globalState.pickingTexture.particleSystemList = null;
this._globalState.pickingTexture.useCameraPostProcesses = true;
this._globalState.previewTexture.useCameraPostProcesses = true;
this._scene.customRenderTargets.push(this._globalState.previewTexture);
this._scene.customRenderTargets.push(this._globalState.pickingTexture);

// Observable
this._scene.onAfterRenderObservable.add(() => {
this._globalState.onPreviewSceneAfterRenderObservable.notifyObservers();
});

// Preview
this._refreshPreviewMesh();

// Render loop
this._engine.runRenderLoop(() => {
this._engine.resize();
this._scene.render();
Expand Down Expand Up @@ -515,12 +523,16 @@ export class PreviewManager {
}
} else if (this._globalState.mode === NodeMaterialModes.ProceduralTexture) {
this._layer = new Layer("proceduralLayer", null, this._scene, false);
this._layer.renderTargetTextures.push(this._globalState.previewTexture!);
this._layer.renderTargetTextures.push(this._globalState.pickingTexture!);
this._prepareScene();
} else if (this._globalState.mode === NodeMaterialModes.Particle) {
switch (this._globalState.previewType) {
case PreviewType.DefaultParticleSystem:
this._particleSystem = ParticleHelper.CreateDefault(new Vector3(0, 0, 0), 500, this._scene);
this._particleSystem.blendMode = DataStorage.ReadNumber("DefaultParticleSystemBlendMode", ParticleSystem.BLENDMODE_ONEONE);
this._particleSystem.start();
this._prepareScene();
break;
case PreviewType.Bubbles:
this._particleSystem = new ParticleSystem("particles", 4000, this._scene);
Expand All @@ -538,6 +550,7 @@ export class PreviewManager {
this._particleSystem.color2 = new Color4(1, 0.5, 0, 1);
this._particleSystem.gravity = new Vector3(0, -1.0, 0);
this._particleSystem.start();
this._prepareScene();
break;
case PreviewType.Explosion:
this._loadParticleSystem(this._globalState.previewType, 1);
Expand Down Expand Up @@ -588,6 +601,8 @@ export class PreviewManager {
this._globalState.filesInput.loadFiles({ target: { files: this._globalState.listOfCustomPreviewFiles } });
return;
}
} else {
this._prepareScene();
}
}
}
Expand Down Expand Up @@ -674,6 +689,8 @@ export class PreviewManager {
this._material.dispose();
}
this._material = tempMaterial;

this._globalState.onPreviewUpdatedObservable.notifyObservers(tempMaterial);
break;
}
case NodeMaterialModes.ProceduralTexture: {
Expand All @@ -688,6 +705,8 @@ export class PreviewManager {
if (this._layer) {
this._layer.texture = this._proceduralTexture;
}

this._globalState.onPreviewUpdatedObservable.notifyObservers(tempMaterial);
break;
}

Expand All @@ -710,6 +729,8 @@ export class PreviewManager {
this._material.dispose();
}
this._material = tempMaterial;

this._globalState.onPreviewUpdatedObservable.notifyObservers(tempMaterial);
break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import { LineContainerComponent } from "shared-ui-components/lines/lineContainerComponent";
import { GeneralPropertyTabComponent } from "./genericNodePropertyComponent";
import { GeneralPropertyTabComponent, GenericPropertyTabComponent } from "./genericNodePropertyComponent";
import type { GlobalState } from "../../globalState";
import type { IPropertyComponentProps } from "shared-ui-components/nodeGraphSystem/interfaces/propertyComponentProps";
import { ButtonLineComponent } from "shared-ui-components/lines/buttonLineComponent";
Expand All @@ -20,6 +20,7 @@ export class DebugNodePropertyTabComponent extends React.Component<IPropertyComp
return (
<div>
<GeneralPropertyTabComponent stateManager={this.props.stateManager} nodeData={this.props.nodeData} />
<GenericPropertyTabComponent stateManager={this.props.stateManager} nodeData={this.props.nodeData} />
<LineContainerComponent title="PROPERTIES">
<ButtonLineComponent label="Refresh all" onClick={() => this.refreshAll()} />
</LineContainerComponent>
Expand Down

0 comments on commit b284c8e

Please sign in to comment.