浏览代码

Add decorator to block properties for generic editing

Popov72 5 年之前
父节点
当前提交
9dabb749c9
共有 23 个文件被更改,包括 202 次插入150 次删除
  1. 2 2
      nodeEditor/src/diagram/graphNode.ts
  2. 0 24
      nodeEditor/src/diagram/properties/PerturbNormalNodePropertyComponent.tsx
  3. 0 33
      nodeEditor/src/diagram/properties/clampNodePropertyComponent.tsx
  4. 106 5
      nodeEditor/src/diagram/properties/genericNodePropertyComponent.tsx
  5. 2 2
      nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx
  6. 2 2
      nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx
  7. 2 2
      nodeEditor/src/diagram/properties/lightInformationPropertyTabComponent.tsx
  8. 2 2
      nodeEditor/src/diagram/properties/lightPropertyTabComponent.tsx
  9. 0 33
      nodeEditor/src/diagram/properties/remapNodePropertyComponent.tsx
  10. 2 2
      nodeEditor/src/diagram/properties/texturePropertyTabComponent.tsx
  11. 2 2
      nodeEditor/src/diagram/properties/transformNodePropertyComponent.tsx
  12. 2 2
      nodeEditor/src/diagram/properties/trigonometryNodePropertyComponent.tsx
  13. 0 23
      nodeEditor/src/diagram/properties/worleyNoise3DNodePropertyComponent.tsx
  14. 0 8
      nodeEditor/src/diagram/propertyLedger.ts
  15. 4 0
      src/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.ts
  16. 17 1
      src/Materials/Node/Blocks/Fragment/pbrMetallicRoughnessBlock.ts
  17. 3 0
      src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts
  18. 6 6
      src/Materials/Node/Blocks/Fragment/sheenBlock.ts
  19. 4 0
      src/Materials/Node/Blocks/clampBlock.ts
  20. 3 0
      src/Materials/Node/Blocks/remapBlock.ts
  21. 2 0
      src/Materials/Node/Blocks/worleyNoise3DBlock.ts
  22. 2 1
      src/Materials/Node/index.ts
  23. 39 0
      src/Materials/Node/nodeMaterialDecorator.ts

+ 2 - 2
nodeEditor/src/diagram/graphNode.ts

@@ -6,7 +6,7 @@ import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMateri
 import { GraphCanvasComponent, FramePortData } from './graphCanvas';
 import { PropertyLedger } from './propertyLedger';
 import * as React from 'react';
-import { GenericPropertyTabComponent } from './properties/genericNodePropertyComponent';
+import { GenericPropertyComponent } from './properties/genericNodePropertyComponent';
 import { DisplayLedger } from './displayLedger';
 import { IDisplayManager } from './display/displayManager';
 import { NodeLink } from './nodeLink';
