فهرست منبع

Merge pull request #7781 from BabylonJS/master

4.2.0-alpha.1
sebavan 5 سال پیش
والد
کامیت
c3c24dbdb0
44فایلهای تغییر یافته به همراه1240 افزوده شده و 680 حذف شده
  1. 73 33
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 371 262
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 146 66
      dist/preview release/babylon.module.d.ts
  6. 1 1
      dist/preview release/glTF2Interface/package.json
  7. 2 2
      dist/preview release/gui/package.json
  8. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  9. 97 56
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  10. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  11. 9 0
      dist/preview release/inspector/babylon.inspector.d.ts
  12. 18 0
      dist/preview release/inspector/babylon.inspector.module.d.ts
  13. 7 7
      dist/preview release/inspector/package.json
  14. 1 1
      dist/preview release/loaders/babylonjs.loaders.js
  15. 3 3
      dist/preview release/loaders/package.json
  16. 2 2
      dist/preview release/materialsLibrary/package.json
  17. 2 2
      dist/preview release/nodeEditor/package.json
  18. 1 1
      dist/preview release/package.json
  19. 2 2
      dist/preview release/postProcessesLibrary/package.json
  20. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  21. 3 3
      dist/preview release/serializers/package.json
  22. 146 66
      dist/preview release/viewer/babylon.module.d.ts
  23. 14 14
      dist/preview release/viewer/babylon.viewer.js
  24. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  25. 6 0
      dist/preview release/what's new.md
  26. 22 11
      inspector/src/components/actionTabs/lines/color3LineComponent.tsx
  27. 33 15
      inspector/src/components/actionTabs/lines/color4LineComponent.tsx
  28. 30 19
      inspector/src/components/actionTabs/lines/optionsLineComponent.tsx
  29. 11 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx
  30. 8 8
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx
  31. 2 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMetallicRoughnessMaterialPropertyGridComponent.tsx
  32. 2 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrSpecularGlossinessMaterialPropertyGridComponent.tsx
  33. 1 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/standardMaterialPropertyGridComponent.tsx
  34. 1 0
      inspector/src/components/propertyChangedEvent.ts
  35. 20 12
      inspector/src/components/replayRecorder.ts
  36. 1 1
      package.json
  37. 22 2
      src/Cameras/Inputs/freeCameraKeyboardMoveInput.ts
  38. 38 0
      src/Cameras/freeCamera.ts
  39. 2 2
      src/Engines/thinEngine.ts
  40. 1 1
      src/Materials/Node/Blocks/Dual/textureBlock.ts
  41. 5 53
      src/Materials/PBR/pbrBaseMaterial.ts
  42. 92 10
      src/Materials/material.ts
  43. 19 4
      src/Materials/standardMaterial.ts
  44. 12 1
      src/Shaders/default.fragment.fx

+ 73 - 33
dist/preview release/babylon.d.ts

