浏览代码

Serialize pp (#8716)

* First pass

* pass 2

* Final push
David Catuhe 5 年之前
父节点
当前提交
3c324d8979
共有 39 个文件被更改,包括 773 次插入77 次删除
  1. 2 1
      dist/preview release/what's new.md
  2. 1 1
      src/Engines/thinEngine.ts
  3. 14 0
      src/Loading/Plugins/babylonFileLoader.ts
  4. 6 2
      src/Misc/sceneRecorder.ts
  5. 6 0
      src/Misc/sceneSerializer.ts
  6. 11 0
      src/PostProcesses/anaglyphPostProcess.ts
  7. 26 0
      src/PostProcesses/blackAndWhitePostProcess.ts
  8. 18 1
      src/PostProcesses/bloomMergePostProcess.ts
  9. 33 2
      src/PostProcesses/blurPostProcess.ts
  10. 43 0
      src/PostProcesses/chromaticAberrationPostProcess.ts
  11. 16 0
      src/PostProcesses/circleOfConfusionPostProcess.ts
  12. 34 0
      src/PostProcesses/colorCorrectionPostProcess.ts
  13. 31 3
      src/PostProcesses/convolutionPostProcess.ts
  14. 21 1
      src/PostProcesses/depthOfFieldBlurPostProcess.ts
  15. 8 0
      src/PostProcesses/depthOfFieldMergePostProcess.ts
  16. 25 0
      src/PostProcesses/displayPassPostProcess.ts
  17. 15 0
      src/PostProcesses/extractHighlightsPostProcess.ts
  18. 31 2
      src/PostProcesses/filterPostProcess.ts
  19. 23 4
      src/PostProcesses/fxaaPostProcess.ts
  20. 27 0
      src/PostProcesses/grainPostProcess.ts
  21. 8 0
      src/PostProcesses/highlightsPostProcess.ts
  22. 0 1
      src/PostProcesses/imageProcessingPostProcess.ts
  23. 26 1
      src/PostProcesses/motionBlurPostProcess.ts
  24. 44 0
      src/PostProcesses/passPostProcess.ts
  25. 93 31
      src/PostProcesses/postProcess.ts
  26. 51 6
      src/PostProcesses/refractionPostProcess.ts
  27. 26 1
      src/PostProcesses/screenSpaceCurvaturePostProcess.ts
  28. 25 2
      src/PostProcesses/screenSpaceReflectionPostProcess.ts
  29. 28 0
      src/PostProcesses/sharpenPostProcess.ts
  30. 16 0
      src/PostProcesses/stereoscopicInterlacePostProcess.ts
  31. 7 5
      src/PostProcesses/subSurfaceScatteringPostProcess.ts
  32. 7 0
      src/PostProcesses/tonemapPostProcess.ts
  33. 3 0
      src/PostProcesses/volumetricLightScatteringPostProcess.ts
  34. 8 0
      src/PostProcesses/vrDistortionCorrectionPostProcess.ts
  35. 8 0
      src/PostProcesses/vrMultiviewToSingleviewPostProcess.ts
  36. 6 0
      src/abstractScene.ts
  37. 1 1
      src/node.ts
  38. 23 10
      src/scene.ts
  39. 2 2
      tests/es6Modules/webpack-stats.json

+ 2 - 1
dist/preview release/what's new.md

@@ -17,7 +17,8 @@
 
 ### General
 
-- Added support for querystrings on KTX file URLs ([abogartz](https://github.com/abogartz/Babylon.js)
+- Added support for postproces serialization ([Deltakosh](https://github.com/deltakosh))
+- Added support for querystrings on KTX file URLs ([abogartz](https://github.com/abogartz)
 - Refactored React refs from old string API to React.createRef() API ([belfortk](https://github.com/belfortk))
 - Scale on one axis for `BoundingBoxGizmo` ([cedricguillemet](https://github.com/cedricguillemet))
 - Camera gizmo ([cedricguillemet](https://github.com/cedricguillemet))

+ 1 - 1
src/Engines/thinEngine.ts

@@ -941,7 +941,7 @@ export class ThinEngine {
     }
 
     /**
-     * Gets a string idenfifying the name of the class
+     * Gets a string identifying the name of the class
      * @returns "Engine" string
      */
     public getClassName(): string {

+ 14 - 0
src/Loading/Plugins/babylonFileLoader.ts

@@ -29,6 +29,7 @@ import { ReflectionProbe } from "../../Probes/reflectionProbe";
 import { _TypeStore } from '../../Misc/typeStore';
 import { Tools } from '../../Misc/tools';
 import { StringTools } from '../../Misc/stringTools';
+import { PostProcess } from '../../PostProcesses/postProcess';
 
 /** @hidden */
 export var _BabylonLoaderRegistered = true;
@@ -315,6 +316,19 @@ var loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError?:
             }
         }
 
+        // Postprocesses
+        if (parsedData.postProcesses !== undefined && parsedData.postProcesses !== null) {
+            for (index = 0, cache = parsedData.postProcesses.length; index < cache; index++) {
+                var parsedPostProcess = parsedData.postProcesses[index];
+                var postProcess = PostProcess.Parse(parsedPostProcess, scene, rootUrl);
+                if (postProcess) {
+                    container.postProcesses.push(postProcess);
+                    log += (index === 0 ? "\n\Postprocesses:" : "");
+                    log += "\n\t\t" + postProcess.toString();
+                }
+            }
+        }
+
         // Animation Groups
         if (parsedData.animationGroups !== undefined && parsedData.animationGroups !== null) {
             for (index = 0, cache = parsedData.animationGroups.length; index < cache; index++) {

+ 6 - 2
src/Misc/sceneRecorder.ts

@@ -11,6 +11,7 @@ import { TransformNode } from '../Meshes/transformNode';
 import { ParticleSystem } from '../Particles/particleSystem';
 import { MorphTargetManager } from '../Morph/morphTargetManager';
 import { ShadowGenerator } from '../Lights/Shadows/shadowGenerator';
+import { PostProcess } from '../PostProcesses/postProcess';
 
 /**
  * Class used to record delta files between 2 scene states
@@ -89,7 +90,7 @@ export class SceneRecorder {
                         deltaJSON[key] = [];
                     }
                     newObject.__state = {
-                        id: currentObject.id
+                        id: currentObject.id || currentObject.name
                     };
                     deltaJSON[key].push(newObject);
                 }
@@ -97,7 +98,7 @@ export class SceneRecorder {
                 // We need to delete
                 let newObject: any = {
                     __state: {
-                        deleteId: originalObject.id
+                        deleteId: originalObject.id || originalObject.name
                     }
                 };
                 deltaJSON[key].push(newObject);
@@ -231,6 +232,9 @@ export class SceneRecorder {
                     case "morphTargetManagers":
                         this._ApplyDeltaForEntity(source, scene, scene.getMorphTargetById.bind(scene), (data) => MorphTargetManager.Parse(data, scene));
                         break;
+                    case "postProcesses":
+                        this._ApplyDeltaForEntity(source, scene, scene.getPostProcessByName.bind(scene), (data) => PostProcess.Parse(data, scene, ""));
+                        break;
                 }
             } else if (!isNaN(property)) {
                 anyScene[prop] = source;

+ 6 - 0
src/Misc/sceneSerializer.ts

@@ -296,6 +296,12 @@ export class SceneSerializer {
             serializationObject.particleSystems.push(scene.particleSystems[index].serialize(false));
         }
 
+        // Post processes
+        serializationObject.postProcesses = [];
+        for (index = 0; index < scene.postProcesses.length; index++) {
+            serializationObject.postProcesses.push(scene.postProcesses[index].serialize());
+        }
+
         // Action Manager
         if (scene.actionManager) {
             serializationObject.actions = scene.actionManager.serialize("scene");

+ 11 - 0
src/PostProcesses/anaglyphPostProcess.ts

@@ -5,6 +5,7 @@ import { Camera } from "../Cameras/camera";
 import { Effect } from "../Materials/effect";
 
 import "../Shaders/anaglyph.fragment";
+import { _TypeStore } from '../Misc/typeStore';
 
 /**
  * Postprocess used to generate anaglyphic rendering
@@ -13,6 +14,14 @@ export class AnaglyphPostProcess extends PostProcess {
     private _passedProcess: Nullable<PostProcess>;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "AnaglyphPostProcess" string
+     */
+    public getClassName(): string {
+        return "AnaglyphPostProcess";
+    }
+
+    /**
      * Creates a new AnaglyphPostProcess
      * @param name defines postprocess name
      * @param options defines creation options or target ratio scale
@@ -30,3 +39,5 @@ export class AnaglyphPostProcess extends PostProcess {
         });
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.AnaglyphPostProcess"] = AnaglyphPostProcess;

+ 26 - 0
src/PostProcesses/blackAndWhitePostProcess.ts

@@ -4,6 +4,11 @@ import { Effect } from "../Materials/effect";
 import { Engine } from "../Engines/engine";
 
 import "../Shaders/blackAndWhite.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
+import { Nullable } from '../types';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * Post process used to render in black and white
@@ -12,9 +17,18 @@ export class BlackAndWhitePostProcess extends PostProcess {
     /**
      * Linear about to convert he result to black and white (default: 1)
      */
+    @serialize()
     public degree = 1;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "BlackAndWhitePostProcess" string
+     */
+    public getClassName(): string {
+        return "BlackAndWhitePostProcess";
+    }
+
+    /**
      * Creates a black and white post process
      * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#black-and-white
      * @param name The name of the effect.
@@ -31,4 +45,16 @@ export class BlackAndWhitePostProcess extends PostProcess {
             effect.setFloat("degree", this.degree);
         });
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<BlackAndWhitePostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new BlackAndWhitePostProcess(
+                parsedPostProcess.name, parsedPostProcess.options,
+                targetCamera, parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.BlackAndWhitePostProcess"] = BlackAndWhitePostProcess;

+ 18 - 1
src/PostProcesses/bloomMergePostProcess.ts

@@ -6,11 +6,25 @@ import { Camera } from "../Cameras/camera";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/bloomMerge.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize } from '../Misc/decorators';
 
 /**
  * The BloomMergePostProcess merges blurred images with the original based on the values of the circle of confusion.
  */
 export class BloomMergePostProcess extends PostProcess {
+    /** Weight of the bloom to be added to the original input. */
+    @serialize()
+    public weight = 1;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "BloomMergePostProcess" string
+     */
+    public getClassName(): string {
+        return "BloomMergePostProcess";
+    }
+
     /**
      * Creates a new instance of @see BloomMergePostProcess
      * @param name The name of the effect.
@@ -27,10 +41,11 @@ export class BloomMergePostProcess extends PostProcess {
      */
     constructor(name: string, originalFromInput: PostProcess, blurred: PostProcess,
         /** Weight of the bloom to be added to the original input. */
-        public weight: number,
+        weight: number,
         options: number | PostProcessOptions,
         camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, "bloomMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
+        this.weight = weight;
         this.onApplyObservable.add((effect: Effect) => {
             effect.setTextureFromPostProcess("textureSampler", originalFromInput);
             effect.setTextureFromPostProcessOutput("bloomBlur", blurred);
@@ -42,3 +57,5 @@ export class BloomMergePostProcess extends PostProcess {
         }
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.BloomMergePostProcess"] = BloomMergePostProcess;

+ 33 - 2
src/PostProcesses/blurPostProcess.ts

@@ -9,16 +9,27 @@ import { Constants } from "../Engines/constants";
 
 import "../Shaders/kernelBlur.fragment";
 import "../Shaders/kernelBlur.vertex";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, serializeAsVector2, SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * The Blur Post Process which blurs an image based on a kernel and direction.
  * Can be used twice in x and y directions to perform a guassian blur in two passes.
  */
 export class BlurPostProcess extends PostProcess {
+    @serialize("kernel")
     protected _kernel: number;
     protected _idealKernel: number;
+    @serialize("packedFloat")
     protected _packedFloat: boolean = false;
     private _staticDefines: string = "";
+
+    /** The direction in which to blur the image. */
+    @serializeAsVector2()
+    public direction: Vector2;
+
     /**
      * Sets the length in pixels of the blur sample region
      */
@@ -63,6 +74,14 @@ export class BlurPostProcess extends PostProcess {
     }
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "BlurPostProcess" string
+     */
+    public getClassName(): string {
+        return "BlurPostProcess";
+    }
+
+    /**
      * Creates a new instance BlurPostProcess
      * @param name The name of the effect.
      * @param direction The direction in which to blur the image.
@@ -76,11 +95,11 @@ export class BlurPostProcess extends PostProcess {
      * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
      */
     constructor(name: string,
-        /** The direction in which to blur the image. */
-        public direction: Vector2,
+        direction: Vector2,
         kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, defines = "", private blockCompilation = false) {
         super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true);
         this._staticDefines = defines;
+        this.direction = direction;
         this.onApplyObservable.add((effect: Effect) => {
             if (this._outputTexture) {
                 effect.setFloat2('delta', (1 / this._outputTexture.width) * this.direction.x, (1 / this._outputTexture.height) * this.direction.y);
@@ -254,4 +273,16 @@ export class BlurPostProcess extends PostProcess {
     protected _glslFloat(x: number, decimalFigures = 8) {
         return x.toFixed(decimalFigures).replace(/0+$/, '');
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<BlurPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new BlurPostProcess(
+                parsedPostProcess.name, parsedPostProcess.direction, parsedPostProcess.kernel,
+                parsedPostProcess.options, targetCamera, parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable, parsedPostProcess.textureType, undefined, false);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.BlurPostProcess"] = BlurPostProcess;

+ 43 - 0
src/PostProcesses/chromaticAberrationPostProcess.ts

@@ -7,6 +7,10 @@ import { Engine } from "../Engines/engine";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/chromaticAberration.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * The ChromaticAberrationPostProcess separates the rgb channels in an image to produce chromatic distortion around the edges of the screen
@@ -15,23 +19,43 @@ export class ChromaticAberrationPostProcess extends PostProcess {
     /**
      * The amount of seperation of rgb channels (default: 30)
      */
+    @serialize()
     aberrationAmount = 30;
 
     /**
      * The amount the effect will increase for pixels closer to the edge of the screen. (default: 0)
      */
+    @serialize()
     radialIntensity = 0;
 
     /**
      * The normilized direction in which the rgb channels should be seperated. If set to 0,0 radial direction will be used. (default: Vector2(0.707,0.707))
      */
+    @serialize()
     direction = new Vector2(0.707, 0.707);
 
     /**
      * The center position where the radialIntensity should be around. [0.5,0.5 is center of screen, 1,1 is top right corder] (default: Vector2(0.5 ,0.5))
      */
+    @serialize()
     centerPosition = new Vector2(0.5, 0.5);
 
+    /** The width of the screen to apply the effect on */
+    @serialize()
+    screenWidth: number;
+
+    /** The height of the screen to apply the effect on */
+    @serialize()
+    screenHeight: number;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "ChromaticAberrationPostProcess" string
+     */
+    public getClassName(): string {
+        return "ChromaticAberrationPostProcess";
+    }
+
     /**
      * Creates a new instance ChromaticAberrationPostProcess
      * @param name The name of the effect.
@@ -47,6 +71,10 @@ export class ChromaticAberrationPostProcess extends PostProcess {
      */
     constructor(name: string, screenWidth: number, screenHeight: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, "chromaticAberration", ["chromatic_aberration", "screen_width", "screen_height", "direction", "radialIntensity", "centerPosition"], [], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation);
+
+        this.screenWidth = screenWidth;
+        this.screenHeight = screenHeight;
+
         this.onApplyObservable.add((effect: Effect) => {
             effect.setFloat('chromatic_aberration', this.aberrationAmount);
             effect.setFloat('screen_width', screenWidth);
@@ -56,4 +84,19 @@ export class ChromaticAberrationPostProcess extends PostProcess {
             effect.setFloat2('centerPosition', this.centerPosition.x, this.centerPosition.y);
         });
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ChromaticAberrationPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new ChromaticAberrationPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.screenWidth, parsedPostProcess.screenHeight,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable,
+                parsedPostProcess.textureType, false);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ChromaticAberrationPostProcess"] = ChromaticAberrationPostProcess;

+ 16 - 0
src/PostProcesses/circleOfConfusionPostProcess.ts

@@ -8,6 +8,8 @@ import { Logger } from "../Misc/logger";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/circleOfConfusion.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize } from '../Misc/decorators';
 
 /**
  * The CircleOfConfusionPostProcess computes the circle of confusion value for each pixel given required lens parameters. See https://en.wikipedia.org/wiki/Circle_of_confusion
@@ -16,20 +18,32 @@ export class CircleOfConfusionPostProcess extends PostProcess {
     /**
      * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
      */
+    @serialize()
     public lensSize = 50;
     /**
      * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
      */
+    @serialize()
     public fStop = 1.4;
     /**
      * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
      */
+    @serialize()
     public focusDistance = 2000;
     /**
      * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
      */
+    @serialize()
     public focalLength = 50;
 
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "CircleOfConfusionPostProcess" string
+     */
+    public getClassName(): string {
+        return "CircleOfConfusionPostProcess";
+    }
+
     private _depthTexture: Nullable<RenderTargetTexture> = null;
     /**
      * Creates a new instance CircleOfConfusionPostProcess
@@ -70,3 +84,5 @@ export class CircleOfConfusionPostProcess extends PostProcess {
         this._depthTexture = value;
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.CircleOfConfusionPostProcess"] = CircleOfConfusionPostProcess;

+ 34 - 0
src/PostProcesses/colorCorrectionPostProcess.ts

@@ -5,6 +5,11 @@ import { Engine } from "../Engines/engine";
 import { Camera } from "../Cameras/camera";
 
 import "../Shaders/colorCorrection.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { SerializationHelper, serialize } from '../Misc/decorators';
+import { Nullable } from '../types';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  *
@@ -25,6 +30,20 @@ export class ColorCorrectionPostProcess extends PostProcess {
 
     private _colorTableTexture: Texture;
 
+    /**
+     * Gets the color table url used to create the LUT texture
+     */
+    @serialize()
+    public colorTableUrl: string;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "ColorCorrectionPostProcess" string
+     */
+    public getClassName(): string {
+        return "ColorCorrectionPostProcess";
+    }
+
     constructor(name: string, colorTableUrl: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
         super(name, 'colorCorrection', null, ['colorTable'], options, camera, samplingMode, engine, reusable);
 
@@ -33,8 +52,23 @@ export class ColorCorrectionPostProcess extends PostProcess {
         this._colorTableTexture.wrapU = Texture.CLAMP_ADDRESSMODE;
         this._colorTableTexture.wrapV = Texture.CLAMP_ADDRESSMODE;
 
+        this.colorTableUrl = colorTableUrl;
+
         this.onApply = (effect: Effect) => {
             effect.setTexture("colorTable", this._colorTableTexture);
         };
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ColorCorrectionPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new ColorCorrectionPostProcess(
+                parsedPostProcess.name, parsedPostProcess.colorTableUrl,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ColorCorrectionPostProcess"] = ColorCorrectionPostProcess;

+ 31 - 3
src/PostProcesses/convolutionPostProcess.ts

@@ -6,6 +6,10 @@ import { Effect } from "../Materials/effect";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/convolution.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * The ConvolutionPostProcess applies a 3x3 kernel to every pixel of the
@@ -13,6 +17,18 @@ import "../Shaders/convolution.fragment";
  * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
  */
 export class ConvolutionPostProcess extends PostProcess {
+    /** Array of 9 values corresponding to the 3x3 kernel to be applied */
+    @serialize()
+    public kernel: number[];
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "ConvolutionPostProcess" string
+     */
+    public getClassName(): string {
+        return "ConvolutionPostProcess";
+    }
+
     /**
      * Creates a new instance ConvolutionPostProcess
      * @param name The name of the effect.
@@ -25,17 +41,27 @@ export class ConvolutionPostProcess extends PostProcess {
      * @param textureType Type of textures used when performing the post process. (default: 0)
      */
     constructor(name: string,
-        /** Array of 9 values corresponding to the 3x3 kernel to be applied */
-        public kernel: number[],
+        kernel: number[],
         options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(name, "convolution", ["kernel", "screenSize"], null, options, camera, samplingMode, engine, reusable, null, textureType);
-
+            this.kernel = kernel;
         this.onApply = (effect: Effect) => {
             effect.setFloat2("screenSize", this.width, this.height);
             effect.setArray("kernel", this.kernel);
         };
     }
 
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ConvolutionPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new ConvolutionPostProcess(
+                parsedPostProcess.name, parsedPostProcess.kernel,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable, parsedPostProcess.textureType);
+        }, parsedPostProcess, scene, rootUrl);
+    }
+
     // Statics
     /**
      * Edge detection 0 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
@@ -62,3 +88,5 @@ export class ConvolutionPostProcess extends PostProcess {
      */
     public static GaussianKernel = [0, 1, 0, 1, 1, 1, 0, 1, 0];
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ConvolutionPostProcess"] = ConvolutionPostProcess;

+ 21 - 1
src/PostProcesses/depthOfFieldBlurPostProcess.ts

@@ -8,6 +8,8 @@ import { BlurPostProcess } from "./blurPostProcess";
 import { Engine } from "../Engines/engine";
 import { Scene } from "../scene";
 import { Constants } from "../Engines/constants";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize } from '../Misc/decorators';
 
 /**
  * The DepthOfFieldBlurPostProcess applied a blur in a give direction.
@@ -17,6 +19,20 @@ import { Constants } from "../Engines/constants";
  */
 export class DepthOfFieldBlurPostProcess extends BlurPostProcess {
     /**
+     * The direction the blur should be applied
+     */
+    @serialize()
+    public direction: Vector2;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "DepthOfFieldBlurPostProcess" string
+     */
+    public getClassName(): string {
+        return "DepthOfFieldBlurPostProcess";
+    }
+
+    /**
      * Creates a new instance CircleOfConfusionPostProcess
      * @param name The name of the effect.
      * @param scene The scene the effect belongs to.
@@ -32,9 +48,11 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess {
      * @param textureType Type of textures used when performing the post process. (default: 0)
      * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
      */
-    constructor(name: string, scene: Scene, public direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, circleOfConfusion: PostProcess, imageToBlur: Nullable<PostProcess> = null, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
+    constructor(name: string, scene: Scene, direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, circleOfConfusion: PostProcess, imageToBlur: Nullable<PostProcess> = null, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, direction, kernel, options, camera, samplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE, engine, reusable, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, `#define DOF 1\r\n`, blockCompilation);
 
+        this.direction = direction;
+
         this.onApplyObservable.add((effect: Effect) => {
             if (imageToBlur != null) {
                 effect.setTextureFromPostProcess("textureSampler", imageToBlur);
@@ -46,3 +64,5 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess {
         });
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.DepthOfFieldBlurPostProcess"] = DepthOfFieldBlurPostProcess;

+ 8 - 0
src/PostProcesses/depthOfFieldMergePostProcess.ts

@@ -36,6 +36,14 @@ export class DepthOfFieldMergePostProcessOptions {
  */
 export class DepthOfFieldMergePostProcess extends PostProcess {
     /**
+     * Gets a string identifying the name of the class
+     * @returns "DepthOfFieldMergePostProcess" string
+     */
+    public getClassName(): string {
+        return "DepthOfFieldMergePostProcess";
+    }
+
+    /**
      * Creates a new instance of DepthOfFieldMergePostProcess
      * @param name The name of the effect.
      * @param originalFromInput Post process which's input will be used for the merge.

+ 25 - 0
src/PostProcesses/displayPassPostProcess.ts

@@ -4,12 +4,24 @@ import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Engine } from "../Engines/engine";
 
 import "../Shaders/displayPass.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * DisplayPassPostProcess which produces an output the same as it's input
  */
 export class DisplayPassPostProcess extends PostProcess {
     /**
+     * Gets a string identifying the name of the class
+     * @returns "DisplayPassPostProcess" string
+     */
+    public getClassName(): string {
+        return "DisplayPassPostProcess";
+    }
+
+    /**
      * Creates the DisplayPassPostProcess
      * @param name The name of the effect.
      * @param options The required width/height ratio to downsize to before computing the render pass.
@@ -21,4 +33,17 @@ export class DisplayPassPostProcess extends PostProcess {
     constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean) {
         super(name, "displayPass", ["passSampler"], ["passSampler"], options, camera, samplingMode, engine, reusable);
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<DisplayPassPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new DisplayPassPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.DisplayPassPostProcess"] = DisplayPassPostProcess;

+ 15 - 0
src/PostProcesses/extractHighlightsPostProcess.ts

@@ -7,6 +7,8 @@ import { ToGammaSpace } from "../Maths/math.constants";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/extractHighlights.fragment";
+import { serialize } from '../Misc/decorators';
+import { _TypeStore } from '../Misc/typeStore';
 
 /**
  * The extract highlights post process sets all pixels to black except pixels above the specified luminance threshold. Used as the first step for a bloom effect.
@@ -15,15 +17,26 @@ export class ExtractHighlightsPostProcess extends PostProcess {
     /**
      * The luminance threshold, pixels below this value will be set to black.
      */
+    @serialize()
     public threshold = 0.9;
 
     /** @hidden */
     public _exposure = 1;
+
     /**
      * Post process which has the input texture to be used when performing highlight extraction
      * @hidden
      */
     public _inputPostProcess: Nullable<PostProcess> = null;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "ExtractHighlightsPostProcess" string
+     */
+    public getClassName(): string {
+        return "ExtractHighlightsPostProcess";
+    }
+
     constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, "extractHighlights", ["threshold", "exposure"], null, options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation);
         this.onApplyObservable.add((effect: Effect) => {
@@ -35,3 +48,5 @@ export class ExtractHighlightsPostProcess extends PostProcess {
         });
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ExtractHighlightsPostProcess"] = ExtractHighlightsPostProcess;

+ 31 - 2
src/PostProcesses/filterPostProcess.ts

@@ -6,11 +6,27 @@ import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Engine } from "../Engines/engine";
 
 import "../Shaders/filter.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serializeAsMatrix, SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * Applies a kernel filter to the image
  */
 export class FilterPostProcess extends PostProcess {
+    /** The matrix to be applied to the image */
+    @serializeAsMatrix()
+    public kernelMatrix: Matrix;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "FilterPostProcess" string
+     */
+    public getClassName(): string {
+        return "FilterPostProcess";
+    }
+
     /**
      *
      * @param name The name of the effect.
@@ -22,8 +38,7 @@ export class FilterPostProcess extends PostProcess {
      * @param reusable If the post process can be reused on the same frame. (default: false)
      */
     constructor(name: string,
-        /** The matrix to be applied to the image */
-        public kernelMatrix: Matrix,
+        kernelMatrix: Matrix,
         options: number | PostProcessOptions,
         camera: Nullable<Camera>,
         samplingMode?: number,
@@ -31,9 +46,23 @@ export class FilterPostProcess extends PostProcess {
         reusable?: boolean
     ) {
         super(name, "filter", ["kernelMatrix"], null, options, camera, samplingMode, engine, reusable);
+        this.kernelMatrix = kernelMatrix;
 
         this.onApply = (effect: Effect) => {
             effect.setMatrix("kernelMatrix", this.kernelMatrix);
         };
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<FilterPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new FilterPostProcess(
+                parsedPostProcess.name, parsedPostProcess.kernelMatrix,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.FilterPostProcess"] = FilterPostProcess;

+ 23 - 4
src/PostProcesses/fxaaPostProcess.ts

@@ -8,16 +8,22 @@ import { Constants } from "../Engines/constants";
 
 import "../Shaders/fxaa.fragment";
 import "../Shaders/fxaa.vertex";
+import { _TypeStore } from '../Misc/typeStore';
+import { SerializationHelper } from '../Misc/decorators';
 
+declare type Scene = import("../scene").Scene;
 /**
  * Fxaa post process
  * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#fxaa
  */
 export class FxaaPostProcess extends PostProcess {
-    /** @hidden */
-    public texelWidth: number;
-    /** @hidden */
-    public texelHeight: number;
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "FxaaPostProcess" string
+     */
+    public getClassName(): string {
+        return "FxaaPostProcess";
+    }
 
     constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa", undefined, true);
@@ -44,4 +50,17 @@ export class FxaaPostProcess extends PostProcess {
 
         return null;
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new FxaaPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.FxaaPostProcess"] = FxaaPostProcess;

+ 27 - 0
src/PostProcesses/grainPostProcess.ts

@@ -6,6 +6,10 @@ import { Engine } from "../Engines/engine";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/grain.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * The GrainPostProcess adds noise to the image at mid luminance levels
@@ -14,13 +18,23 @@ export class GrainPostProcess extends PostProcess {
     /**
      * The intensity of the grain added (default: 30)
      */
+    @serialize()
     public intensity: number = 30;
     /**
      * If the grain should be randomized on every frame
      */
+    @serialize()
     public animated: boolean = false;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "GrainPostProcess" string
+     */
+    public getClassName(): string {
+        return "GrainPostProcess";
+    }
+
+    /**
      * Creates a new instance of @see GrainPostProcess
      * @param name The name of the effect.
      * @param options The required width/height ratio to downsize to before computing the render pass.
@@ -38,4 +52,17 @@ export class GrainPostProcess extends PostProcess {
             effect.setFloat('animatedSeed', this.animated ? Math.random() + 1 : 1);
         });
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new GrainPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.GrainPostProcess"] = GrainPostProcess;

+ 8 - 0
src/PostProcesses/highlightsPostProcess.ts

@@ -12,6 +12,14 @@ import "../Shaders/highlights.fragment";
  */
 export class HighlightsPostProcess extends PostProcess {
     /**
+     * Gets a string identifying the name of the class
+     * @returns "HighlightsPostProcess" string
+     */
+    public getClassName(): string {
+        return "HighlightsPostProcess";
+    }
+
+    /**
      * Extracts highlights from the image
      * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses
      * @param name The name of the effect.

+ 0 - 1
src/PostProcesses/imageProcessingPostProcess.ts

@@ -20,7 +20,6 @@ import "../Shaders/postprocess.vertex";
  * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#imageprocessing
  */
 export class ImageProcessingPostProcess extends PostProcess {
-
     /**
      * Default configuration related to image processing available in the PBR Material.
      */

+ 26 - 1
src/PostProcesses/motionBlurPostProcess.ts

@@ -6,14 +6,16 @@ import { Effect } from "../Materials/effect";
 import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Constants } from "../Engines/constants";
 import { GeometryBufferRenderer } from "../Rendering/geometryBufferRenderer";
-import { Scene } from "../scene";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 
 import "../Animations/animatable";
 import '../Rendering/geometryBufferRendererSceneComponent';
 import "../Shaders/motionBlur.fragment";
+import { serialize, SerializationHelper } from '../Misc/decorators';
+import { _TypeStore } from '../Misc/typeStore';
 
 declare type Engine = import("../Engines/engine").Engine;
+declare type Scene = import("../scene").Scene;
 
 /**
  * The Motion Blur Post Process which blurs an image based on the objects velocity in scene.
@@ -31,6 +33,7 @@ export class MotionBlurPostProcess extends PostProcess {
     /**
      * Defines how much the image is blurred by the movement. Default value is equal to 1
      */
+    @serialize()
     public motionStrength: number = 1;
 
     /**
@@ -51,10 +54,19 @@ export class MotionBlurPostProcess extends PostProcess {
         }
     }
 
+    @serialize("motionBlurSamples")
     private _motionBlurSamples: number = 32;
     private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "MotionBlurPostProcess" string
+     */
+    public getClassName(): string {
+        return "MotionBlurPostProcess";
+    }
+
+    /**
      * Creates a new instance MotionBlurPostProcess
      * @param name The name of the effect.
      * @param scene The scene containing the objects to blur according to their velocity.
@@ -132,4 +144,17 @@ export class MotionBlurPostProcess extends PostProcess {
 
         super.dispose(camera);
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<MotionBlurPostProcess> {
+        return SerializationHelper.Parse(() => {
+            return new MotionBlurPostProcess(
+                parsedPostProcess.name, scene, parsedPostProcess.options,
+                targetCamera, parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable,
+                parsedPostProcess.textureType, false);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.MotionBlurPostProcess"] = MotionBlurPostProcess;

+ 44 - 0
src/PostProcesses/passPostProcess.ts

@@ -6,12 +6,24 @@ import { Engine } from "../Engines/engine";
 
 import "../Shaders/pass.fragment";
 import "../Shaders/passCube.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { SerializationHelper } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * PassPostProcess which produces an output the same as it's input
  */
 export class PassPostProcess extends PostProcess {
     /**
+     * Gets a string identifying the name of the class
+     * @returns "PassPostProcess" string
+     */
+    public getClassName(): string {
+        return "PassPostProcess";
+    }
+
+    /**
      * Creates the PassPostProcess
      * @param name The name of the effect.
      * @param options The required width/height ratio to downsize to before computing the render pass.
@@ -25,8 +37,21 @@ export class PassPostProcess extends PostProcess {
     constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, "pass", null, null, options, camera, samplingMode, engine, reusable, undefined, textureType, undefined, null, blockCompilation);
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new PassPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
 
+_TypeStore.RegisteredTypes["BABYLON.PassPostProcess"] = PassPostProcess;
+
 /**
  * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)
  */
@@ -75,6 +100,14 @@ export class PassCubePostProcess extends PostProcess {
     }
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "PassCubePostProcess" string
+     */
+    public getClassName(): string {
+        return "PassCubePostProcess";
+    }
+
+    /**
      * Creates the PassCubePostProcess
      * @param name The name of the effect.
      * @param options The required width/height ratio to downsize to before computing the render pass.
@@ -88,6 +121,17 @@ export class PassCubePostProcess extends PostProcess {
     constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         super(name, "passCube", null, null, options, camera, samplingMode, engine, reusable, "#define POSITIVEX", textureType, undefined, null, blockCompilation);
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new PassCubePostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
 
 Engine._RescalePostProcessFactory = (engine: Engine) => {

+ 93 - 31
src/PostProcesses/postProcess.ts

@@ -12,6 +12,8 @@ import { Color4 } from '../Maths/math.color';
 
 import "../Engines/Extensions/engine.renderTarget";
 import { NodeMaterial } from '../Materials/Node/nodeMaterial';
+import { serialize, serializeAsColor4, SerializationHelper } from '../Misc/decorators';
+import { _TypeStore } from '../Misc/typeStore';
 
 declare type Scene = import("../scene").Scene;
 declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture;
@@ -31,16 +33,23 @@ export class PostProcess {
     /**
      * Gets or sets the unique id of the post process
      */
+    @serialize()
     public uniqueId: number;
 
+    /** Name of the PostProcess. */
+    @serialize()
+    public name: string;
+
     /**
     * Width of the texture to apply the post process on
     */
+    @serialize()
     public width = -1;
 
     /**
     * Height of the texture to apply the post process on
     */
+    @serialize()
     public height = -1;
 
     /**
@@ -57,23 +66,28 @@ export class PostProcess {
     * Sampling mode used by the shader
     * See https://doc.babylonjs.com/classes/3.1/texture
     */
+    @serialize()
     public renderTargetSamplingMode: number;
     /**
     * Clear color to use when screen clearing
     */
+    @serializeAsColor4()
     public clearColor: Color4;
     /**
     * If the buffer needs to be cleared before applying the post process. (default: true)
     * Should be set to false if shader will overwrite all previous pixels.
     */
+    @serialize()
     public autoClear = true;
     /**
     * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
     */
+    @serialize()
     public alphaMode = Constants.ALPHA_DISABLE;
     /**
     * Sets the setAlphaBlendConstants of the babylon engine
     */
+    @serialize()
     public alphaConstants: Color4;
     /**
     * Animations to be used for the post processing
@@ -84,11 +98,13 @@ export class PostProcess {
      * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
      * Can only be used on a single postprocess or on the last one of a chain. (default: false)
      */
+    @serialize()
     public enablePixelPerfectMode = false;
 
     /**
      * Force the postprocess to be applied without taking in account viewport
      */
+    @serialize()
     public forceFullscreenViewport = true;
 
     /**
@@ -107,13 +123,17 @@ export class PostProcess {
      * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |
      *
      */
+    @serialize()
     public scaleMode = Constants.SCALEMODE_FLOOR;
     /**
     * Force textures to be a power of two (default: false)
     */
+    @serialize()
     public alwaysForcePOT = false;
 
+    @serialize("samples")
     private _samples = 1;
+
     /**
     * Number of sample textures (default: 1)
     */
@@ -134,6 +154,7 @@ export class PostProcess {
     /**
     * Modify the scale of the post process to be the same as the viewport (default: false)
     */
+    @serialize()
     public adaptScaleToCurrentViewport = false;
 
     private _camera: Camera;
@@ -320,48 +341,49 @@ export class PostProcess {
      * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
      */
     constructor(
-        /** Name of the PostProcess. */
-        public name: string,
+        name: string,
         fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>,
         samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE, engine?: Engine, reusable?: boolean, defines: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, vertexUrl: string = "postprocess",
         indexParameters?: any, blockCompilation = false, textureFormat = Constants.TEXTUREFORMAT_RGBA) {
-        if (camera != null) {
-            this._camera = camera;
-            this._scene = camera.getScene();
-            camera.attachPostProcess(this);
-            this._engine = this._scene.getEngine();
-
-            this._scene.postProcesses.push(this);
-            this.uniqueId = this._scene.getUniqueId();
-        }
-        else if (engine) {
-            this._engine = engine;
-            this._engine.postProcesses.push(this);
-        }
-        this._options = options;
-        this.renderTargetSamplingMode = samplingMode ? samplingMode : Constants.TEXTURE_NEAREST_SAMPLINGMODE;
-        this._reusable = reusable || false;
-        this._textureType = textureType;
-        this._textureFormat = textureFormat;
 
-        this._samplers = samplers || [];
-        this._samplers.push("textureSampler");
+                this.name = name;
+            if (camera != null) {
+                this._camera = camera;
+                this._scene = camera.getScene();
+                camera.attachPostProcess(this);
+                this._engine = this._scene.getEngine();
 
-        this._fragmentUrl = fragmentUrl;
-        this._vertexUrl = vertexUrl;
-        this._parameters = parameters || [];
+                this._scene.postProcesses.push(this);
+                this.uniqueId = this._scene.getUniqueId();
+            }
+            else if (engine) {
+                this._engine = engine;
+                this._engine.postProcesses.push(this);
+            }
+            this._options = options;
+            this.renderTargetSamplingMode = samplingMode ? samplingMode : Constants.TEXTURE_NEAREST_SAMPLINGMODE;
+            this._reusable = reusable || false;
+            this._textureType = textureType;
+            this._textureFormat = textureFormat;
 
-        this._parameters.push("scale");
+            this._samplers = samplers || [];
+            this._samplers.push("textureSampler");
 
-        this._indexParameters = indexParameters;
+            this._fragmentUrl = fragmentUrl;
+            this._vertexUrl = vertexUrl;
+            this._parameters = parameters || [];
 
-        if (!blockCompilation) {
-            this.updateEffect(defines);
-        }
+            this._parameters.push("scale");
+
+            this._indexParameters = indexParameters;
+
+            if (!blockCompilation) {
+                this.updateEffect(defines);
+            }
     }
 
     /**
-     * Gets a string idenfifying the name of the class
+     * Gets a string identifying the name of the class
      * @returns "PostProcess" string
      */
     public getClassName(): string {
@@ -697,4 +719,44 @@ export class PostProcess {
         this.onBeforeRenderObservable.clear();
         this.onSizeChangedObservable.clear();
     }
+
+    /**
+     * Serializes the particle system to a JSON object
+     * @returns the JSON object
+     */
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON." + this.getClassName();
+        serializationObject.cameraId = this.getCamera().id;
+        serializationObject.reusable = this._reusable;
+        serializationObject.options = this._options;
+        serializationObject.textureType = this._textureType;
+
+        return serializationObject;
+    }
+
+    /**
+     * Creates a material from parsed material data
+     * @param parsedPostProcess defines parsed post process data
+     * @param scene defines the hosting scene
+     * @param rootUrl defines the root URL to use to load textures
+     * @returns a new post process
+     */
+    public static Parse(parsedPostProcess: any, scene: Scene, rootUrl: string): Nullable<PostProcess> {
+        var postProcessType = _TypeStore.GetClass(parsedPostProcess.customType);
+
+        if (!postProcessType || !postProcessType._Parse) {
+            return null;
+        }
+
+        var camera = scene.getCameraByID(parsedPostProcess.cameraId);
+
+        if (!camera) {
+            return null;
+        }
+
+        return postProcessType._Parse(parsedPostProcess, camera, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.PostProcess"] = PostProcess;

+ 51 - 6
src/PostProcesses/refractionPostProcess.ts

@@ -6,6 +6,10 @@ import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Engine } from "../Engines/engine";
 
 import "../Shaders/refraction.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { SerializationHelper, serialize } from '../Misc/decorators';
+
+declare type Scene = import("../scene").Scene;
 
 /**
  * Post process which applies a refractin texture
@@ -15,6 +19,22 @@ export class RefractionPostProcess extends PostProcess {
     private _refTexture: Texture;
     private _ownRefractionTexture = true;
 
+    /** the base color of the refraction (used to taint the rendering) */
+    @serialize()
+    public color: Color3;
+
+    /** simulated refraction depth */
+    @serialize()
+    public depth: number;
+
+    /** the coefficient of the base color (0 to remove base color tainting) */
+    @serialize()
+    public colorLevel: number;
+
+    /** Gets the url used to load the refraction texture */
+    @serialize()
+    public refractionTextureUrl: string;
+
     /**
      * Gets or sets the refraction texture
      * Please note that you are responsible for disposing the texture if you set it manually
@@ -33,6 +53,14 @@ export class RefractionPostProcess extends PostProcess {
     }
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "RefractionPostProcess" string
+     */
+    public getClassName(): string {
+        return "RefractionPostProcess";
+    }
+
+    /**
      * Initializes the RefractionPostProcess
      * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#refraction
      * @param name The name of the effect.
@@ -49,12 +77,9 @@ export class RefractionPostProcess extends PostProcess {
     constructor(
         name: string,
         refractionTextureUrl: string,
-        /** the base color of the refraction (used to taint the rendering) */
-        public color: Color3,
-        /** simulated refraction depth */
-        public depth: number,
-        /** the coefficient of the base color (0 to remove base color tainting) */
-        public colorLevel: number,
+        color: Color3,
+        depth: number,
+        colorLevel: number,
         options: number | PostProcessOptions,
         camera: Camera,
         samplingMode?: number,
@@ -63,6 +88,11 @@ export class RefractionPostProcess extends PostProcess {
     ) {
         super(name, "refraction", ["baseColor", "depth", "colorLevel"], ["refractionSampler"], options, camera, samplingMode, engine, reusable);
 
+        this.color = color;
+        this.depth = depth;
+        this.colorLevel = colorLevel;
+        this.refractionTextureUrl = refractionTextureUrl;
+
         this.onActivateObservable.add((cam: Camera) => {
             this._refTexture = this._refTexture || new Texture(refractionTextureUrl, cam.getScene());
         });
@@ -89,4 +119,19 @@ export class RefractionPostProcess extends PostProcess {
 
         super.dispose(camera);
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new RefractionPostProcess(
+                parsedPostProcess.name, parsedPostProcess.refractionTextureUrl,
+                parsedPostProcess.color, parsedPostProcess.depth,
+                parsedPostProcess.colorLevel,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.RefractionPostProcess"] = RefractionPostProcess;

+ 26 - 1
src/PostProcesses/screenSpaceCurvaturePostProcess.ts

@@ -5,13 +5,15 @@ import { Effect } from "../Materials/effect";
 import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Constants } from "../Engines/constants";
 import { GeometryBufferRenderer } from "../Rendering/geometryBufferRenderer";
-import { Scene } from "../scene";
 
 import '../Rendering/geometryBufferRendererSceneComponent';
 import "../Shaders/screenSpaceCurvature.fragment";
 import { EngineStore } from '../Engines/engineStore';
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
 
 declare type Engine = import("../Engines/engine").Engine;
+declare type Scene = import("../scene").Scene;
 
 /**
  * The Screen Space curvature effect can help highlighting ridge and valley of a model.
@@ -20,16 +22,26 @@ export class ScreenSpaceCurvaturePostProcess extends PostProcess {
     /**
      * Defines how much ridge the curvature effect displays.
      */
+    @serialize()
     public ridge: number = 1;
 
     /**
      * Defines how much valley the curvature effect displays.
      */
+    @serialize()
     public valley: number = 1;
 
     private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "ScreenSpaceCurvaturePostProcess" string
+     */
+    public getClassName(): string {
+        return "ScreenSpaceCurvaturePostProcess";
+    }
+
+    /**
      * Creates a new instance ScreenSpaceCurvaturePostProcess
      * @param name The name of the effect.
      * @param scene The scene containing the objects to blur according to their velocity.
@@ -72,4 +84,17 @@ export class ScreenSpaceCurvaturePostProcess extends PostProcess {
 
         return engine.webGLVersion > 1 || engine.getCaps().drawBuffersExtension;
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new ScreenSpaceCurvaturePostProcess(
+                parsedPostProcess.name, scene,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.textureType, parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ScreenSpaceCurvaturePostProcess"] = ScreenSpaceCurvaturePostProcess;

+ 25 - 2
src/PostProcesses/screenSpaceReflectionPostProcess.ts

@@ -3,13 +3,15 @@ import { Camera } from "../Cameras/camera";
 import { Effect } from "../Materials/effect";
 import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Constants } from "../Engines/constants";
-import { Scene } from '../scene';
 import { GeometryBufferRenderer } from '../Rendering/geometryBufferRenderer';
-import { serialize } from '../Misc/decorators';
+import { serialize, SerializationHelper } from '../Misc/decorators';
 
 import "../Shaders/screenSpaceReflection.fragment";
+import { _TypeStore } from '../Misc/typeStore';
 
 declare type Engine = import("../Engines/engine").Engine;
+declare type Scene = import("../scene").Scene;
+
 /**
  * The ScreenSpaceReflectionPostProcess performs realtime reflections using only and only the available informations on the screen (positions and normals).
  * Basically, the screen space reflection post-process will compute reflections according the material's reflectivity.
@@ -47,6 +49,14 @@ export class ScreenSpaceReflectionPostProcess extends PostProcess {
     private _smoothSteps: number = 5;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "ScreenSpaceReflectionPostProcess" string
+     */
+    public getClassName(): string {
+        return "ScreenSpaceReflectionPostProcess";
+    }
+
+    /**
      * Creates a new instance of ScreenSpaceReflectionPostProcess.
      * @param name The name of the effect.
      * @param scene The scene containing the objects to calculate reflections.
@@ -194,4 +204,17 @@ export class ScreenSpaceReflectionPostProcess extends PostProcess {
 
         this.updateEffect(defines.join("\n"));
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new ScreenSpaceReflectionPostProcess(
+                parsedPostProcess.name, scene,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.textureType, parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.ScreenSpaceReflectionPostProcess"] = ScreenSpaceReflectionPostProcess;

+ 28 - 0
src/PostProcesses/sharpenPostProcess.ts

@@ -5,8 +5,12 @@ import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/sharpen.fragment";
+import { _TypeStore } from '../Misc/typeStore';
+import { serialize, SerializationHelper } from '../Misc/decorators';
 
 declare type Engine = import("../Engines/engine").Engine;
+declare type Scene = import("../scene").Scene;
+
 /**
  * The SharpenPostProcess applies a sharpen kernel to every pixel
  * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
@@ -15,11 +19,22 @@ export class SharpenPostProcess extends PostProcess {
     /**
      * How much of the original color should be applied. Setting this to 0 will display edge detection. (default: 1)
      */
+    @serialize()
     public colorAmount: number = 1.0;
     /**
      * How much sharpness should be applied (default: 0.3)
      */
+    @serialize()
     public edgeAmount: number = 0.3;
+
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "SharpenPostProcess" string
+     */
+    public getClassName(): string {
+        return "SharpenPostProcess";
+    }
+
     /**
      * Creates a new instance ConvolutionPostProcess
      * @param name The name of the effect.
@@ -39,4 +54,17 @@ export class SharpenPostProcess extends PostProcess {
             effect.setFloat2("sharpnessAmounts", this.edgeAmount, this.colorAmount);
         };
     }
+
+    /** @hidden */
+    public static _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {
+        return SerializationHelper.Parse(() => {
+            return new SharpenPostProcess(
+                parsedPostProcess.name,
+                parsedPostProcess.options, targetCamera,
+                parsedPostProcess.renderTargetSamplingMode,
+                scene.getEngine(), parsedPostProcess.textureType, parsedPostProcess.reusable);
+        }, parsedPostProcess, scene, rootUrl);
+    }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.SharpenPostProcess"] = SharpenPostProcess;

+ 16 - 0
src/PostProcesses/stereoscopicInterlacePostProcess.ts

@@ -15,6 +15,14 @@ export class StereoscopicInterlacePostProcessI extends PostProcess {
     private _passedProcess: Nullable<PostProcess>;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "StereoscopicInterlacePostProcessI" string
+     */
+    public getClassName(): string {
+        return "StereoscopicInterlacePostProcessI";
+    }
+
+    /**
      * Initializes a StereoscopicInterlacePostProcessI
      * @param name The name of the effect.
      * @param rigCameras The rig cameras to be appled to the post process
@@ -47,6 +55,14 @@ export class StereoscopicInterlacePostProcess extends PostProcess {
     private _passedProcess: Nullable<PostProcess>;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "StereoscopicInterlacePostProcess" string
+     */
+    public getClassName(): string {
+        return "StereoscopicInterlacePostProcess";
+    }
+
+    /**
      * Initializes a StereoscopicInterlacePostProcess
      * @param name The name of the effect.
      * @param rigCameras The rig cameras to be appled to the post process

+ 7 - 5
src/PostProcesses/subSurfaceScatteringPostProcess.ts

@@ -16,10 +16,13 @@ import "../Shaders/postprocess.vertex";
  * Sub surface scattering post process
  */
 export class SubSurfaceScatteringPostProcess extends PostProcess {
-    /** @hidden */
-    public texelWidth: number;
-    /** @hidden */
-    public texelHeight: number;
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "SubSurfaceScatteringPostProcess" string
+     */
+    public getClassName(): string {
+        return "SubSurfaceScatteringPostProcess";
+    }
 
     constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(name, "subSurfaceScattering", ["texelSize", "viewportSize", "metersPerUnit"], ["diffusionS", "diffusionD", "filterRadii", "irradianceSampler", "depthSampler", "albedoSampler"], options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
@@ -45,6 +48,5 @@ export class SubSurfaceScatteringPostProcess extends PostProcess {
             effect.setArray("diffusionD", scene.prePassRenderer.subSurfaceConfiguration.ssDiffusionD);
             effect.setArray("filterRadii", scene.prePassRenderer.subSurfaceConfiguration.ssFilterRadii);
         });
-
     }
 }

+ 7 - 0
src/PostProcesses/tonemapPostProcess.ts

@@ -23,6 +23,13 @@ export enum TonemappingOperator {
  * Defines a post process to apply tone mapping
  */
 export class TonemapPostProcess extends PostProcess {
+    /**
+     * Gets a string identifying the name of the class
+     * @returns "TonemapPostProcess" string
+     */
+    public getClassName(): string {
+        return "TonemapPostProcess";
+    }
 
     /**
      * Creates a new TonemapPostProcess

+ 3 - 0
src/PostProcesses/volumetricLightScatteringPostProcess.ts

@@ -25,6 +25,7 @@ import "../Shaders/volumetricLightScatteringPass.vertex";
 import "../Shaders/volumetricLightScatteringPass.fragment";
 import { Color4, Color3 } from '../Maths/math.color';
 import { Viewport } from '../Maths/math.viewport';
+import { _TypeStore } from '../Misc/typeStore';
 
 declare type Engine = import("../Engines/engine").Engine;
 
@@ -484,3 +485,5 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
         return mesh;
     }
 }
+
+_TypeStore.RegisteredTypes["BABYLON.VolumetricLightScatteringPostProcess"] = VolumetricLightScatteringPostProcess;

+ 8 - 0
src/PostProcesses/vrDistortionCorrectionPostProcess.ts

@@ -20,6 +20,14 @@ export class VRDistortionCorrectionPostProcess extends PostProcess {
     private _lensCenter: Vector2;
 
     /**
+     * Gets a string identifying the name of the class
+     * @returns "VRDistortionCorrectionPostProcess" string
+     */
+    public getClassName(): string {
+        return "VRDistortionCorrectionPostProcess";
+    }
+
+    /**
      * Initializes the VRDistortionCorrectionPostProcess
      * @param name The name of the effect.
      * @param camera The camera to apply the render pass to.

+ 8 - 0
src/PostProcesses/vrMultiviewToSingleviewPostProcess.ts

@@ -12,6 +12,14 @@ import "../Engines/Extensions/engine.multiview";
  */
 export class VRMultiviewToSingleviewPostProcess extends PostProcess {
     /**
+     * Gets a string identifying the name of the class
+     * @returns "VRMultiviewToSingleviewPostProcess" string
+     */
+    public getClassName(): string {
+        return "VRMultiviewToSingleviewPostProcess";
+    }
+
+    /**
      * Initializes a VRMultiviewToSingleview
      * @param name name of the post process
      * @param camera camera to be applied to

+ 6 - 0
src/abstractScene.ts

@@ -17,6 +17,7 @@ import { Light } from "./Lights/light";
 import { Node } from "./node";
 
 declare type Animation = import("./Animations/animation").Animation;
+declare type PostProcess = import("./PostProcesses/postProcess").PostProcess;
 
 /**
  * Defines how the parser contract is defined.
@@ -200,6 +201,11 @@ export abstract class AbstractScene {
     public environmentTexture: Nullable<BaseTexture> = null;
 
     /**
+     * The list of postprocesses added to the scene
+     */
+    public postProcesses = new Array<PostProcess>();
+
+    /**
      * @returns all meshes, lights, cameras, transformNodes and bones
      */
     public getNodes(): Array<Node> {

+ 1 - 1
src/node.ts

@@ -254,7 +254,7 @@ export class Node implements IBehaviorAware<Node> {
     }
 
     /**
-     * Gets a string idenfifying the name of the class
+     * Gets a string identifying the name of the class
      * @returns "Node" string
      */
     public getClassName(): string {

+ 23 - 10
src/scene.ts

@@ -32,7 +32,6 @@ import { ICollisionCoordinator } from "./Collisions/collisionCoordinator";
 import { PointerEventTypes, PointerInfoPre, PointerInfo } from "./Events/pointerEvents";
 import { KeyboardInfoPre, KeyboardInfo } from "./Events/keyboardEvents";
 import { ActionEvent } from "./Actions/actionEvent";
-import { PostProcess } from "./PostProcesses/postProcess";
 import { PostProcessManager } from "./PostProcesses/postProcessManager";
 import { IOfflineProvider } from "./Offline/IOfflineProvider";
 import { RenderingGroupInfo, RenderingManager, IRenderingManagerAutoClearSetup } from "./Rendering/renderingManager";
@@ -64,6 +63,7 @@ declare type Animatable = import("./Animations/animatable").Animatable;
 declare type AnimationGroup = import("./Animations/animationGroup").AnimationGroup;
 declare type AnimationPropertiesOverride = import("./Animations/animationPropertiesOverride").AnimationPropertiesOverride;
 declare type Collider = import("./Collisions/collider").Collider;
+declare type PostProcess = import("./PostProcesses/postProcess").PostProcess;
 
 /**
  * Define an interface for all classes that will hold resources
@@ -1046,10 +1046,6 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
     */
     public postProcessesEnabled = true;
     /**
-     * The list of postprocesses added to the scene
-     */
-    public postProcesses = new Array<PostProcess>();
-    /**
      * Gets the current postprocess manager
      */
     public postProcessManager: PostProcessManager;
@@ -1436,7 +1432,7 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
     }
 
     /**
-     * Gets a string idenfifying the name of the class
+     * Gets a string identifying the name of the class
      * @returns "Scene" string
      */
     public getClassName(): string {
@@ -2872,10 +2868,12 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
 
         if (index !== this.geometries.length - 1) {
             const lastGeometry = this.geometries[this.geometries.length - 1];
-            this.geometries[index] = lastGeometry;
-            if (this.geometriesByUniqueId) {
-                this.geometriesByUniqueId[lastGeometry.uniqueId] = index;
-                this.geometriesByUniqueId[geometry.uniqueId] = undefined;
+            if (lastGeometry) {
+                this.geometries[index] = lastGeometry;
+                if (this.geometriesByUniqueId) {
+                    this.geometriesByUniqueId[lastGeometry.uniqueId] = index;
+                    this.geometriesByUniqueId[geometry.uniqueId] = undefined;
+                }
             }
         }
 
@@ -3234,6 +3232,21 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
     }
 
     /**
+     * Gets a post process using a given name (if many are found, this function will pick the first one)
+     * @param name defines the name to search for
+     * @return the found post process or null if not found at all.
+     */
+    public getPostProcessByName(name: string): Nullable<PostProcess> {
+        for (let postProcessIndex = 0; postProcessIndex < this.postProcesses.length; ++postProcessIndex) {
+            const postProcess = this.postProcesses[postProcessIndex];
+            if (postProcess.name === name) {
+                return postProcess;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Gets a boolean indicating if the given mesh is active
      * @param mesh defines the mesh to look for
      * @returns true if the mesh is in the active list

文件差异内容过多而无法显示
+ 2 - 2
tests/es6Modules/webpack-stats.json