@@ -344,7 +344,7 @@ export class GraphNode {
         let control = PropertyLedger.RegisteredControls[this.block.getClassName()];
 
         if (!control) {
-            control = GenericPropertyTabComponent;
+            control = GenericPropertyComponent;
         }
 
         return React.createElement(control, {

+ 0 - 24
nodeEditor/src/diagram/properties/PerturbNormalNodePropertyComponent.tsx

@@ -1,24 +0,0 @@
-
-import * as React from "react";
-import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
-import { IPropertyComponentProps } from './propertyComponentProps';
-import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
-
-export class PerturbNormalPropertyTabComponent extends React.Component<IPropertyComponentProps> {
-    constructor(props: IPropertyComponentProps) {
-        super(props)
-    }
-
-    render() {
-        return (
-            <>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Invert X axis" target={this.props.block} propertyName="invertX" onValueChanged={() => this.props.globalState.onRebuildRequiredObservable.notifyObservers()} />
-                    <CheckBoxLineComponent label="Invert Y axis" target={this.props.block} propertyName="invertY" onValueChanged={() => this.props.globalState.onRebuildRequiredObservable.notifyObservers()}/>                    
-                </LineContainerComponent>        
-            </>
-        );
-    }
-}

+ 0 - 33
nodeEditor/src/diagram/properties/clampNodePropertyComponent.tsx

@@ -1,33 +0,0 @@
-
-import * as React from "react";
-import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
-import { FloatLineComponent } from '../../sharedComponents/floatLineComponent';
-import { IPropertyComponentProps } from './propertyComponentProps';
-import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
-
-export class ClampPropertyTabComponent extends React.Component<IPropertyComponentProps> {
-
-    constructor(props: IPropertyComponentProps) {
-        super(props)
-    }
-
-    forceRebuild() {
-        this.props.globalState.onUpdateRequiredObservable.notifyObservers();
-        this.props.globalState.onRebuildRequiredObservable.notifyObservers();
-    }
-
-    render() {
-        let clampBlock = this.props.block as ClampBlock
-      
-        return (
-            <div>
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
-                <LineContainerComponent title="PROPERTIES">
-                  <FloatLineComponent globalState={this.props.globalState} label="Minimum" propertyName="minimum" target={clampBlock} onChange={() => this.forceRebuild()} />
-                  <FloatLineComponent globalState={this.props.globalState} label="Maximum" propertyName="maximum" target={clampBlock} onChange={() => this.forceRebuild()} />
-                </LineContainerComponent>
-            </div>
-        );
-    }
-}

+ 106 - 5
nodeEditor/src/diagram/properties/genericNodePropertyComponent.tsx

@@ -4,11 +4,31 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { TextLineComponent } from '../../sharedComponents/textLineComponent';
+import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
+import { FloatLineComponent } from '../../sharedComponents/floatLineComponent';
+import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent';
+import { Vector2LineComponent } from '../../sharedComponents/vector2LineComponent';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
+import { PropertyTypeForEdition, IPropertyDescriptionForEdition } from 'babylonjs/Materials/Node/nodeMaterialDecorator';
 
-export class GenericPropertyTabComponent extends React.Component<IPropertyComponentProps> {
+export class GenericPropertyComponent extends React.Component<IPropertyComponentProps> {
+    constructor(props: IPropertyComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+            </>
+        );
+    }
+}
+
+export class GeneralPropertyTabComponent extends React.Component<IPropertyComponentProps> {
     constructor(props: IPropertyComponentProps) {
-        super(props)
+        super(props);
     }
 
     render() {
@@ -17,13 +37,94 @@ export class GenericPropertyTabComponent extends React.Component<IPropertyCompon
                 <LineContainerComponent title="GENERAL">
                     {
                         (!this.props.block.isInput || !(this.props.block as InputBlock).isAttribute) &&
-                        <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.block} 
+                        <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.block}
                             onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()} />
                     }
                     <TextLineComponent label="Type" value={this.props.block.getClassName()} />
-                    <TextInputLineComponent globalState={this.props.globalState} label="Comments" propertyName="comments" target={this.props.block} 
+                    <TextInputLineComponent globalState={this.props.globalState} label="Comments" propertyName="comments" target={this.props.block}
                             onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()} />
-                </LineContainerComponent>         
+                </LineContainerComponent>
+            </>
+        );
+    }
+}
+
+export class GenericPropertyTabComponent extends React.Component<IPropertyComponentProps> {
+    constructor(props: IPropertyComponentProps) {
+        super(props);
+    }
+
+    forceRebuild(notifiers?: { "rebuild"?: boolean; "update"?: boolean; }) {
+        if (!notifiers || notifiers.update) {
+            this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+        }
+
+        if (!notifiers || notifiers.rebuild) {
+            this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+        }
+    }
+
+    render() {
+        const block = this.props.block,
+              propStore: IPropertyDescriptionForEdition[] = (block as any)._propStore;
+
+        if (!propStore) {
+            return (
+                <>
+                </>
+            );
+        }
+
+        const componentList: { [groupName: string]: JSX.Element[]} = {},
+              groups: string[] = [];
+
+        for (const { propertyName, displayName, type, groupName, options } of propStore) {
+            let components = componentList[groupName];
+
+            if (!components) {
+                components = [];
+                componentList[groupName] = components;
+                groups.push(groupName);
+            }
+
+            switch (type) {
+                case PropertyTypeForEdition.Boolean: {
+                    components.push(
+                        <CheckBoxLineComponent label={displayName} target={this.props.block} propertyName={propertyName} onValueChanged={() => this.forceRebuild(options.notifiers)} />
+                    );
+                    break;
+                }
+                case PropertyTypeForEdition.Float: {
+                    let cantDisplaySlider = (isNaN(options.min) || isNaN(options.max) || options.min === options.max);
+                    if (cantDisplaySlider) {
+                        components.push(
+                            <FloatLineComponent globalState={this.props.globalState} label={displayName} propertyName={propertyName} target={this.props.block} onChange={() => this.forceRebuild(options.notifiers)} />
+                        );
+                    } else {
+                        components.push(
+                            <SliderLineComponent label={displayName} target={this.props.block} propertyName={propertyName} step={Math.abs(options.max - options.min) / 100.0} minimum={Math.min(options.min, options.max)} maximum={options.max} onChange={() => this.forceRebuild(options.notifiers)}/>
+                        );
+                    }
+                    break;
+                }
+                case PropertyTypeForEdition.Vector2: {
+                    components.push(
+                        <Vector2LineComponent globalState={this.props.globalState} label={displayName} propertyName={propertyName} target={this.props.block} onChange={() => this.forceRebuild(options.notifiers)} />
+                    );
+                    break;
+                }
+            }
+        }
+
+        return (
+            <>
+            {
+                groups.map((group) =>
+                    <LineContainerComponent title={group}>
+                        {componentList[group]}
+                    </LineContainerComponent>
+                )
+            }
             </>
         );
     }

+ 2 - 2
nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx

@@ -6,7 +6,7 @@ import { GradientStepComponent } from './gradientStepComponent';
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
 import { Color3 } from 'babylonjs/Maths/math.color';
 import { IPropertyComponentProps } from './propertyComponentProps';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class GradientPropertyTabComponent extends React.Component<IPropertyComponentProps> {
 
@@ -64,7 +64,7 @@ export class GradientPropertyTabComponent extends React.Component<IPropertyCompo
       
         return (
             <div>
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="STEPS">
                     <ButtonLineComponent label="Add new step" onClick={() => this.addNewStep()} />
                     {

+ 2 - 2
nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx

@@ -16,7 +16,7 @@ import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/Enums/nodeMat
 import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
 import { Color4PropertyTabComponent } from '../../components/propertyTab/properties/color4PropertyTabComponent';
@@ -206,7 +206,7 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
 
         return (
             <div>
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">
                     {
                         inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&

+ 2 - 2
nodeEditor/src/diagram/properties/lightInformationPropertyTabComponent.tsx

@@ -4,7 +4,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class LightInformationPropertyTabComponent extends React.Component<IPropertyComponentProps> {
 
@@ -18,7 +18,7 @@ export class LightInformationPropertyTabComponent extends React.Component<IPrope
 
         return (
             <div>               
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">
                     <OptionsLineComponent label="Light" noDirectUpdate={true} valuesAreStrings={true} options={lightOptions} target={lightInformationBlock} propertyName="name" onSelect={(name: any) => {
                         lightInformationBlock.light = scene.getLightByName(name);

+ 2 - 2
nodeEditor/src/diagram/properties/lightPropertyTabComponent.tsx

@@ -4,7 +4,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class LightPropertyTabComponent extends React.Component<IPropertyComponentProps> {
 
@@ -20,7 +20,7 @@ export class LightPropertyTabComponent extends React.Component<IPropertyComponen
 
         return (
             <div>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">
                     <OptionsLineComponent label="Light" defaultIfNull={0} noDirectUpdate={true} valuesAreStrings={true} options={lightOptions} target={lightBlock} propertyName="name" onSelect={(name: any) => {
                         if (name === "") {

+ 0 - 33
nodeEditor/src/diagram/properties/remapNodePropertyComponent.tsx

@@ -1,33 +0,0 @@
-
-import * as React from "react";
-import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
-import { Vector2LineComponent } from '../../sharedComponents/vector2LineComponent';
-import { IPropertyComponentProps } from './propertyComponentProps';
-import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
-
-export class RemapPropertyTabComponent extends React.Component<IPropertyComponentProps> {
-
-    constructor(props: IPropertyComponentProps) {
-        super(props)
-    }
-
-    forceRebuild() {
-        this.props.globalState.onUpdateRequiredObservable.notifyObservers();
-        this.props.globalState.onRebuildRequiredObservable.notifyObservers();
-    }
-
-    render() {
-        let remapBlock = this.props.block as RemapBlock;
-      
-        return (
-            <div>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
-                <LineContainerComponent title="PROPERTIES">
-                  <Vector2LineComponent globalState={this.props.globalState} label="From" propertyName="sourceRange" target={remapBlock} onChange={() => this.forceRebuild()} />
-                  <Vector2LineComponent globalState={this.props.globalState} label="To" propertyName="targetRange" target={remapBlock} onChange={() => this.forceRebuild()} />
-                </LineContainerComponent>
-            </div>
-        );
-    }
-}

+ 2 - 2
nodeEditor/src/diagram/properties/texturePropertyTabComponent.tsx

@@ -15,7 +15,7 @@ import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponen
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
 import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class TexturePropertyTabComponent extends React.Component<IPropertyComponentProps, {isEmbedded: boolean, loadAsCubeTexture: boolean}> {
 
@@ -177,7 +177,7 @@ export class TexturePropertyTabComponent extends React.Component<IPropertyCompon
         
         return (
             <div>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">
                     <CheckBoxLineComponent label="Auto select UV" propertyName="autoSelectUV" target={this.props.block} onValueChanged={() => {                        
                         this.props.globalState.onUpdateRequiredObservable.notifyObservers();

+ 2 - 2
nodeEditor/src/diagram/properties/transformNodePropertyComponent.tsx

@@ -4,7 +4,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
 import { TransformBlock } from 'babylonjs/Materials/Node/Blocks/transformBlock';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class TransformPropertyTabComponent extends React.Component<IPropertyComponentProps> {
     constructor(props: IPropertyComponentProps) {
@@ -14,7 +14,7 @@ export class TransformPropertyTabComponent extends React.Component<IPropertyComp
     render() {
         return (
             <>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">
                     <CheckBoxLineComponent label="Transform as direction" onSelect={value => {
                         let transformBlock = this.props.block as TransformBlock;

+ 2 - 2
nodeEditor/src/diagram/properties/trigonometryNodePropertyComponent.tsx

@@ -4,7 +4,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import { TrigonometryBlockOperations, TrigonometryBlock } from 'babylonjs/Materials/Node/Blocks/trigonometryBlock';
 import { IPropertyComponentProps } from './propertyComponentProps';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
+import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
 
 export class TrigonometryPropertyTabComponent extends React.Component<IPropertyComponentProps> {
 
@@ -41,7 +41,7 @@ export class TrigonometryPropertyTabComponent extends React.Component<IPropertyC
         
         return (
             <div>                
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
+                <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
                 <LineContainerComponent title="PROPERTIES">  
                     <OptionsLineComponent label="Operation" options={operationOptions} target={trigonometryBlock} propertyName="operation" onSelect={(value: any) => {
                         this.props.globalState.onUpdateRequiredObservable.notifyObservers();

+ 0 - 23
nodeEditor/src/diagram/properties/worleyNoise3DNodePropertyComponent.tsx

@@ -1,23 +0,0 @@
-
-import * as React from "react";
-import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
-import { IPropertyComponentProps } from './propertyComponentProps';
-import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
-import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
-
-export class WorleyNoise3DNodePropertyComponent extends React.Component<IPropertyComponentProps> {
-    constructor(props: IPropertyComponentProps) {
-        super(props)
-    }
-
-    render() {
-        return (
-            <>
-                <GenericPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Use Manhattan Distance" target={this.props.block} propertyName="manhattanDistance" onValueChanged={() => this.props.globalState.onRebuildRequiredObservable.notifyObservers()} />              
-                </LineContainerComponent>        
-            </>
-        );
-    }
-}

+ 0 - 8
nodeEditor/src/diagram/propertyLedger.ts

@@ -2,13 +2,9 @@ import { ComponentClass } from 'react';
 import { InputPropertyTabComponent } from './properties/inputNodePropertyComponent';
 import { IPropertyComponentProps } from './properties/propertyComponentProps';
 import { TransformPropertyTabComponent } from './properties/transformNodePropertyComponent';
-import { PerturbNormalPropertyTabComponent } from './properties/PerturbNormalNodePropertyComponent';
-import { WorleyNoise3DNodePropertyComponent } from './properties/worleyNoise3DNodePropertyComponent';
-import { ClampPropertyTabComponent } from './properties/clampNodePropertyComponent';
 import { GradientPropertyTabComponent } from './properties/gradientNodePropertyComponent';
 import { LightPropertyTabComponent } from './properties/lightPropertyTabComponent';
 import { LightInformationPropertyTabComponent } from './properties/lightInformationPropertyTabComponent';
-import { RemapPropertyTabComponent } from './properties/remapNodePropertyComponent';
 import { TexturePropertyTabComponent } from './properties/texturePropertyTabComponent';
 import { TrigonometryPropertyTabComponent } from './properties/trigonometryNodePropertyComponent';
 
@@ -18,13 +14,9 @@ export class PropertyLedger {
 
 PropertyLedger.RegisteredControls["TransformBlock"] = TransformPropertyTabComponent;
 PropertyLedger.RegisteredControls["InputBlock"] = InputPropertyTabComponent;
-PropertyLedger.RegisteredControls["PerturbNormalBlock"] = PerturbNormalPropertyTabComponent;
-PropertyLedger.RegisteredControls["WorleyNoise3DBlock"] = WorleyNoise3DNodePropertyComponent;
-PropertyLedger.RegisteredControls["ClampBlock"] = ClampPropertyTabComponent;
 PropertyLedger.RegisteredControls["GradientBlock"] = GradientPropertyTabComponent;
 PropertyLedger.RegisteredControls["LightBlock"] = LightPropertyTabComponent;
 PropertyLedger.RegisteredControls["LightInformationBlock"] = LightInformationPropertyTabComponent;
-PropertyLedger.RegisteredControls["RemapBlock"] = RemapPropertyTabComponent;
 PropertyLedger.RegisteredControls["TextureBlock"] = TexturePropertyTabComponent;
 PropertyLedger.RegisteredControls["ReflectionTextureBlock"] = TexturePropertyTabComponent;
 PropertyLedger.RegisteredControls["TrigonometryBlock"] = TrigonometryPropertyTabComponent;

+ 4 - 0
src/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../Enums/nodeMaterialB
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 import { _TypeStore } from '../../../../Misc/typeStore';
 
 export class AmbientOcclusionBlock extends NodeMaterialBlock {
@@ -17,6 +18,9 @@ export class AmbientOcclusionBlock extends NodeMaterialBlock {
         this.registerOutput("ambientOcclusion", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
     }
 
+    @editableInPropertyPage("Ambient in gray scale", PropertyTypeForEdition.Boolean, "AMBIENT")
+    public useAmbientInGrayScale: boolean = false;
+
     /**
      * Gets the current class name
      * @returns the class name

+ 17 - 1
src/Materials/Node/Blocks/Fragment/pbrMetallicRoughnessBlock.ts

@@ -16,6 +16,7 @@ import { Mesh } from '../../../../Meshes/mesh';
 import { PBRBaseMaterial } from '../../../PBR/pbrBaseMaterial';
 import { Scene } from '../../../../scene';
 import { AmbientOcclusionBlock } from './ambientOcclusionBlock';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 
 export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     private _lightId: number;
@@ -63,6 +64,21 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
 
     }
 
+    @editableInPropertyPage("Alpha from albedo", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    public useAlphaFromAlbedoTexture: boolean = false;
+
+    @editableInPropertyPage("Alpha Testing", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    public useAlphaTest: boolean = false;
+
+    @editableInPropertyPage("Alpha CutOff", PropertyTypeForEdition.Float, "TRANSPARENCY", { min: 0, max: 1})
+    public alphaTestCutoff: number = 0.4;
+
+    @editableInPropertyPage("Alpha blending", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    public useAlphaBlending: boolean = false;
+
+    @editableInPropertyPage("Get alpha from opacity texture RGB", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    public opacityRGB: boolean = false;
+
     /**
      * Gets the current class name
      * @returns the class name
@@ -513,7 +529,7 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             state.compilationString += this._declareOutput(this.shadow, state) + ` = shadow;\r\n`;
         }
 
-        (window as any).sheenParams = this.sheenParams;
+        (window as any).sheenParams = this.sheenParams.connectedPoint?.ownerBlock;
         return this;
     }
 

+ 3 - 0
src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts

@@ -10,6 +10,7 @@ import { InputBlock } from '../Input/inputBlock';
 import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
 import { Scene } from '../../../../scene';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 
 import "../../../../Shaders/ShadersInclude/bumpFragmentFunctions";
 import "../../../../Shaders/ShadersInclude/bumpFragment";
@@ -21,8 +22,10 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
     private _tangentSpaceParameterName = "";
 
     /** Gets or sets a boolean indicating that normal should be inverted on X axis */
+    @editableInPropertyPage("Invert X axis", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": false }})
     public invertX = false;
     /** Gets or sets a boolean indicating that normal should be inverted on Y axis */
+    @editableInPropertyPage("Invert Y axis", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": false }})
     public invertY = false;
 
     /**

+ 6 - 6
src/Materials/Node/Blocks/Fragment/sheenBlock.ts

@@ -3,7 +3,9 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../Enums/nodeMaterialB
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
+//import { Nullable } from "../../../../types";
 import { _TypeStore } from '../../../../Misc/typeStore';
+import { editableInPropertyPage } from "../../nodeMaterialDecorator";
 
 export class SheenBlock extends NodeMaterialBlock {
 
@@ -14,11 +16,13 @@ export class SheenBlock extends NodeMaterialBlock {
         this.registerInput("intensity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("color", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("roughness", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("albedoScaling", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
 
         this.registerOutput("sheen", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
     }
 
+    @editableInPropertyPage("Albedo scaling")
+    public albedoScaling: boolean = false;
+
     /**
      * Gets the current class name
      * @returns the class name
@@ -43,12 +47,8 @@ export class SheenBlock extends NodeMaterialBlock {
         return this._inputs[3];
     }
 
-    public get albedoScaling(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
-    }
-
     public get sheen(): NodeMaterialConnectionPoint {
-        return this._outputs[5];
+        return this._outputs[0];
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {

+ 4 - 0
src/Materials/Node/Blocks/clampBlock.ts

@@ -5,14 +5,18 @@ import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint
 import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
 import { _TypeStore } from '../../../Misc/typeStore';
 import { Scene } from '../../../scene';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../nodeMaterialDecorator";
+
 /**
  * Block used to clamp a float
  */
 export class ClampBlock extends NodeMaterialBlock {
 
     /** Gets or sets the minimum range */
+    @editableInPropertyPage("Minimum", PropertyTypeForEdition.Float)
     public minimum = 0.0;
     /** Gets or sets the maximum range */
+    @editableInPropertyPage("Maximum", PropertyTypeForEdition.Float)
     public maximum = 1.0;
 
     /**

+ 3 - 0
src/Materials/Node/Blocks/remapBlock.ts

@@ -6,6 +6,7 @@ import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
 import { _TypeStore } from '../../../Misc/typeStore';
 import { Vector2 } from '../../../Maths/math.vector';
 import { Scene } from '../../../scene';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../nodeMaterialDecorator";
 /**
  * Block used to remap a float from a range to a new one
  */
@@ -13,11 +14,13 @@ export class RemapBlock extends NodeMaterialBlock {
     /**
      * Gets or sets the source range
      */
+    @editableInPropertyPage("From", PropertyTypeForEdition.Vector2)
     public sourceRange = new Vector2(-1, 1);
 
     /**
      * Gets or sets the target range
      */
+    @editableInPropertyPage("To", PropertyTypeForEdition.Vector2)
     public targetRange = new Vector2(0, 1);
 
     /**

+ 2 - 0
src/Materials/Node/Blocks/worleyNoise3DBlock.ts

@@ -5,6 +5,7 @@ import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint
 import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
 import { _TypeStore } from '../../../Misc/typeStore';
 import { Scene } from '../../../scene';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 
 /**
  * block used to Generate a Worley Noise 3D Noise Pattern
@@ -18,6 +19,7 @@ import { Scene } from '../../../scene';
 
 export class WorleyNoise3DBlock extends NodeMaterialBlock {
     /** Gets or sets a boolean indicating that normal should be inverted on X axis */
+    @editableInPropertyPage("Use Manhattan Distance", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": false }})
     public manhattanDistance = false;
 
     /**

+ 2 - 1
src/Materials/Node/index.ts

@@ -3,4 +3,5 @@ export * from "./nodeMaterialBlockConnectionPoint";
 export * from "./nodeMaterialBlock";
 export * from "./nodeMaterial";
 export * from "./Blocks/index";
-export * from "./Optimizers/index";
+export * from "./Optimizers/index";
+export * from "./nodeMaterialDecorator";

+ 39 - 0
src/Materials/Node/nodeMaterialDecorator.ts

@@ -0,0 +1,39 @@
+export enum PropertyTypeForEdition {
+    Boolean,
+    Float,
+    Vector2,
+}
+
+export interface IEditablePropertyOption {
+    "min"?: number;
+    "max"?: number;
+    "notifiers"?: {
+        "rebuild"?: boolean;
+        "update"?: boolean;
+    };
+}
+
+export interface IPropertyDescriptionForEdition {
+    "propertyName": string;
+    "displayName": string;
+    "type": PropertyTypeForEdition;
+    "groupName": string;
+    "options": IEditablePropertyOption;
+}
+
+export function editableInPropertyPage(displayName: string, propertyType: PropertyTypeForEdition = PropertyTypeForEdition.Boolean, groupName: string = "PROPERTIES", options?: IEditablePropertyOption) {
+    return (target: any, propertyKey: string) => {
+        let propStore: IPropertyDescriptionForEdition[] = target._propStore;
+        if (!propStore) {
+            propStore = [];
+            target._propStore = propStore;
+        }
+        propStore.push({
+            "propertyName": propertyKey,
+            "displayName": displayName,
+            "type": propertyType,
+            "groupName": groupName,
+            "options": options ?? {}
+        });
+    };
+}