@@ -8754,10 +8754,18 @@ declare module BABYLON {
          */
         keysUp: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        keysUpward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         keysDown: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+         */
+        keysDownward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         keysLeft: number[];
@@ -18392,11 +18400,21 @@ declare module BABYLON {
         get keysUp(): number[];
         set keysUp(value: number[]);
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        get keysUpward(): number[];
+        set keysUpward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         get keysDown(): number[];
         set keysDown(value: number[]);
         /**
+        * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+        */
+        get keysDownward(): number[];
+        set keysDownward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         get keysLeft(): number[];
@@ -20878,6 +20896,23 @@ declare module BABYLON {
          */
         static readonly AllDirtyFlag: number;
         /**
+         * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+         */
+        static readonly MATERIAL_OPAQUE: number;
+        /**
+         * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+         */
+        static readonly MATERIAL_ALPHATEST: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         */
+        static readonly MATERIAL_ALPHABLEND: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         * They are also discarded below the alpha cutoff threshold to improve performances.
+         */
+        static readonly MATERIAL_ALPHATESTANDBLEND: number;
+        /**
          * The ID of the material
          */
         id: string;
@@ -21190,7 +21225,35 @@ declare module BABYLON {
          */
         getScene(): Scene;
         /**
-         * Specifies if the material will require alpha blending
+         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+         */
+        protected _forceAlphaTest: boolean;
+        /**
+         * The transparency mode of the material.
+         */
+        protected _transparencyMode: Nullable<number>;
+        /**
+         * Gets the current transparency mode.
+         */
+        get transparencyMode(): Nullable<number>;
+        /**
+         * Sets the transparency mode of the material.
+         *
+         * | Value | Type                                | Description |
+         * | ----- | ----------------------------------- | ----------- |
+         * | 0     | OPAQUE                              |             |
+         * | 1     | ALPHATEST                           |             |
+         * | 2     | ALPHABLEND                          |             |
+         * | 3     | ALPHATESTANDBLEND                   |             |
+         *
+         */
+        set transparencyMode(value: Nullable<number>);
+        /**
+         * Returns true if alpha blending should be disabled.
+         */
+        protected get _disableAlphaBlending(): boolean;
+        /**
+         * Specifies whether or not this material should be rendered in alpha blend mode.
          * @returns a boolean specifying if alpha blending is needed
          */
         needAlphaBlending(): boolean;
@@ -21201,11 +21264,16 @@ declare module BABYLON {
          */
         needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
         /**
-         * Specifies if this material should be rendered in alpha test mode
+         * Specifies whether or not this material should be rendered in alpha test mode.
          * @returns a boolean specifying if an alpha test is needed.
          */
         needAlphaTesting(): boolean;
         /**
+         * Specifies if material alpha testing should be turned on for the mesh
+         * @param mesh defines the mesh to check
+         */
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
+        /**
          * Gets the texture used for the alpha test
          * @returns the texture to use for alpha testing
          */
@@ -21251,11 +21319,6 @@ declare module BABYLON {
          */
         bindViewProjection(effect: Effect): void;
         /**
-         * Specifies if material alpha testing should be turned on for the mesh
-         * @param mesh defines the mesh to check
-         */
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        /**
          * Processes to execute after binding the material to a mesh
          * @param mesh defines the rendered mesh
          */
@@ -26411,6 +26474,8 @@ declare module BABYLON {
         NUM_MORPH_INFLUENCERS: number;
         NONUNIFORMSCALING: boolean;
         PREMULTIPLYALPHA: boolean;
+        ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
+        ALPHABLEND: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -51362,10 +51427,6 @@ declare module BABYLON {
          */
         protected _useLinearAlphaFresnel: boolean;
         /**
-         * The transparency mode of the material.
-         */
-        protected _transparencyMode: Nullable<number>;
-        /**
          * Specifies the environment BRDF texture used to comput the scale and offset roughness values
          * from cos thetav and roughness:
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -51487,35 +51548,14 @@ declare module BABYLON {
          */
         set useLogarithmicDepth(value: boolean);
         /**
-         * Gets the current transparency mode.
-         */
-        get transparencyMode(): Nullable<number>;
-        /**
-         * Sets the transparency mode of the material.
-         *
-         * | Value | Type                                | Description |
-         * | ----- | ----------------------------------- | ----------- |
-         * | 0     | OPAQUE                              |             |
-         * | 1     | ALPHATEST                           |             |
-         * | 2     | ALPHABLEND                          |             |
-         * | 3     | ALPHATESTANDBLEND                   |             |
-         *
-         */
-        set transparencyMode(value: Nullable<number>);
-        /**
          * Returns true if alpha blending should be disabled.
          */
-        private get _disableAlphaBlending();
+        protected get _disableAlphaBlending(): boolean;
         /**
          * Specifies whether or not this material should be rendered in alpha blend mode.
          */
         needAlphaBlending(): boolean;
         /**
-         * Specifies if the mesh will require alpha blending.
-         * @param mesh - BJS mesh.
-         */
-        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
-        /**
          * Specifies whether or not this material should be rendered in alpha test mode.
          */
         needAlphaTesting(): boolean;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 2
dist/preview release/babylon.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 371 - 262
dist/preview release/babylon.max.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 146 - 66
dist/preview release/babylon.module.d.ts

@@ -8868,10 +8868,18 @@ declare module "babylonjs/Cameras/Inputs/freeCameraKeyboardMoveInput" {
          */
         keysUp: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        keysUpward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         keysDown: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+         */
+        keysDownward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         keysLeft: number[];
@@ -18909,11 +18917,21 @@ declare module "babylonjs/Cameras/freeCamera" {
         get keysUp(): number[];
         set keysUp(value: number[]);
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        get keysUpward(): number[];
+        set keysUpward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         get keysDown(): number[];
         set keysDown(value: number[]);
         /**
+        * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+        */
+        get keysDownward(): number[];
+        set keysDownward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         get keysLeft(): number[];
@@ -21529,6 +21547,23 @@ declare module "babylonjs/Materials/material" {
          */
         static readonly AllDirtyFlag: number;
         /**
+         * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+         */
+        static readonly MATERIAL_OPAQUE: number;
+        /**
+         * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+         */
+        static readonly MATERIAL_ALPHATEST: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         */
+        static readonly MATERIAL_ALPHABLEND: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         * They are also discarded below the alpha cutoff threshold to improve performances.
+         */
+        static readonly MATERIAL_ALPHATESTANDBLEND: number;
+        /**
          * The ID of the material
          */
         id: string;
@@ -21841,7 +21876,35 @@ declare module "babylonjs/Materials/material" {
          */
         getScene(): Scene;
         /**
-         * Specifies if the material will require alpha blending
+         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+         */
+        protected _forceAlphaTest: boolean;
+        /**
+         * The transparency mode of the material.
+         */
+        protected _transparencyMode: Nullable<number>;
+        /**
+         * Gets the current transparency mode.
+         */
+        get transparencyMode(): Nullable<number>;
+        /**
+         * Sets the transparency mode of the material.
+         *
+         * | Value | Type                                | Description |
+         * | ----- | ----------------------------------- | ----------- |
+         * | 0     | OPAQUE                              |             |
+         * | 1     | ALPHATEST                           |             |
+         * | 2     | ALPHABLEND                          |             |
+         * | 3     | ALPHATESTANDBLEND                   |             |
+         *
+         */
+        set transparencyMode(value: Nullable<number>);
+        /**
+         * Returns true if alpha blending should be disabled.
+         */
+        protected get _disableAlphaBlending(): boolean;
+        /**
+         * Specifies whether or not this material should be rendered in alpha blend mode.
          * @returns a boolean specifying if alpha blending is needed
          */
         needAlphaBlending(): boolean;
@@ -21852,11 +21915,16 @@ declare module "babylonjs/Materials/material" {
          */
         needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
         /**
-         * Specifies if this material should be rendered in alpha test mode
+         * Specifies whether or not this material should be rendered in alpha test mode.
          * @returns a boolean specifying if an alpha test is needed.
          */
         needAlphaTesting(): boolean;
         /**
+         * Specifies if material alpha testing should be turned on for the mesh
+         * @param mesh defines the mesh to check
+         */
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
+        /**
          * Gets the texture used for the alpha test
          * @returns the texture to use for alpha testing
          */
@@ -21902,11 +21970,6 @@ declare module "babylonjs/Materials/material" {
          */
         bindViewProjection(effect: Effect): void;
         /**
-         * Specifies if material alpha testing should be turned on for the mesh
-         * @param mesh defines the mesh to check
-         */
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        /**
          * Processes to execute after binding the material to a mesh
          * @param mesh defines the rendered mesh
          */
@@ -27247,6 +27310,8 @@ declare module "babylonjs/Materials/standardMaterial" {
         NUM_MORPH_INFLUENCERS: number;
         NONUNIFORMSCALING: boolean;
         PREMULTIPLYALPHA: boolean;
+        ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
+        ALPHABLEND: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -53568,10 +53633,6 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
          */
         protected _useLinearAlphaFresnel: boolean;
         /**
-         * The transparency mode of the material.
-         */
-        protected _transparencyMode: Nullable<number>;
-        /**
          * Specifies the environment BRDF texture used to comput the scale and offset roughness values
          * from cos thetav and roughness:
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -53693,35 +53754,14 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
          */
         set useLogarithmicDepth(value: boolean);
         /**
-         * Gets the current transparency mode.
-         */
-        get transparencyMode(): Nullable<number>;
-        /**
-         * Sets the transparency mode of the material.
-         *
-         * | Value | Type                                | Description |
-         * | ----- | ----------------------------------- | ----------- |
-         * | 0     | OPAQUE                              |             |
-         * | 1     | ALPHATEST                           |             |
-         * | 2     | ALPHABLEND                          |             |
-         * | 3     | ALPHATESTANDBLEND                   |             |
-         *
-         */
-        set transparencyMode(value: Nullable<number>);
-        /**
          * Returns true if alpha blending should be disabled.
          */
-        private get _disableAlphaBlending();
+        protected get _disableAlphaBlending(): boolean;
         /**
          * Specifies whether or not this material should be rendered in alpha blend mode.
          */
         needAlphaBlending(): boolean;
         /**
-         * Specifies if the mesh will require alpha blending.
-         * @param mesh - BJS mesh.
-         */
-        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
-        /**
          * Specifies whether or not this material should be rendered in alpha test mode.
          */
         needAlphaTesting(): boolean;
@@ -82256,10 +82296,18 @@ declare module BABYLON {
          */
         keysUp: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        keysUpward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         keysDown: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+         */
+        keysDownward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         keysLeft: number[];
@@ -91894,11 +91942,21 @@ declare module BABYLON {
         get keysUp(): number[];
         set keysUp(value: number[]);
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        get keysUpward(): number[];
+        set keysUpward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         get keysDown(): number[];
         set keysDown(value: number[]);
         /**
+        * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+        */
+        get keysDownward(): number[];
+        set keysDownward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         get keysLeft(): number[];
@@ -94380,6 +94438,23 @@ declare module BABYLON {
          */
         static readonly AllDirtyFlag: number;
         /**
+         * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+         */
+        static readonly MATERIAL_OPAQUE: number;
+        /**
+         * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+         */
+        static readonly MATERIAL_ALPHATEST: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         */
+        static readonly MATERIAL_ALPHABLEND: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         * They are also discarded below the alpha cutoff threshold to improve performances.
+         */
+        static readonly MATERIAL_ALPHATESTANDBLEND: number;
+        /**
          * The ID of the material
          */
         id: string;
@@ -94692,7 +94767,35 @@ declare module BABYLON {
          */
         getScene(): Scene;
         /**
-         * Specifies if the material will require alpha blending
+         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+         */
+        protected _forceAlphaTest: boolean;
+        /**
+         * The transparency mode of the material.
+         */
+        protected _transparencyMode: Nullable<number>;
+        /**
+         * Gets the current transparency mode.
+         */
+        get transparencyMode(): Nullable<number>;
+        /**
+         * Sets the transparency mode of the material.
+         *
+         * | Value | Type                                | Description |
+         * | ----- | ----------------------------------- | ----------- |
+         * | 0     | OPAQUE                              |             |
+         * | 1     | ALPHATEST                           |             |
+         * | 2     | ALPHABLEND                          |             |
+         * | 3     | ALPHATESTANDBLEND                   |             |
+         *
+         */
+        set transparencyMode(value: Nullable<number>);
+        /**
+         * Returns true if alpha blending should be disabled.
+         */
+        protected get _disableAlphaBlending(): boolean;
+        /**
+         * Specifies whether or not this material should be rendered in alpha blend mode.
          * @returns a boolean specifying if alpha blending is needed
          */
         needAlphaBlending(): boolean;
@@ -94703,11 +94806,16 @@ declare module BABYLON {
          */
         needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
         /**
-         * Specifies if this material should be rendered in alpha test mode
+         * Specifies whether or not this material should be rendered in alpha test mode.
          * @returns a boolean specifying if an alpha test is needed.
          */
         needAlphaTesting(): boolean;
         /**
+         * Specifies if material alpha testing should be turned on for the mesh
+         * @param mesh defines the mesh to check
+         */
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
+        /**
          * Gets the texture used for the alpha test
          * @returns the texture to use for alpha testing
          */
@@ -94753,11 +94861,6 @@ declare module BABYLON {
          */
         bindViewProjection(effect: Effect): void;
         /**
-         * Specifies if material alpha testing should be turned on for the mesh
-         * @param mesh defines the mesh to check
-         */
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        /**
          * Processes to execute after binding the material to a mesh
          * @param mesh defines the rendered mesh
          */
@@ -99913,6 +100016,8 @@ declare module BABYLON {
         NUM_MORPH_INFLUENCERS: number;
         NONUNIFORMSCALING: boolean;
         PREMULTIPLYALPHA: boolean;
+        ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
+        ALPHABLEND: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -124864,10 +124969,6 @@ declare module BABYLON {
          */
         protected _useLinearAlphaFresnel: boolean;
         /**
-         * The transparency mode of the material.
-         */
-        protected _transparencyMode: Nullable<number>;
-        /**
          * Specifies the environment BRDF texture used to comput the scale and offset roughness values
          * from cos thetav and roughness:
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -124989,35 +125090,14 @@ declare module BABYLON {
          */
         set useLogarithmicDepth(value: boolean);
         /**
-         * Gets the current transparency mode.
-         */
-        get transparencyMode(): Nullable<number>;
-        /**
-         * Sets the transparency mode of the material.
-         *
-         * | Value | Type                                | Description |
-         * | ----- | ----------------------------------- | ----------- |
-         * | 0     | OPAQUE                              |             |
-         * | 1     | ALPHATEST                           |             |
-         * | 2     | ALPHABLEND                          |             |
-         * | 3     | ALPHATESTANDBLEND                   |             |
-         *
-         */
-        set transparencyMode(value: Nullable<number>);
-        /**
          * Returns true if alpha blending should be disabled.
          */
-        private get _disableAlphaBlending();
+        protected get _disableAlphaBlending(): boolean;
         /**
          * Specifies whether or not this material should be rendered in alpha blend mode.
          */
         needAlphaBlending(): boolean;
         /**
-         * Specifies if the mesh will require alpha blending.
-         * @param mesh - BJS mesh.
-         */
-        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
-        /**
          * Specifies whether or not this material should be rendered in alpha test mode.
          */
         needAlphaTesting(): boolean;

+ 1 - 1
dist/preview release/glTF2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 6 - 6
dist/preview release/inspector/babylon.inspector.bundle.js


+ 97 - 56
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -39738,10 +39738,14 @@ var Color3LineComponent = /** @class */ (function (_super) {
         var _this = _super.call(this, props) || this;
         _this._localChange = false;
         _this.state = { isExpanded: false, color: _this.props.target[_this.props.propertyName].clone() };
+        if (props.isLinear) {
+            _this.state.color.toGammaSpaceToRef(_this.state.color);
+        }
+        props.target._isLinearColor = props.isLinear; // so that replayRecorder can append toLinearSpace() as appropriate
         return _this;
     }
     Color3LineComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
-        var currentState = nextProps.target[nextProps.propertyName];
+        var currentState = this.props.isLinear ? nextProps.target[nextProps.propertyName].toGammaSpace() : nextProps.target[nextProps.propertyName];
         if (!currentState.equals(nextState.color) || this._localChange) {
             nextState.color = currentState.clone();
             this._localChange = false;
@@ -39749,6 +39753,12 @@ var Color3LineComponent = /** @class */ (function (_super) {
         }
         return false;
     };
+    Color3LineComponent.prototype.setPropertyValue = function (newColor) {
+        this.props.target[this.props.propertyName] = newColor;
+        if (this.props.isLinear) {
+            this.props.target[this.props.propertyName] = newColor.toLinearSpace();
+        }
+    };
     Color3LineComponent.prototype.onChange = function (newValue) {
         this._localChange = true;
         var newColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"].FromHexString(newValue);
@@ -39757,10 +39767,10 @@ var Color3LineComponent = /** @class */ (function (_super) {
                 object: this.props.target,
                 property: this.props.propertyName,
                 value: newColor,
-                initialValue: this.state.color
+                initialValue: this.state.color,
             });
         }
-        this.props.target[this.props.propertyName] = newColor;
+        this.setPropertyValue(newColor);
         this.setState({ color: newColor });
     };
     Color3LineComponent.prototype.switchExpandState = function () {
@@ -39775,33 +39785,30 @@ var Color3LineComponent = /** @class */ (function (_super) {
             object: this.props.target,
             property: this.props.propertyName,
             value: this.state.color,
-            initialValue: previousValue
+            initialValue: previousValue,
         });
     };
     Color3LineComponent.prototype.updateStateR = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].x = value;
         this.state.color.r = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
     Color3LineComponent.prototype.updateStateG = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].g = value;
         this.state.color.g = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
     Color3LineComponent.prototype.updateStateB = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].b = value;
         this.state.color.b = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
@@ -39876,11 +39883,18 @@ var Color4LineComponent = /** @class */ (function (_super) {
         var value = _this.props.target[_this.props.propertyName];
         var currentColor = value.getClassName() === "Color4" ? value.clone() : new babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](value.r, value.g, value.b, 1.0);
         _this.state = { isExpanded: false, color: currentColor };
+        if (props.isLinear) {
+            _this.state.color.toGammaSpaceToRef(_this.state.color);
+        }
+        props.target._isLinearColor = props.isLinear; // so that replayRecorder can append toLinearSpace() as appropriate
         return _this;
     }
     Color4LineComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
         var value = this.props.target[this.props.propertyName];
         var currentColor = value.getClassName() === "Color4" ? value : new babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](value.r, value.g, value.b, 1.0);
+        if (this.props.isLinear) {
+            currentColor.toGammaSpaceRef(currentColor);
+        }
         if (!currentColor.equals(nextState.color) || this._localChange) {
             nextState.color = currentColor.clone();
             this._localChange = false;
@@ -39888,6 +39902,12 @@ var Color4LineComponent = /** @class */ (function (_super) {
         }
         return false;
     };
+    Color4LineComponent.prototype.setPropertyValue = function (newColor) {
+        this.props.target[this.props.propertyName] = newColor;
+        if (this.props.isLinear) {
+            this.props.target[this.props.propertyName] = newColor.toLinearSpace();
+        }
+    };
     Color4LineComponent.prototype.onChange = function (newValue) {
         this._localChange = true;
         var newColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].FromHexString(newValue);
@@ -39896,11 +39916,12 @@ var Color4LineComponent = /** @class */ (function (_super) {
                 object: this.props.target,
                 property: this.props.propertyName,
                 value: newColor,
-                initialValue: this.state.color
+                initialValue: this.state.color,
             });
         }
-        this.props.target[this.props.propertyName] = new babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
-        this.setState({ color: this.props.target[this.props.propertyName] });
+        var newColor4 = new babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+        this.setPropertyValue(newColor4);
+        this.setState({ color: newColor4 });
         if (this.props.onChange) {
             this.props.onChange();
         }
@@ -39917,33 +39938,30 @@ var Color4LineComponent = /** @class */ (function (_super) {
             object: this.props.target,
             property: this.props.propertyName,
             value: this.state.color,
-            initialValue: previousValue
+            initialValue: previousValue,
         });
     };
     Color4LineComponent.prototype.updateStateR = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].x = value;
         this.state.color.r = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
     Color4LineComponent.prototype.updateStateG = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].g = value;
         this.state.color.g = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
     Color4LineComponent.prototype.updateStateB = function (value) {
         this._localChange = true;
         var store = this.state.color.clone();
-        this.props.target[this.props.propertyName].b = value;
         this.state.color.b = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
         this.raiseOnPropertyChanged(store);
     };
@@ -40388,17 +40406,19 @@ var NumericInputComponent = /** @class */ (function (_super) {
 /*!**************************************************************!*\
   !*** ./components/actionTabs/lines/optionsLineComponent.tsx ***!
   \**************************************************************/
-/*! exports provided: OptionsLineComponent */
+/*! exports provided: Null_Value, OptionsLineComponent */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Null_Value", function() { return Null_Value; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OptionsLineComponent", function() { return OptionsLineComponent; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 
 
+var Null_Value = Number.MAX_SAFE_INTEGER;
 var ListLineOption = /** @class */ (function () {
     function ListLineOption() {
     }
@@ -40409,15 +40429,21 @@ var OptionsLineComponent = /** @class */ (function (_super) {
     function OptionsLineComponent(props) {
         var _this = _super.call(this, props) || this;
         _this._localChange = false;
-        _this.state = { value: _this.props.extractValue ? _this.props.extractValue() : props.target[props.propertyName] };
+        _this.state = { value: _this.remapValueIn(_this.props.extractValue ? _this.props.extractValue() : props.target[props.propertyName]) };
         return _this;
     }
+    OptionsLineComponent.prototype.remapValueIn = function (value) {
+        return this.props.allowNullValue && value === null ? Null_Value : value;
+    };
+    OptionsLineComponent.prototype.remapValueOut = function (value) {
+        return this.props.allowNullValue && value === Null_Value ? null : value;
+    };
     OptionsLineComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
         if (this._localChange) {
             this._localChange = false;
             return true;
         }
-        var newValue = nextProps.extractValue ? nextProps.extractValue() : nextProps.target[nextProps.propertyName];
+        var newValue = this.remapValueIn(nextProps.extractValue ? nextProps.extractValue() : nextProps.target[nextProps.propertyName]);
         if (newValue != null && newValue !== nextState.value) {
             nextState.value = newValue;
             return true;
@@ -40432,7 +40458,8 @@ var OptionsLineComponent = /** @class */ (function (_super) {
             object: this.props.target,
             property: this.props.propertyName,
             value: newValue,
-            initialValue: previousValue
+            initialValue: previousValue,
+            allowNullValue: this.props.allowNullValue,
         });
     };
     OptionsLineComponent.prototype.updateValue = function (valueString) {
@@ -40440,7 +40467,7 @@ var OptionsLineComponent = /** @class */ (function (_super) {
         this._localChange = true;
         var store = this.props.extractValue ? this.props.extractValue() : this.props.target[this.props.propertyName];
         if (!this.props.noDirectUpdate) {
-            this.props.target[this.props.propertyName] = value;
+            this.props.target[this.props.propertyName] = this.remapValueOut(value);
         }
         this.setState({ value: value });
         if (this.props.onSelect) {
@@ -44117,6 +44144,7 @@ var CommonMaterialPropertyGridComponent = /** @class */ (function (_super) {
             { label: "Counterclockwise", value: babylonjs_Materials_material__WEBPACK_IMPORTED_MODULE_2__["Material"].CounterClockWiseSideOrientation }
         ];
         var transparencyModeOptions = [
+            { label: "<Not Defined>", value: _lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_7__["Null_Value"] },
             { label: "Opaque", value: babylonjs_Materials_material__WEBPACK_IMPORTED_MODULE_2__["PBRMaterial"].PBRMATERIAL_OPAQUE },
             { label: "Alpha test", value: babylonjs_Materials_material__WEBPACK_IMPORTED_MODULE_2__["PBRMaterial"].PBRMATERIAL_ALPHATEST },
             { label: "Alpha blend", value: babylonjs_Materials_material__WEBPACK_IMPORTED_MODULE_2__["PBRMaterial"].PBRMATERIAL_ALPHABLEND },
@@ -44165,8 +44193,12 @@ var CommonMaterialPropertyGridComponent = /** @class */ (function (_super) {
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_5__["LineContainerComponent"], { globalState: this.props.globalState, title: "TRANSPARENCY" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_4__["SliderLineComponent"], { label: "Alpha", target: material, propertyName: "alpha", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 material.transparencyMode !== undefined &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_7__["OptionsLineComponent"], { label: "Transparency mode", options: transparencyModeOptions, target: material, propertyName: "transparencyMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ transparencyMode: value }); } }),
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_7__["OptionsLineComponent"], { allowNullValue: true, label: "Transparency mode", options: transparencyModeOptions, target: material, propertyName: "transparencyMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ transparencyMode: value }); } }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_7__["OptionsLineComponent"], { label: "Alpha mode", options: alphaModeOptions, target: material, propertyName: "alphaMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ alphaMode: value }); } }),
+                material.useAlphaFromDiffuseTexture !== undefined &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Use alpha from diffuse texture", target: material, propertyName: "useAlphaFromDiffuseTexture", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                material.useAlphaFromAlbedoTexture !== undefined &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Use alpha from albedo texture", target: material, propertyName: "useAlphaFromAlbedoTexture", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Separate culling pass", target: material, propertyName: "separateCullingPass", onPropertyChangedObservable: this.props.onPropertyChangedObservable }))));
     };
     return CommonMaterialPropertyGridComponent;
@@ -44545,11 +44577,11 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_9__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
             this.renderTextures(this._onDebugSelectionChangeObservable),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LIGHTING & COLORS" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Albedo", target: material, propertyName: "albedoColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Reflectivity", target: material, propertyName: "reflectivityColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Albedo", target: material, propertyName: "albedoColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Reflectivity", target: material, propertyName: "reflectivityColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Micro-surface", target: material, propertyName: "microSurface", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Use physical light falloff", target: material, propertyName: "usePhysicalLightFalloff", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "METALLIC WORKFLOW" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Metallic", target: material, propertyName: "metallic", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
@@ -44569,7 +44601,7 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
                             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Bump strength", target: material.clearCoat.bumpTexture, propertyName: "level", minimum: 0, maximum: 2, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Tint", target: material.clearCoat, propertyName: "isTintEnabled", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                         material.clearCoat.isEnabled && material.clearCoat.isTintEnabled &&
-                            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Tint Color", target: material.clearCoat, propertyName: "tintColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Tint Color", target: material.clearCoat, propertyName: "tintColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
                         material.clearCoat.isEnabled && material.clearCoat.isTintEnabled &&
                             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "At Distance", target: material.clearCoat, propertyName: "tintColorAtDistance", minimum: 0, maximum: 20, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                         material.clearCoat.isEnabled && material.clearCoat.isTintEnabled &&
@@ -44589,7 +44621,7 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "fragment" },
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Link to Albedo", target: material.sheen, propertyName: "linkSheenWithAlbedo", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Intensity", target: material.sheen, propertyName: "intensity", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Color", target: material.sheen, propertyName: "color", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Color", target: material.sheen, propertyName: "color", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textureLinkLineComponent__WEBPACK_IMPORTED_MODULE_10__["TextureLinkLineComponent"], { label: "Texture", texture: material.sheen.texture, material: material, onSelectionChangedObservable: this.props.onSelectionChangedObservable, onDebugSelectionChangeObservable: this._onDebugSelectionChangeObservable }),
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Use roughness", target: material.sheen, propertyName: "_useRoughness" }),
                         material.sheen._useRoughness &&
@@ -44600,7 +44632,7 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Min Thickness", target: material.subSurface, propertyName: "minimumThickness", minimum: 0, maximum: 10, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Max Thickness", target: material.subSurface, propertyName: "maximumThickness", minimum: 0, maximum: 10, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Mask From Thickness", target: material.subSurface, propertyName: "useMaskFromThicknessTexture", onValueChanged: function () { return _this.forceUpdate(); }, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Tint Color", target: material.subSurface, propertyName: "tintColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Tint Color", target: material.subSurface, propertyName: "tintColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Refraction Enabled", target: material.subSurface, propertyName: "isRefractionEnabled", onValueChanged: function () { return _this.forceUpdate(); }, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 material.subSurface.isRefractionEnabled &&
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "fragment" },
@@ -44612,7 +44644,7 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
                 material.subSurface.isTranslucencyEnabled &&
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "fragment" },
                         react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Intensity", target: material.subSurface, propertyName: "translucencyIntensity", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Diffusion Distance", target: material.subSurface, propertyName: "diffusionDistance", onPropertyChangedObservable: this.props.onPropertyChangedObservable }))),
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Diffusion Distance", target: material.subSurface, propertyName: "diffusionDistance", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }))),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LEVELS", closed: true },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Environment", target: material, propertyName: "environmentIntensity", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Specular", target: material, propertyName: "specularIntensity", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
@@ -44706,8 +44738,8 @@ var PBRMetallicRoughnessMaterialPropertyGridComponent = /** @class */ (function
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_6__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
             this.renderTextures(),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LIGHTING & COLORS" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Base", target: material, propertyName: "baseColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Base", target: material, propertyName: "baseColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LEVELS", closed: true },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__["SliderLineComponent"], { label: "Metallic", target: material, propertyName: "metallic", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__["SliderLineComponent"], { label: "Roughness", target: material, propertyName: "roughness", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
@@ -44776,8 +44808,8 @@ var PBRSpecularGlossinessMaterialPropertyGridComponent = /** @class */ (function
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_6__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
             this.renderTextures(),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LIGHTING & COLORS" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Diffuse", target: material, propertyName: "diffuseColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Specular", target: material, propertyName: "specularColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Diffuse", target: material, propertyName: "diffuseColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Specular", target: material, propertyName: "specularColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable, isLinear: true })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LEVELS", closed: true },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__["SliderLineComponent"], { label: "Glossiness", target: material, propertyName: "glossiness", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "NORMAL MAP", closed: true },
@@ -44853,7 +44885,8 @@ var StandardMaterialPropertyGridComponent = /** @class */ (function (_super) {
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Specular", target: material, propertyName: "specularColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__["SliderLineComponent"], { label: "Specular power", target: material, propertyName: "specularPower", minimum: 0, maximum: 128, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_4__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_8__["CheckBoxLineComponent"], { label: "Use specular over alpha", target: material, propertyName: "useSpecularOverAlpha", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "LEVELS", closed: true },
                 material.diffuseTexture &&
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__["SliderLineComponent"], { label: "Diffuse level", target: material.diffuseTexture, propertyName: "level", minimum: 0, maximum: 2, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
@@ -47983,23 +48016,31 @@ var ReplayRecorder = /** @class */ (function () {
             this._recordedCodeLines.pop();
         }
         var value = event.value;
-        if (value.w !== undefined) { // Quaternion
-            value = "new BABYLON.Quaternion(" + value.x + ", " + value.y + ", " + value.z + ", " + value.w + ")";
-        }
-        else if (value.z !== undefined) { // Vector3
-            value = "new BABYLON.Vector3(" + value.x + ", " + value.y + ", " + value.z + ")";
-        }
-        else if (value.y !== undefined) { // Vector2
-            value = "new BABYLON.Vector2(" + value.x + ", " + value.y + ")";
-        }
-        else if (value.a !== undefined) { // Color4
-            value = "new BABYLON.Color4(" + value.r + ", " + value.g + ", " + value.b + ", " + value.a + ")";
-        }
-        else if (value.b !== undefined) { // Color3
-            value = "new BABYLON.Color3(" + value.r + ", " + value.g + ", " + value.b + ")";
-        }
-        else if (value.getClassName) {
-            value = this._getIndirectData(value);
+        if (!event.allowNullValue || event.allowNullValue && value !== null) {
+            if (value.w !== undefined) { // Quaternion
+                value = "new BABYLON.Quaternion(" + value.x + ", " + value.y + ", " + value.z + ", " + value.w + ")";
+            }
+            else if (value.z !== undefined) { // Vector3
+                value = "new BABYLON.Vector3(" + value.x + ", " + value.y + ", " + value.z + ")";
+            }
+            else if (value.y !== undefined) { // Vector2
+                value = "new BABYLON.Vector2(" + value.x + ", " + value.y + ")";
+            }
+            else if (value.a !== undefined) { // Color4
+                value = "new BABYLON.Color4(" + value.r + ", " + value.g + ", " + value.b + ", " + value.a + ")";
+                if (event.object._isLinearColor) {
+                    value += '.toLinearSpace()';
+                }
+            }
+            else if (value.b !== undefined) { // Color3
+                value = "new BABYLON.Color3(" + value.r + ", " + value.g + ", " + value.b + ")";
+                if (event.object._isLinearColor) {
+                    value += '.toLinearSpace()';
+                }
+            }
+            else if (value.getClassName) {
+                value = this._getIndirectData(value);
+            }
         }
         var target = this._getIndirectData(event.object);
         this._recordedCodeLines.push(target + "." + event.property + " = " + value + ";");

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 9 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -5,6 +5,7 @@ declare module INSPECTOR {
         property: string;
         value: any;
         initialValue: any;
+        allowNullValue?: boolean;
     }
 }
 declare module INSPECTOR {
@@ -229,6 +230,7 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export const Null_Value: number;
     class ListLineOption {
         label: string;
         value: number;
@@ -242,11 +244,14 @@ declare module INSPECTOR {
         onSelect?: (value: number) => void;
         extractValue?: () => number;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        allowNullValue?: boolean;
     }
     export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, {
         value: number;
     }> {
         private _localChange;
+        private remapValueIn;
+        private remapValueOut;
         constructor(props: IOptionsLineComponentProps);
         shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: {
             value: number;
@@ -296,6 +301,7 @@ declare module INSPECTOR {
         target: any;
         propertyName: string;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        isLinear?: boolean;
     }
     export class Color3LineComponent extends React.Component<IColor3LineComponentProps, {
         isExpanded: boolean;
@@ -306,6 +312,7 @@ declare module INSPECTOR {
         shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: {
             color: BABYLON.Color3;
         }): boolean;
+        setPropertyValue(newColor: BABYLON.Color3): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: BABYLON.Color3): void;
@@ -1301,6 +1308,7 @@ declare module INSPECTOR {
         propertyName: string;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         onChange?: () => void;
+        isLinear?: boolean;
     }
     export class Color4LineComponent extends React.Component<IColor4LineComponentProps, {
         isExpanded: boolean;
@@ -1311,6 +1319,7 @@ declare module INSPECTOR {
         shouldComponentUpdate(nextProps: IColor4LineComponentProps, nextState: {
             color: BABYLON.Color4;
         }): boolean;
+        setPropertyValue(newColor: BABYLON.Color4): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: BABYLON.Color4): void;

+ 18 - 0
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -5,6 +5,7 @@ declare module "babylonjs-inspector/components/propertyChangedEvent" {
         property: string;
         value: any;
         initialValue: any;
+        allowNullValue?: boolean;
     }
 }
 declare module "babylonjs-inspector/components/replayRecorder" {
@@ -266,6 +267,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/optionsLineCompo
     import * as React from "react";
     import { Observable } from "babylonjs/Misc/observable";
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    export const Null_Value: number;
     class ListLineOption {
         label: string;
         value: number;
@@ -279,11 +281,14 @@ declare module "babylonjs-inspector/components/actionTabs/lines/optionsLineCompo
         onSelect?: (value: number) => void;
         extractValue?: () => number;
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+        allowNullValue?: boolean;
     }
     export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, {
         value: number;
     }> {
         private _localChange;
+        private remapValueIn;
+        private remapValueOut;
         constructor(props: IOptionsLineComponentProps);
         shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: {
             value: number;
@@ -338,6 +343,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/color3LineCompon
         target: any;
         propertyName: string;
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+        isLinear?: boolean;
     }
     export class Color3LineComponent extends React.Component<IColor3LineComponentProps, {
         isExpanded: boolean;
@@ -348,6 +354,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/color3LineCompon
         shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: {
             color: Color3;
         }): boolean;
+        setPropertyValue(newColor: Color3): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: Color3): void;
@@ -1687,6 +1694,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/color4LineCompon
         propertyName: string;
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
         onChange?: () => void;
+        isLinear?: boolean;
     }
     export class Color4LineComponent extends React.Component<IColor4LineComponentProps, {
         isExpanded: boolean;
@@ -1697,6 +1705,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/color4LineCompon
         shouldComponentUpdate(nextProps: IColor4LineComponentProps, nextState: {
             color: Color4;
         }): boolean;
+        setPropertyValue(newColor: Color4): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: Color4): void;
@@ -2599,6 +2608,7 @@ declare module INSPECTOR {
         property: string;
         value: any;
         initialValue: any;
+        allowNullValue?: boolean;
     }
 }
 declare module INSPECTOR {
@@ -2823,6 +2833,7 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export const Null_Value: number;
     class ListLineOption {
         label: string;
         value: number;
@@ -2836,11 +2847,14 @@ declare module INSPECTOR {
         onSelect?: (value: number) => void;
         extractValue?: () => number;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        allowNullValue?: boolean;
     }
     export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, {
         value: number;
     }> {
         private _localChange;
+        private remapValueIn;
+        private remapValueOut;
         constructor(props: IOptionsLineComponentProps);
         shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: {
             value: number;
@@ -2890,6 +2904,7 @@ declare module INSPECTOR {
         target: any;
         propertyName: string;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        isLinear?: boolean;
     }
     export class Color3LineComponent extends React.Component<IColor3LineComponentProps, {
         isExpanded: boolean;
@@ -2900,6 +2915,7 @@ declare module INSPECTOR {
         shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: {
             color: BABYLON.Color3;
         }): boolean;
+        setPropertyValue(newColor: BABYLON.Color3): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: BABYLON.Color3): void;
@@ -3895,6 +3911,7 @@ declare module INSPECTOR {
         propertyName: string;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         onChange?: () => void;
+        isLinear?: boolean;
     }
     export class Color4LineComponent extends React.Component<IColor4LineComponentProps, {
         isExpanded: boolean;
@@ -3905,6 +3922,7 @@ declare module INSPECTOR {
         shouldComponentUpdate(nextProps: IColor4LineComponentProps, nextState: {
             color: BABYLON.Color4;
         }): boolean;
+        setPropertyValue(newColor: BABYLON.Color4): void;
         onChange(newValue: string): void;
         switchExpandState(): void;
         raiseOnPropertyChanged(previousValue: BABYLON.Color4): void;

+ 7 - 7
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,12 +29,12 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0",
-        "babylonjs-gui": "4.2.0-alpha.0",
-        "babylonjs-loaders": "4.2.0-alpha.0",
-        "babylonjs-materials": "4.2.0-alpha.0",
-        "babylonjs-serializers": "4.2.0-alpha.0",
-        "babylonjs-gltf2interface": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1",
+        "babylonjs-gui": "4.2.0-alpha.1",
+        "babylonjs-loaders": "4.2.0-alpha.1",
+        "babylonjs-materials": "4.2.0-alpha.1",
+        "babylonjs-serializers": "4.2.0-alpha.1",
+        "babylonjs-gltf2interface": "4.2.0-alpha.1"
     },
     "devDependencies": {
         "@types/react": "~16.7.3",

+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js

@@ -9110,7 +9110,7 @@ __webpack_require__.r(__webpack_exports__);
 /*!******************!*\
   !*** ./index.ts ***!
   \******************/
-/*! exports provided: GLTFLoaderCoordinateSystemMode, GLTFLoaderAnimationStartMode, GLTFLoaderState, GLTFFileLoader, GLTFValidation, GLTF1, GLTF2, MTLFileLoader, OBJFileLoader, STLFileLoader */
+/*! exports provided: GLTFLoaderCoordinateSystemMode, GLTFLoaderAnimationStartMode, GLTFLoaderState, GLTFFileLoader, GLTFValidation, GLTF1, GLTF2, STLFileLoader, MTLFileLoader, OBJFileLoader */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";

+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.2.0-alpha.0",
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs-gltf2interface": "4.2.0-alpha.1",
+        "babylonjs": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/nodeEditor/package.json

@@ -4,14 +4,14 @@
     },
     "name": "babylonjs-node-editor",
     "description": "The Babylon.js node material editor.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1"
     },
     "files": [
         "babylon.nodeEditor.max.js.map",

+ 1 - 1
dist/preview release/package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.0",
-        "babylonjs-gltf2interface": "4.2.0-alpha.0"
+        "babylonjs": "4.2.0-alpha.1",
+        "babylonjs-gltf2interface": "4.2.0-alpha.1"
     },
     "engines": {
         "node": "*"

+ 146 - 66
dist/preview release/viewer/babylon.module.d.ts

@@ -8868,10 +8868,18 @@ declare module "babylonjs/Cameras/Inputs/freeCameraKeyboardMoveInput" {
          */
         keysUp: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        keysUpward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         keysDown: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+         */
+        keysDownward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         keysLeft: number[];
@@ -18909,11 +18917,21 @@ declare module "babylonjs/Cameras/freeCamera" {
         get keysUp(): number[];
         set keysUp(value: number[]);
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        get keysUpward(): number[];
+        set keysUpward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         get keysDown(): number[];
         set keysDown(value: number[]);
         /**
+        * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+        */
+        get keysDownward(): number[];
+        set keysDownward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         get keysLeft(): number[];
@@ -21529,6 +21547,23 @@ declare module "babylonjs/Materials/material" {
          */
         static readonly AllDirtyFlag: number;
         /**
+         * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+         */
+        static readonly MATERIAL_OPAQUE: number;
+        /**
+         * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+         */
+        static readonly MATERIAL_ALPHATEST: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         */
+        static readonly MATERIAL_ALPHABLEND: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         * They are also discarded below the alpha cutoff threshold to improve performances.
+         */
+        static readonly MATERIAL_ALPHATESTANDBLEND: number;
+        /**
          * The ID of the material
          */
         id: string;
@@ -21841,7 +21876,35 @@ declare module "babylonjs/Materials/material" {
          */
         getScene(): Scene;
         /**
-         * Specifies if the material will require alpha blending
+         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+         */
+        protected _forceAlphaTest: boolean;
+        /**
+         * The transparency mode of the material.
+         */
+        protected _transparencyMode: Nullable<number>;
+        /**
+         * Gets the current transparency mode.
+         */
+        get transparencyMode(): Nullable<number>;
+        /**
+         * Sets the transparency mode of the material.
+         *
+         * | Value | Type                                | Description |
+         * | ----- | ----------------------------------- | ----------- |
+         * | 0     | OPAQUE                              |             |
+         * | 1     | ALPHATEST                           |             |
+         * | 2     | ALPHABLEND                          |             |
+         * | 3     | ALPHATESTANDBLEND                   |             |
+         *
+         */
+        set transparencyMode(value: Nullable<number>);
+        /**
+         * Returns true if alpha blending should be disabled.
+         */
+        protected get _disableAlphaBlending(): boolean;
+        /**
+         * Specifies whether or not this material should be rendered in alpha blend mode.
          * @returns a boolean specifying if alpha blending is needed
          */
         needAlphaBlending(): boolean;
@@ -21852,11 +21915,16 @@ declare module "babylonjs/Materials/material" {
          */
         needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
         /**
-         * Specifies if this material should be rendered in alpha test mode
+         * Specifies whether or not this material should be rendered in alpha test mode.
          * @returns a boolean specifying if an alpha test is needed.
          */
         needAlphaTesting(): boolean;
         /**
+         * Specifies if material alpha testing should be turned on for the mesh
+         * @param mesh defines the mesh to check
+         */
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
+        /**
          * Gets the texture used for the alpha test
          * @returns the texture to use for alpha testing
          */
@@ -21902,11 +21970,6 @@ declare module "babylonjs/Materials/material" {
          */
         bindViewProjection(effect: Effect): void;
         /**
-         * Specifies if material alpha testing should be turned on for the mesh
-         * @param mesh defines the mesh to check
-         */
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        /**
          * Processes to execute after binding the material to a mesh
          * @param mesh defines the rendered mesh
          */
@@ -27247,6 +27310,8 @@ declare module "babylonjs/Materials/standardMaterial" {
         NUM_MORPH_INFLUENCERS: number;
         NONUNIFORMSCALING: boolean;
         PREMULTIPLYALPHA: boolean;
+        ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
+        ALPHABLEND: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -53568,10 +53633,6 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
          */
         protected _useLinearAlphaFresnel: boolean;
         /**
-         * The transparency mode of the material.
-         */
-        protected _transparencyMode: Nullable<number>;
-        /**
          * Specifies the environment BRDF texture used to comput the scale and offset roughness values
          * from cos thetav and roughness:
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -53693,35 +53754,14 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
          */
         set useLogarithmicDepth(value: boolean);
         /**
-         * Gets the current transparency mode.
-         */
-        get transparencyMode(): Nullable<number>;
-        /**
-         * Sets the transparency mode of the material.
-         *
-         * | Value | Type                                | Description |
-         * | ----- | ----------------------------------- | ----------- |
-         * | 0     | OPAQUE                              |             |
-         * | 1     | ALPHATEST                           |             |
-         * | 2     | ALPHABLEND                          |             |
-         * | 3     | ALPHATESTANDBLEND                   |             |
-         *
-         */
-        set transparencyMode(value: Nullable<number>);
-        /**
          * Returns true if alpha blending should be disabled.
          */
-        private get _disableAlphaBlending();
+        protected get _disableAlphaBlending(): boolean;
         /**
          * Specifies whether or not this material should be rendered in alpha blend mode.
          */
         needAlphaBlending(): boolean;
         /**
-         * Specifies if the mesh will require alpha blending.
-         * @param mesh - BJS mesh.
-         */
-        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
-        /**
          * Specifies whether or not this material should be rendered in alpha test mode.
          */
         needAlphaTesting(): boolean;
@@ -82256,10 +82296,18 @@ declare module BABYLON {
          */
         keysUp: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        keysUpward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         keysDown: number[];
         /**
+         * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+         */
+        keysDownward: number[];
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         keysLeft: number[];
@@ -91894,11 +91942,21 @@ declare module BABYLON {
         get keysUp(): number[];
         set keysUp(value: number[]);
         /**
+         * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+         */
+        get keysUpward(): number[];
+        set keysUpward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the backward move of the camera.
          */
         get keysDown(): number[];
         set keysDown(value: number[]);
         /**
+        * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+        */
+        get keysDownward(): number[];
+        set keysDownward(value: number[]);
+        /**
          * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
          */
         get keysLeft(): number[];
@@ -94380,6 +94438,23 @@ declare module BABYLON {
          */
         static readonly AllDirtyFlag: number;
         /**
+         * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+         */
+        static readonly MATERIAL_OPAQUE: number;
+        /**
+         * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+         */
+        static readonly MATERIAL_ALPHATEST: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         */
+        static readonly MATERIAL_ALPHABLEND: number;
+        /**
+         * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+         * They are also discarded below the alpha cutoff threshold to improve performances.
+         */
+        static readonly MATERIAL_ALPHATESTANDBLEND: number;
+        /**
          * The ID of the material
          */
         id: string;
@@ -94692,7 +94767,35 @@ declare module BABYLON {
          */
         getScene(): Scene;
         /**
-         * Specifies if the material will require alpha blending
+         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+         */
+        protected _forceAlphaTest: boolean;
+        /**
+         * The transparency mode of the material.
+         */
+        protected _transparencyMode: Nullable<number>;
+        /**
+         * Gets the current transparency mode.
+         */
+        get transparencyMode(): Nullable<number>;
+        /**
+         * Sets the transparency mode of the material.
+         *
+         * | Value | Type                                | Description |
+         * | ----- | ----------------------------------- | ----------- |
+         * | 0     | OPAQUE                              |             |
+         * | 1     | ALPHATEST                           |             |
+         * | 2     | ALPHABLEND                          |             |
+         * | 3     | ALPHATESTANDBLEND                   |             |
+         *
+         */
+        set transparencyMode(value: Nullable<number>);
+        /**
+         * Returns true if alpha blending should be disabled.
+         */
+        protected get _disableAlphaBlending(): boolean;
+        /**
+         * Specifies whether or not this material should be rendered in alpha blend mode.
          * @returns a boolean specifying if alpha blending is needed
          */
         needAlphaBlending(): boolean;
@@ -94703,11 +94806,16 @@ declare module BABYLON {
          */
         needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
         /**
-         * Specifies if this material should be rendered in alpha test mode
+         * Specifies whether or not this material should be rendered in alpha test mode.
          * @returns a boolean specifying if an alpha test is needed.
          */
         needAlphaTesting(): boolean;
         /**
+         * Specifies if material alpha testing should be turned on for the mesh
+         * @param mesh defines the mesh to check
+         */
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
+        /**
          * Gets the texture used for the alpha test
          * @returns the texture to use for alpha testing
          */
@@ -94753,11 +94861,6 @@ declare module BABYLON {
          */
         bindViewProjection(effect: Effect): void;
         /**
-         * Specifies if material alpha testing should be turned on for the mesh
-         * @param mesh defines the mesh to check
-         */
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        /**
          * Processes to execute after binding the material to a mesh
          * @param mesh defines the rendered mesh
          */
@@ -99913,6 +100016,8 @@ declare module BABYLON {
         NUM_MORPH_INFLUENCERS: number;
         NONUNIFORMSCALING: boolean;
         PREMULTIPLYALPHA: boolean;
+        ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
+        ALPHABLEND: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -124864,10 +124969,6 @@ declare module BABYLON {
          */
         protected _useLinearAlphaFresnel: boolean;
         /**
-         * The transparency mode of the material.
-         */
-        protected _transparencyMode: Nullable<number>;
-        /**
          * Specifies the environment BRDF texture used to comput the scale and offset roughness values
          * from cos thetav and roughness:
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -124989,35 +125090,14 @@ declare module BABYLON {
          */
         set useLogarithmicDepth(value: boolean);
         /**
-         * Gets the current transparency mode.
-         */
-        get transparencyMode(): Nullable<number>;
-        /**
-         * Sets the transparency mode of the material.
-         *
-         * | Value | Type                                | Description |
-         * | ----- | ----------------------------------- | ----------- |
-         * | 0     | OPAQUE                              |             |
-         * | 1     | ALPHATEST                           |             |
-         * | 2     | ALPHABLEND                          |             |
-         * | 3     | ALPHATESTANDBLEND                   |             |
-         *
-         */
-        set transparencyMode(value: Nullable<number>);
-        /**
          * Returns true if alpha blending should be disabled.
          */
-        private get _disableAlphaBlending();
+        protected get _disableAlphaBlending(): boolean;
         /**
          * Specifies whether or not this material should be rendered in alpha blend mode.
          */
         needAlphaBlending(): boolean;
         /**
-         * Specifies if the mesh will require alpha blending.
-         * @param mesh - BJS mesh.
-         */
-        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
-        /**
          * Specifies whether or not this material should be rendered in alpha test mode.
          */
         needAlphaTesting(): boolean;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 14 - 14
dist/preview release/viewer/babylon.viewer.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 6 - 0
dist/preview release/what's new.md

@@ -16,9 +16,14 @@
 
 - Allow logging of shader code when a compilation error occurs ([Popov72](https://github.com/Popov72))
 
+### Inspector
+
+- Handle PBR colors as colors in linear space ([Popov72](https://github.com/Popov72))
+
 ### Cameras
 
 - Added flag to TargetCamera to invert rotation direction and multiplier to adjust speed ([Exolun](https://github.com/Exolun))
+- Added upwards and downwards keyboard input to `FreeCamera` ([Pheater](https://github.com/pheater))
 
 ### Physics
 
@@ -31,6 +36,7 @@
 ### Materials
 - Added the `roughness` and `albedoScaling` parameters to PBR sheen ([Popov72](https://github.com/Popov72))
 - Updated the energy conservation factor for the clear coat layer in PBR materials ([Popov72](https://github.com/Popov72))
+- Added the `transparencyMode` property to the `StandardMaterial` class ([Popov72](https://github.com/Popov72))
 
 ### WebXR
 - Added optional ray and mesh selection predicates to `WebXRControllerPointerSelection` ([Exolun](https://github.com/Exolun))

+ 22 - 11
inspector/src/components/actionTabs/lines/color3LineComponent.tsx

@@ -13,6 +13,7 @@ export interface IColor3LineComponentProps {
     target: any;
     propertyName: string;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    isLinear?: boolean;
 }
 
 export class Color3LineComponent extends React.Component<IColor3LineComponentProps, { isExpanded: boolean, color: Color3 }> {
@@ -21,10 +22,16 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
         super(props);
 
         this.state = { isExpanded: false, color: this.props.target[this.props.propertyName].clone() };
+
+        if (props.isLinear) {
+            this.state.color.toGammaSpaceToRef(this.state.color);
+        }
+
+        props.target._isLinearColor = props.isLinear; // so that replayRecorder can append toLinearSpace() as appropriate
     }
 
     shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: { color: Color3 }) {
-        const currentState = nextProps.target[nextProps.propertyName];
+        const currentState = this.props.isLinear ? nextProps.target[nextProps.propertyName].toGammaSpace() : nextProps.target[nextProps.propertyName];
 
         if (!currentState.equals(nextState.color) || this._localChange) {
             nextState.color = currentState.clone();
@@ -34,6 +41,14 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
         return false;
     }
 
+    setPropertyValue(newColor: Color3) {
+        this.props.target[this.props.propertyName] = newColor;
+
+        if (this.props.isLinear) {
+            this.props.target[this.props.propertyName] = newColor.toLinearSpace();
+        }
+    }
+
     onChange(newValue: string) {
         this._localChange = true;
         const newColor = Color3.FromHexString(newValue);
@@ -43,11 +58,11 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
                 object: this.props.target,
                 property: this.props.propertyName,
                 value: newColor,
-                initialValue: this.state.color
+                initialValue: this.state.color,
             });
         }
 
-        this.props.target[this.props.propertyName] = newColor;
+        this.setPropertyValue(newColor);
 
         this.setState({ color: newColor });
     }
@@ -58,7 +73,6 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
     }
 
     raiseOnPropertyChanged(previousValue: Color3) {
-
         if (!this.props.onPropertyChangedObservable) {
             return;
         }
@@ -66,7 +80,7 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
             object: this.props.target,
             property: this.props.propertyName,
             value: this.state.color,
-            initialValue: previousValue
+            initialValue: previousValue,
         });
     }
 
@@ -74,9 +88,8 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].x = value;
         this.state.color.r = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);
@@ -86,9 +99,8 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].g = value;
         this.state.color.g = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);
@@ -98,9 +110,8 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].b = value;
         this.state.color.b = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);

+ 33 - 15
inspector/src/components/actionTabs/lines/color4LineComponent.tsx

@@ -14,6 +14,7 @@ export interface IColor4LineComponentProps {
     propertyName: string;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
     onChange?: () => void;
+    isLinear?: boolean;
 }
 
 export class Color4LineComponent extends React.Component<IColor4LineComponentProps, { isExpanded: boolean, color: Color4 }> {
@@ -24,12 +25,22 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
         let value = this.props.target[this.props.propertyName];
         let currentColor = value.getClassName() === "Color4" ? value.clone() : new Color4(value.r, value.g, value.b, 1.0);
         this.state = { isExpanded: false, color: currentColor };
+
+        if (props.isLinear) {
+            this.state.color.toGammaSpaceToRef(this.state.color);
+        }
+
+        props.target._isLinearColor = props.isLinear; // so that replayRecorder can append toLinearSpace() as appropriate
     }
 
     shouldComponentUpdate(nextProps: IColor4LineComponentProps, nextState: { color: Color4 }) {
         let value = this.props.target[this.props.propertyName];
         let currentColor = value.getClassName() === "Color4" ? value : new Color4(value.r, value.g, value.b, 1.0);
 
+        if (this.props.isLinear) {
+            currentColor.toGammaSpaceRef(currentColor);
+        }
+
         if (!currentColor.equals(nextState.color) || this._localChange) {
             nextState.color = currentColor.clone();
             this._localChange = false;
@@ -38,6 +49,14 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
         return false;
     }
 
+    setPropertyValue(newColor: Color4) {
+        this.props.target[this.props.propertyName] = newColor;
+
+        if (this.props.isLinear) {
+            this.props.target[this.props.propertyName] = newColor.toLinearSpace();
+        }
+    }
+
     onChange(newValue: string) {
         this._localChange = true;
         const newColor = Color3.FromHexString(newValue);
@@ -47,13 +66,15 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                 object: this.props.target,
                 property: this.props.propertyName,
                 value: newColor,
-                initialValue: this.state.color
+                initialValue: this.state.color,
             });
         }
 
-        this.props.target[this.props.propertyName] = new Color4(newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+        const newColor4 = new Color4(newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+
+        this.setPropertyValue(newColor4);
 
-        this.setState({ color: this.props.target[this.props.propertyName] });
+        this.setState({ color: newColor4 });
 
         if (this.props.onChange) {
             this.props.onChange();
@@ -73,7 +94,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
             object: this.props.target,
             property: this.props.propertyName,
             value: this.state.color,
-            initialValue: previousValue
+            initialValue: previousValue,
         });
     }
 
@@ -81,9 +102,8 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].x = value;
         this.state.color.r = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);
@@ -93,9 +113,8 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].g = value;
         this.state.color.g = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);
@@ -105,9 +124,8 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
         this._localChange = true;
 
         const store = this.state.color.clone();
-        this.props.target[this.props.propertyName].b = value;
         this.state.color.b = value;
-        this.props.target[this.props.propertyName] = this.state.color;
+        this.setPropertyValue(this.state.color);
         this.setState({ color: this.state.color });
 
         this.raiseOnPropertyChanged(store);
@@ -143,7 +161,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
 
     render() {
 
-        const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
+        const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
         const colorAsColor3 = new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
 
         return (
@@ -165,10 +183,10 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                 {
                     this.state.isExpanded &&
                     <div className="secondLine">
-                        <NumericInputComponent label="r" value={this.state.color.r} onChange={value => this.updateStateR(value)} />
-                        <NumericInputComponent label="g" value={this.state.color.g} onChange={value => this.updateStateG(value)} />
-                        <NumericInputComponent label="b" value={this.state.color.b} onChange={value => this.updateStateB(value)} />
-                        <NumericInputComponent label="a" value={this.state.color.a} onChange={value => this.updateStateA(value)} />
+                        <NumericInputComponent label="r" value={this.state.color.r} onChange={(value) => this.updateStateR(value)} />
+                        <NumericInputComponent label="g" value={this.state.color.g} onChange={(value) => this.updateStateG(value)} />
+                        <NumericInputComponent label="b" value={this.state.color.b} onChange={(value) => this.updateStateB(value)} />
+                        <NumericInputComponent label="a" value={this.state.color.a} onChange={(value) => this.updateStateA(value)} />
                     </div>
                 }
             </div>

+ 30 - 19
inspector/src/components/actionTabs/lines/optionsLineComponent.tsx

@@ -3,29 +3,40 @@ import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
 
+export const Null_Value = Number.MAX_SAFE_INTEGER;
+
 class ListLineOption {
     public label: string;
     public value: number;
 }
 
 interface IOptionsLineComponentProps {
-    label: string,
-    target: any,
-    propertyName: string,
-    options: ListLineOption[],
-    noDirectUpdate?: boolean,
-    onSelect?: (value: number) => void,
-    extractValue?: () => number,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    label: string;
+    target: any;
+    propertyName: string;
+    options: ListLineOption[];
+    noDirectUpdate?: boolean;
+    onSelect?: (value: number) => void;
+    extractValue?: () => number;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    allowNullValue?: boolean;
 }
 
 export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, { value: number }> {
     private _localChange = false;
 
+    private remapValueIn(value: number | null): number {
+        return this.props.allowNullValue && value === null ? Null_Value : value!;
+    }
+
+    private remapValueOut(value: number): number | null {
+        return this.props.allowNullValue && value === Null_Value ? null : value;
+    }
+
     constructor(props: IOptionsLineComponentProps) {
         super(props);
 
-        this.state = { value: this.props.extractValue ? this.props.extractValue() : props.target[props.propertyName] };
+        this.state = { value: this.remapValueIn(this.props.extractValue ? this.props.extractValue() : props.target[props.propertyName]) };
     }
 
     shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: { value: number }) {
@@ -34,7 +45,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
             return true;
         }
 
-        const newValue = nextProps.extractValue ? nextProps.extractValue() : nextProps.target[nextProps.propertyName];
+        let newValue = this.remapValueIn(nextProps.extractValue ? nextProps.extractValue() : nextProps.target[nextProps.propertyName]);
         if (newValue != null && newValue !== nextState.value) {
             nextState.value = newValue;
             return true;
@@ -51,7 +62,8 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
             object: this.props.target,
             property: this.props.propertyName,
             value: newValue,
-            initialValue: previousValue
+            initialValue: previousValue,
+            allowNullValue: this.props.allowNullValue,
         });
     }
 
@@ -59,21 +71,20 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
         const value = parseInt(valueString);
         this._localChange = true;
 
-        const store = this.props.extractValue ? this.props.extractValue() : this.props.target[this.props.propertyName]
+        const store = this.props.extractValue ? this.props.extractValue() : this.props.target[this.props.propertyName];
 
         if (!this.props.noDirectUpdate) {
-            this.props.target[this.props.propertyName] = value;
+            this.props.target[this.props.propertyName] = this.remapValueOut(value);
         }
         this.setState({ value: value });
-        
+
         if (this.props.onSelect) {
             this.props.onSelect(value);
         }
 
-        const newValue = this.props.extractValue ? this.props.extractValue() : this.props.target[this.props.propertyName]
+        const newValue = this.props.extractValue ? this.props.extractValue() : this.props.target[this.props.propertyName];
 
         this.raiseOnPropertyChanged(newValue, store);
-
     }
 
     render() {
@@ -84,12 +95,12 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
 
                 </div>
                 <div className="options">
-                    <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value ?? ""}>
+                    <select onChange={(evt) => this.updateValue(evt.target.value)} value={this.state.value ?? ""}>
                         {
-                            this.props.options.map(option => {
+                            this.props.options.map((option) => {
                                 return (
                                     <option key={option.label} value={option.value}>{option.label}</option>
-                                )
+                                );
                             })
                         }
                     </select>

+ 11 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx

@@ -11,7 +11,7 @@ import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { SliderLineComponent } from "../../../lines/sliderLineComponent";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
-import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+import { OptionsLineComponent, Null_Value } from "../../../lines/optionsLineComponent";
 import { LockObject } from "../lockObject";
 import { GlobalState } from '../../../../globalState';
 import { CustomPropertyGridComponent } from '../customPropertyGridComponent';
@@ -40,6 +40,7 @@ export class CommonMaterialPropertyGridComponent extends React.Component<ICommon
         ];
 
         var transparencyModeOptions = [
+            { label: "<Not Defined>", value: Null_Value },
             { label: "Opaque", value: PBRMaterial.PBRMATERIAL_OPAQUE },
             { label: "Alpha test", value: PBRMaterial.PBRMATERIAL_ALPHATEST },
             { label: "Alpha blend", value: PBRMaterial.PBRMATERIAL_ALPHABLEND },
@@ -96,9 +97,17 @@ export class CommonMaterialPropertyGridComponent extends React.Component<ICommon
                     <SliderLineComponent label="Alpha" target={material} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         (material as any).transparencyMode !== undefined &&
-                        <OptionsLineComponent label="Transparency mode" options={transparencyModeOptions} target={material} propertyName="transparencyMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => this.setState({ transparencyMode: value })} />
+                        <OptionsLineComponent allowNullValue={true} label="Transparency mode" options={transparencyModeOptions} target={material} propertyName="transparencyMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => this.setState({ transparencyMode: value })} />
                     }
                     <OptionsLineComponent label="Alpha mode" options={alphaModeOptions} target={material} propertyName="alphaMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => this.setState({ alphaMode: value })} />
+                    {
+                        (material as any).useAlphaFromDiffuseTexture !== undefined &&
+                        <CheckBoxLineComponent label="Use alpha from diffuse texture" target={material} propertyName="useAlphaFromDiffuseTexture" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
+                    {
+                        (material as any).useAlphaFromAlbedoTexture !== undefined &&
+                        <CheckBoxLineComponent label="Use alpha from albedo texture" target={material} propertyName="useAlphaFromAlbedoTexture" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
                     <CheckBoxLineComponent label="Separate culling pass" target={material} propertyName="separateCullingPass" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
             </div>

+ 8 - 8
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx

@@ -141,11 +141,11 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                 <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 {this.renderTextures(this._onDebugSelectionChangeObservable)}
                 <LineContainerComponent globalState={this.props.globalState} title="LIGHTING & COLORS">
-                    <Color3LineComponent label="Albedo" target={material} propertyName="albedoColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Reflectivity" target={material} propertyName="reflectivityColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color3LineComponent label="Albedo" target={material} propertyName="albedoColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true}/>
+                    <Color3LineComponent label="Reflectivity" target={material} propertyName="reflectivityColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                     <SliderLineComponent label="Micro-surface" target={material} propertyName="microSurface" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Emissive" target={material} propertyName="emissiveColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Ambient" target={material} propertyName="ambientColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color3LineComponent label="Emissive" target={material} propertyName="emissiveColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
+                    <Color3LineComponent label="Ambient" target={material} propertyName="ambientColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                     <CheckBoxLineComponent label="Use physical light falloff" target={material} propertyName="usePhysicalLightFalloff" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} title="METALLIC WORKFLOW">
@@ -175,7 +175,7 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                             <CheckBoxLineComponent label="Tint" target={material.clearCoat} propertyName="isTintEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                             {
                                 material.clearCoat.isEnabled && material.clearCoat.isTintEnabled &&
-                                <Color3LineComponent label="Tint Color" target={material.clearCoat} propertyName="tintColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                                <Color3LineComponent label="Tint Color" target={material.clearCoat} propertyName="tintColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                             }
                             {
                                 material.clearCoat.isEnabled && material.clearCoat.isTintEnabled &&
@@ -214,7 +214,7 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                         <div className="fragment">
                             <CheckBoxLineComponent label="Link to Albedo" target={material.sheen} propertyName="linkSheenWithAlbedo" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                             <SliderLineComponent label="Intensity" target={material.sheen} propertyName="intensity" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                            <Color3LineComponent label="Color" target={material.sheen} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                            <Color3LineComponent label="Color" target={material.sheen} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                             <TextureLinkLineComponent label="Texture" texture={material.sheen.texture} material={material} onSelectionChangedObservable={this.props.onSelectionChangedObservable} onDebugSelectionChangeObservable={this._onDebugSelectionChangeObservable} />
                             <CheckBoxLineComponent label="Use roughness" target={material.sheen} propertyName="_useRoughness" />
                             { (material.sheen as any)._useRoughness &&
@@ -231,7 +231,7 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                     <CheckBoxLineComponent label="Mask From Thickness" target={material.subSurface} propertyName="useMaskFromThicknessTexture"
                         onValueChanged={() => this.forceUpdate()}
                         onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Tint Color" target={material.subSurface} propertyName="tintColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color3LineComponent label="Tint Color" target={material.subSurface} propertyName="tintColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
 
                     <CheckBoxLineComponent label="Refraction Enabled" target={material.subSurface} propertyName="isRefractionEnabled"
                         onValueChanged={() => this.forceUpdate()}
@@ -253,7 +253,7 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                         material.subSurface.isTranslucencyEnabled &&
                         <div className="fragment">
                             <SliderLineComponent label="Intensity" target={material.subSurface} propertyName="translucencyIntensity" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                            <Color3LineComponent label="Diffusion Distance" target={material.subSurface} propertyName="diffusionDistance" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                            <Color3LineComponent label="Diffusion Distance" target={material.subSurface} propertyName="diffusionDistance" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                         </div>
                     }
                 </LineContainerComponent>

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMetallicRoughnessMaterialPropertyGridComponent.tsx

@@ -52,8 +52,8 @@ export class PBRMetallicRoughnessMaterialPropertyGridComponent extends React.Com
                 <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 {this.renderTextures()}
                 <LineContainerComponent globalState={this.props.globalState} title="LIGHTING & COLORS">
-                    <Color3LineComponent label="Base" target={material} propertyName="baseColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Emissive" target={material} propertyName="emissiveColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color3LineComponent label="Base" target={material} propertyName="baseColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
+                    <Color3LineComponent label="Emissive" target={material} propertyName="emissiveColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} title="LEVELS" closed={true}>
                     <SliderLineComponent label="Metallic" target={material} propertyName="metallic" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrSpecularGlossinessMaterialPropertyGridComponent.tsx

@@ -52,8 +52,8 @@ export class PBRSpecularGlossinessMaterialPropertyGridComponent extends React.Co
                 <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 {this.renderTextures()}
                 <LineContainerComponent globalState={this.props.globalState} title="LIGHTING & COLORS">
-                    <Color3LineComponent label="Diffuse" target={material} propertyName="diffuseColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Color3LineComponent label="Specular" target={material} propertyName="specularColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color3LineComponent label="Diffuse" target={material} propertyName="diffuseColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
+                    <Color3LineComponent label="Specular" target={material} propertyName="specularColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} isLinear={true} />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} title="LEVELS" closed={true}>
                     <SliderLineComponent label="Glossiness" target={material} propertyName="glossiness" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 1 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/standardMaterialPropertyGridComponent.tsx

@@ -62,6 +62,7 @@ export class StandardMaterialPropertyGridComponent extends React.Component<IStan
                     <SliderLineComponent label="Specular power" target={material} propertyName="specularPower" minimum={0} maximum={128} step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Emissive" target={material} propertyName="emissiveColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Ambient" target={material} propertyName="ambientColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Use specular over alpha" target={material} propertyName="useSpecularOverAlpha" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} title="LEVELS" closed={true}>
                     {

+ 1 - 0
inspector/src/components/propertyChangedEvent.ts

@@ -3,4 +3,5 @@ export class PropertyChangedEvent {
     public property: string;
     public value: any;
     public initialValue: any;
+    public allowNullValue?: boolean;
 }

+ 20 - 12
inspector/src/components/replayRecorder.ts

@@ -53,18 +53,26 @@ export class ReplayRecorder {
 
         let value = event.value;
 
-        if (value.w !== undefined) { // Quaternion
-            value = `new BABYLON.Quaternion(${value.x}, ${value.y}, ${value.z}, ${value.w})`;
-        } else if (value.z !== undefined) { // Vector3
-            value = `new BABYLON.Vector3(${value.x}, ${value.y}, ${value.z})`;
-        } else if (value.y !== undefined) { // Vector2
-            value = `new BABYLON.Vector2(${value.x}, ${value.y})`;
-        } else if (value.a !== undefined) { // Color4
-            value = `new BABYLON.Color4(${value.r}, ${value.g}, ${value.b}, ${value.a})`;
-        } else if (value.b !== undefined) { // Color3
-            value = `new BABYLON.Color3(${value.r}, ${value.g}, ${value.b})`;
-        } else if (value.getClassName) {
-            value = this._getIndirectData(value);
+        if (!event.allowNullValue || event.allowNullValue && value !== null) {
+            if (value.w !== undefined) { // Quaternion
+                value = `new BABYLON.Quaternion(${value.x}, ${value.y}, ${value.z}, ${value.w})`;
+            } else if (value.z !== undefined) { // Vector3
+                value = `new BABYLON.Vector3(${value.x}, ${value.y}, ${value.z})`;
+            } else if (value.y !== undefined) { // Vector2
+                value = `new BABYLON.Vector2(${value.x}, ${value.y})`;
+            } else if (value.a !== undefined) { // Color4
+                value = `new BABYLON.Color4(${value.r}, ${value.g}, ${value.b}, ${value.a})`;
+                if (event.object._isLinearColor) {
+                    value += '.toLinearSpace()';
+                }
+            } else if (value.b !== undefined) { // Color3
+                value = `new BABYLON.Color3(${value.r}, ${value.g}, ${value.b})`;
+                if (event.object._isLinearColor) {
+                    value += '.toLinearSpace()';
+                }
+            } else if (value.getClassName) {
+                value = this._getIndirectData(value);
+            }
         }
 
         let target = this._getIndirectData(event.object);

+ 1 - 1
package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.2.0-alpha.0",
+    "version": "4.2.0-alpha.1",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 22 - 2
src/Cameras/Inputs/freeCameraKeyboardMoveInput.ts

@@ -24,12 +24,24 @@ export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
     public keysUp = [38];
 
     /**
+     * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+     */
+    @serialize()
+    public keysUpward = [33];
+
+    /**
      * Gets or Set the list of keyboard keys used to control the backward move of the camera.
      */
     @serialize()
     public keysDown = [40];
 
     /**
+     * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+     */
+    @serialize()
+    public keysDownward = [34];
+
+    /**
      * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
      */
     @serialize()
@@ -71,7 +83,9 @@ export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
                     if (this.keysUp.indexOf(evt.keyCode) !== -1 ||
                         this.keysDown.indexOf(evt.keyCode) !== -1 ||
                         this.keysLeft.indexOf(evt.keyCode) !== -1 ||
-                        this.keysRight.indexOf(evt.keyCode) !== -1) {
+                        this.keysRight.indexOf(evt.keyCode) !== -1 ||
+                        this.keysUpward.indexOf(evt.keyCode) !== -1 ||
+                        this.keysDownward.indexOf(evt.keyCode) !== -1) {
                         var index = this._keys.indexOf(evt.keyCode);
 
                         if (index === -1) {
@@ -85,7 +99,9 @@ export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
                     if (this.keysUp.indexOf(evt.keyCode) !== -1 ||
                         this.keysDown.indexOf(evt.keyCode) !== -1 ||
                         this.keysLeft.indexOf(evt.keyCode) !== -1 ||
-                        this.keysRight.indexOf(evt.keyCode) !== -1) {
+                        this.keysRight.indexOf(evt.keyCode) !== -1 ||
+                        this.keysUpward.indexOf(evt.keyCode) !== -1 ||
+                        this.keysDownward.indexOf(evt.keyCode) !== -1) {
                         var index = this._keys.indexOf(evt.keyCode);
 
                         if (index >= 0) {
@@ -139,6 +155,10 @@ export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
                     camera._localDirection.copyFromFloats(speed, 0, 0);
                 } else if (this.keysDown.indexOf(keyCode) !== -1) {
                     camera._localDirection.copyFromFloats(0, 0, -speed);
+                } else if (this.keysUpward.indexOf(keyCode) !== -1) {
+                    camera._localDirection.copyFromFloats(0, speed, 0);
+                } else if (this.keysDownward.indexOf(keyCode) !== -1) {
+                    camera._localDirection.copyFromFloats(0, -speed, 0);
                 }
 
                 if (camera.getScene().useRightHandedSystem) {

+ 38 - 0
src/Cameras/freeCamera.ts

@@ -94,6 +94,25 @@ export class FreeCamera extends TargetCamera {
     }
 
     /**
+     * Gets or Set the list of keyboard keys used to control the upward move of the camera.
+     */
+    public get keysUpward(): number[] {
+        var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
+        if (keyboard) {
+            return keyboard.keysUpward;
+        }
+
+        return [];
+    }
+
+    public set keysUpward(value: number[]) {
+        var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
+        if (keyboard) {
+            keyboard.keysUpward = value;
+        }
+    }
+
+    /**
      * Gets or Set the list of keyboard keys used to control the backward move of the camera.
      */
     public get keysDown(): number[] {
@@ -112,6 +131,25 @@ export class FreeCamera extends TargetCamera {
         }
     }
 
+     /**
+     * Gets or Set the list of keyboard keys used to control the downward move of the camera.
+     */
+    public get keysDownward(): number[] {
+        var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
+        if (keyboard) {
+            return keyboard.keysDownward;
+        }
+
+        return [];
+    }
+
+    public set keysDownward(value: number[]) {
+        var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
+        if (keyboard) {
+            keyboard.keysDownward = value;
+        }
+    }
+
     /**
      * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
      */

+ 2 - 2
src/Engines/thinEngine.ts

@@ -132,14 +132,14 @@ export class ThinEngine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.2.0-alpha.0";
+        return "babylonjs@4.2.0-alpha.1";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.2.0-alpha.0";
+        return "4.2.0-alpha.1";
     }
 
     /**

+ 1 - 1
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -376,7 +376,7 @@ export class TextureBlock extends NodeMaterialBlock {
             return "";
         }
 
-        var codeString = `${this._codeVariableName}.texture = new BABYLON.Texture("${this.texture.name}");\r\n`;
+        var codeString = `${this._codeVariableName}.texture = new BABYLON.Texture("${this.texture.name}", null);\r\n`;
         codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\r\n`;
         codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\r\n`;
         codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\r\n`;

+ 5 - 53
src/Materials/PBR/pbrBaseMaterial.ts

@@ -269,23 +269,23 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     /**
      * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.
      */
-    public static readonly PBRMATERIAL_OPAQUE = 0;
+    public static readonly PBRMATERIAL_OPAQUE = Material.MATERIAL_OPAQUE;
 
     /**
      * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
      */
-    public static readonly PBRMATERIAL_ALPHATEST = 1;
+    public static readonly PBRMATERIAL_ALPHATEST = Material.MATERIAL_ALPHATEST;
 
     /**
      * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
      */
-    public static readonly PBRMATERIAL_ALPHABLEND = 2;
+    public static readonly PBRMATERIAL_ALPHABLEND = Material.MATERIAL_ALPHABLEND;
 
     /**
      * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
      * They are also discarded below the alpha cutoff threshold to improve performances.
      */
-    public static readonly PBRMATERIAL_ALPHATESTANDBLEND = 3;
+    public static readonly PBRMATERIAL_ALPHATESTANDBLEND = Material.MATERIAL_ALPHATESTANDBLEND;
 
     /**
      * Defines the default value of how much AO map is occluding the analytical lights
@@ -608,11 +608,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     protected _useLinearAlphaFresnel = false;
 
     /**
-     * The transparency mode of the material.
-     */
-    protected _transparencyMode: Nullable<number> = null;
-
-    /**
      * Specifies the environment BRDF texture used to comput the scale and offset roughness values
      * from cos thetav and roughness:
      * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
@@ -818,40 +813,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     }
 
     /**
-     * Gets the current transparency mode.
-     */
-    @serialize()
-    public get transparencyMode(): Nullable<number> {
-        return this._transparencyMode;
-    }
-
-    /**
-     * Sets the transparency mode of the material.
-     *
-     * | Value | Type                                | Description |
-     * | ----- | ----------------------------------- | ----------- |
-     * | 0     | OPAQUE                              |             |
-     * | 1     | ALPHATEST                           |             |
-     * | 2     | ALPHABLEND                          |             |
-     * | 3     | ALPHATESTANDBLEND                   |             |
-     *
-     */
-    public set transparencyMode(value: Nullable<number>) {
-        if (this._transparencyMode === value) {
-            return;
-        }
-
-        this._transparencyMode = value;
-
-        this._forceAlphaTest = (value === PBRBaseMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
-
-        this._markAllSubMeshesAsTexturesAndMiscDirty();
-    }
-
-    /**
      * Returns true if alpha blending should be disabled.
      */
-    private get _disableAlphaBlending(): boolean {
+    protected get _disableAlphaBlending(): boolean {
         return (this.subSurface.disableAlphaBlending ||
             this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_OPAQUE ||
             this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);
@@ -869,18 +833,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     }
 
     /**
-     * Specifies if the mesh will require alpha blending.
-     * @param mesh - BJS mesh.
-     */
-    public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
-        if (this._disableAlphaBlending && mesh.visibility >= 1.0) {
-            return false;
-        }
-
-        return super.needAlphaBlendingForMesh(mesh);
-    }
-
-    /**
      * Specifies whether or not this material should be rendered in alpha test mode.
      */
     public needAlphaTesting(): boolean {

+ 92 - 10
src/Materials/material.ts

@@ -123,6 +123,27 @@ export class Material implements IAnimatable {
     public static readonly AllDirtyFlag = Constants.MATERIAL_AllDirtyFlag;
 
     /**
+     * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
+     */
+    public static readonly MATERIAL_OPAQUE = 0;
+
+    /**
+     * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
+     */
+    public static readonly MATERIAL_ALPHATEST = 1;
+
+    /**
+     * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+     */
+    public static readonly MATERIAL_ALPHABLEND = 2;
+
+    /**
+     * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
+     * They are also discarded below the alpha cutoff threshold to improve performances.
+     */
+    public static readonly MATERIAL_ALPHATESTANDBLEND = 3;
+
+    /**
      * The ID of the material
      */
     @serialize()
@@ -668,10 +689,63 @@ export class Material implements IAnimatable {
     }
 
     /**
-     * Specifies if the material will require alpha blending
+     * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
+     */
+    protected _forceAlphaTest = false;
+
+    /**
+     * The transparency mode of the material.
+     */
+    protected _transparencyMode: Nullable<number> = null;
+
+    /**
+     * Gets the current transparency mode.
+     */
+    @serialize()
+    public get transparencyMode(): Nullable<number> {
+        return this._transparencyMode;
+    }
+
+    /**
+     * Sets the transparency mode of the material.
+     *
+     * | Value | Type                                | Description |
+     * | ----- | ----------------------------------- | ----------- |
+     * | 0     | OPAQUE                              |             |
+     * | 1     | ALPHATEST                           |             |
+     * | 2     | ALPHABLEND                          |             |
+     * | 3     | ALPHATESTANDBLEND                   |             |
+     *
+     */
+    public set transparencyMode(value: Nullable<number>) {
+        if (this._transparencyMode === value) {
+            return;
+        }
+
+        this._transparencyMode = value;
+
+        this._forceAlphaTest = (value === Material.MATERIAL_ALPHATESTANDBLEND);
+
+        this._markAllSubMeshesAsTexturesAndMiscDirty();
+    }
+
+    /**
+     * Returns true if alpha blending should be disabled.
+     */
+    protected get _disableAlphaBlending(): boolean {
+        return (this._transparencyMode === Material.MATERIAL_OPAQUE ||
+                this._transparencyMode === Material.MATERIAL_ALPHATEST);
+    }
+
+    /**
+     * Specifies whether or not this material should be rendered in alpha blend mode.
      * @returns a boolean specifying if alpha blending is needed
      */
     public needAlphaBlending(): boolean {
+        if (this._disableAlphaBlending) {
+            return false;
+        }
+
         return (this.alpha < 1.0);
     }
 
@@ -681,18 +755,34 @@ export class Material implements IAnimatable {
      * @returns a boolean specifying if alpha blending is needed for the mesh
      */
     public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
+        if (this._disableAlphaBlending && mesh.visibility >= 1.0) {
+            return false;
+        }
+
         return this.needAlphaBlending() || (mesh.visibility < 1.0) || mesh.hasVertexAlpha;
     }
 
     /**
-     * Specifies if this material should be rendered in alpha test mode
+     * Specifies whether or not this material should be rendered in alpha test mode.
      * @returns a boolean specifying if an alpha test is needed.
      */
     public needAlphaTesting(): boolean {
+        if (this._forceAlphaTest) {
+            return true;
+        }
+
         return false;
     }
 
     /**
+     * Specifies if material alpha testing should be turned on for the mesh
+     * @param mesh defines the mesh to check
+     */
+    protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean {
+        return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+    }
+
+    /**
      * Gets the texture used for the alpha test
      * @returns the texture to use for alpha testing
      */
@@ -794,14 +884,6 @@ export class Material implements IAnimatable {
     }
 
     /**
-     * Specifies if material alpha testing should be turned on for the mesh
-     * @param mesh defines the mesh to check
-     */
-    protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean {
-        return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
-    }
-
-    /**
      * Processes to execute after binding the material to a mesh
      * @param mesh defines the rendered mesh
      */

+ 19 - 4
src/Materials/standardMaterial.ts

@@ -15,6 +15,7 @@ import { Mesh } from "../Meshes/mesh";
 import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } from "./imageProcessingConfiguration";
 import { ColorCurves } from "./colorCurves";
 import { FresnelParameters } from "./fresnelParameters";
+import { Material } from "../Materials/material";
 import { MaterialDefines } from "../Materials/materialDefines";
 import { PushMaterial } from "./pushMaterial";
 import { MaterialHelper } from "./materialHelper";
@@ -114,6 +115,8 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public NUM_MORPH_INFLUENCERS = 0;
     public NONUNIFORMSCALING = false; // https://playground.babylonjs.com#V6DWIH
     public PREMULTIPLYALPHA = false; // https://playground.babylonjs.com#LNVJJ7
+    public ALPHATEST_AFTERALLALPHACOMPUTATIONS = false;
+    public ALPHABLEND = true;
 
     public IMAGEPROCESSING = false;
     public VIGNETTE = false;
@@ -286,7 +289,7 @@ export class StandardMaterial extends PushMaterial {
     /**
      * Does the transparency come from the diffuse texture alpha channel.
      */
-    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
     public useAlphaFromDiffuseTexture: boolean;
 
     @serialize("useEmissiveAsIllumination")
@@ -744,6 +747,10 @@ export class StandardMaterial extends PushMaterial {
      * @returns a boolean specifying if alpha blending is needed
      */
     public needAlphaBlending(): boolean {
+        if (this._disableAlphaBlending) {
+            return false;
+        }
+
         return (this.alpha < 1.0) || (this._opacityTexture != null) || this._shouldUseAlphaFromDiffuseTexture() || this._opacityFresnelParameters && this._opacityFresnelParameters.isEnabled;
     }
 
@@ -752,11 +759,15 @@ export class StandardMaterial extends PushMaterial {
      * @returns a boolean specifying if an alpha test is needed.
      */
     public needAlphaTesting(): boolean {
-        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha;
+        if (this._forceAlphaTest) {
+            return true;
+        }
+
+        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha && (this._transparencyMode == null || this._transparencyMode === Material.MATERIAL_ALPHATEST);
     }
 
     protected _shouldUseAlphaFromDiffuseTexture(): boolean {
-        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha && this._useAlphaFromDiffuseTexture;
+        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha && this._useAlphaFromDiffuseTexture && this._transparencyMode !== Material.MATERIAL_OPAQUE;
     }
 
     /**
@@ -971,6 +982,10 @@ export class StandardMaterial extends PushMaterial {
             defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
 
             defines.PREMULTIPLYALPHA = (this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF);
+
+            defines.ALPHATEST_AFTERALLALPHACOMPUTATIONS = this.transparencyMode !== null;
+
+            defines.ALPHABLEND = this.transparencyMode === null || this.needAlphaBlendingForMesh(mesh); // check on null for backward compatibility
         }
 
         if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
@@ -1012,7 +1027,7 @@ export class StandardMaterial extends PushMaterial {
         }
 
         // Misc.
-        MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
 
         // Attribs
         MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);

+ 12 - 1
src/Shaders/default.fragment.fx

@@ -195,7 +195,7 @@ void main(void) {
 #ifdef DIFFUSE
 	baseColor = texture2D(diffuseSampler, vDiffuseUV + uvOffset);
 
-	#ifdef ALPHATEST
+	#if defined(ALPHATEST) && !defined(ALPHATEST_AFTERALLALPHACOMPUTATIONS)
 		if (baseColor.a < alphaCutOff)
 			discard;
 	#endif
@@ -363,6 +363,17 @@ vec3 reflectionColor = vec3(0., 0., 0.);
 	alpha += opacityParts.x * (1.0 - opacityFresnelTerm) + opacityFresnelTerm * opacityParts.y;
 #endif
 
+#ifdef ALPHATEST
+    #ifdef ALPHATEST_AFTERALLALPHACOMPUTATIONS
+        if (alpha < alphaCutOff)
+            discard;
+    #endif
+    #ifndef ALPHABLEND
+        // Prevent to blend with the canvas.
+        alpha = 1.0;
+    #endif
+#endif
+
 	// Emissive
 	vec3 emissiveColor = vEmissiveColor;
 #ifdef EMISSIVE