ソースを参照

Merge pull request #7751 from BabylonJS/master

Nightly
mergify[bot] 5 年 前
コミット
1425d1bb30
46 ファイル変更1400 行追加221 行削除
  1. 41 0
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 148 65
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 82 0
      dist/preview release/babylon.module.d.ts
  6. 67 1
      dist/preview release/documentation.d.ts
  7. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  8. 12 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  9. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  10. 139 18
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  11. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  12. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  13. 139 18
      dist/preview release/loaders/babylon.glTFFileLoader.js
  14. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  15. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  16. 26 1
      dist/preview release/loaders/babylonjs.loaders.d.ts
  17. 139 18
      dist/preview release/loaders/babylonjs.loaders.js
  18. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  19. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  20. 59 3
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  21. 1 1
      dist/preview release/packagesSizeBaseLine.json
  22. 82 0
      dist/preview release/viewer/babylon.module.d.ts
  23. 25 21
      dist/preview release/viewer/babylon.viewer.js
  24. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  25. 59 3
      dist/preview release/viewer/babylonjs.loaders.module.d.ts
  26. 9 0
      dist/preview release/what's new.md
  27. 13 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx
  28. 9 0
      loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts
  29. 112 0
      loaders/src/glTF/2.0/Extensions/KHR_mesh_instancing.ts
  30. 1 0
      loaders/src/glTF/2.0/Extensions/index.ts
  31. 2 1
      loaders/src/glTF/2.0/glTFLoader.ts
  32. 25 9
      src/Gizmos/boundingBoxGizmo.ts
  33. 2 0
      src/Materials/PBR/pbrBaseMaterial.ts
  34. 32 1
      src/Materials/PBR/pbrSheenConfiguration.ts
  35. 13 0
      src/Maths/math.vector.ts
  36. 13 0
      src/Misc/stringTools.ts
  37. 6 0
      src/Shaders/ShadersInclude/lightFragment.fx
  38. 41 1
      src/Shaders/ShadersInclude/pbrBRDFFunctions.fx
  39. 6 2
      src/Shaders/ShadersInclude/pbrDirectLightingFunctions.fx
  40. 3 0
      src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx
  41. 1 0
      src/Shaders/ShadersInclude/pbrUboDeclaration.fx
  42. 77 41
      src/Shaders/pbr.fragment.fx
  43. BIN
      tests/validation/ReferenceImages/Gizmos.png
  44. BIN
      tests/validation/ReferenceImages/nested_BBG.png
  45. BIN
      tests/validation/ReferenceImages/simulatePointer.png
  46. 1 1
      tests/validation/config.json

+ 41 - 0
dist/preview release/babylon.d.ts

@@ -404,6 +404,13 @@ declare module BABYLON {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module BABYLON {
@@ -3730,6 +3737,13 @@ declare module BABYLON {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -8533,6 +8547,15 @@ declare module BABYLON {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -50339,6 +50362,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -50371,6 +50396,20 @@ declare module BABYLON {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -50963,6 +51002,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;

ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/babylon.js


ファイルの差分が大きいため隠しています
+ 148 - 65
dist/preview release/babylon.max.js


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/babylon.max.js.map


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

@@ -405,6 +405,13 @@ declare module "babylonjs/Misc/stringTools" {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module "babylonjs/Misc/deepCopier" {
@@ -3763,6 +3770,13 @@ declare module "babylonjs/Maths/math.vector" {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -8644,6 +8658,15 @@ declare module "babylonjs/Cameras/targetCamera" {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -52460,6 +52483,8 @@ declare module "babylonjs/Materials/PBR/pbrSheenConfiguration" {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -52492,6 +52517,20 @@ declare module "babylonjs/Materials/PBR/pbrSheenConfiguration" {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -53167,6 +53206,8 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;
@@ -73817,6 +73858,13 @@ declare module BABYLON {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module BABYLON {
@@ -77143,6 +77191,13 @@ declare module BABYLON {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -81946,6 +82001,15 @@ declare module BABYLON {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -123752,6 +123816,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -123784,6 +123850,20 @@ declare module BABYLON {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -124376,6 +124456,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;

+ 67 - 1
dist/preview release/documentation.d.ts

@@ -404,6 +404,13 @@ declare module BABYLON {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module BABYLON {
@@ -3730,6 +3737,13 @@ declare module BABYLON {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -8533,6 +8547,15 @@ declare module BABYLON {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -50339,6 +50362,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -50371,6 +50396,20 @@ declare module BABYLON {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -50963,6 +51002,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;
@@ -75795,7 +75836,8 @@ declare module BABYLON.GLTF2 {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -76170,6 +76212,30 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
      */
     export class KHR_mesh_quantization implements IGLTFLoaderExtension {

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


+ 12 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -45593,6 +45593,7 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
     };
     PBRMaterialPropertyGridComponent.prototype.render = function () {
         var _this = this;
+        var _a, _b, _c;
         var material = this.props.material;
         var debugMode = [
             { label: "None", value: 0 },
@@ -45656,6 +45657,12 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
             { label: "Luminance Over Alpha", value: 86 },
             { label: "Alpha", value: 87 },
         ];
+        material.sheen._useRoughness = (_a = material.sheen._useRoughness, (_a !== null && _a !== void 0 ? _a : material.sheen.roughness !== null));
+        material.sheen.roughness = (_c = (_b = material.sheen.roughness, (_b !== null && _b !== void 0 ? _b : material.sheen._saveRoughness)), (_c !== null && _c !== void 0 ? _c : 0));
+        if (!material.sheen._useRoughness) {
+            material.sheen._saveRoughness = material.sheen.roughness;
+            material.sheen.roughness = null;
+        }
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "pane" },
             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),
@@ -45705,7 +45712,11 @@ var PBRMaterialPropertyGridComponent = /** @class */ (function (_super) {
                         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_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_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 &&
+                            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Roughness", target: material.sheen, propertyName: "roughness", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Albedo scaling", target: material.sheen, propertyName: "albedoScaling", onPropertyChangedObservable: this.props.onPropertyChangedObservable }))),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "SUBSURFACE" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textureLinkLineComponent__WEBPACK_IMPORTED_MODULE_10__["TextureLinkLineComponent"], { label: "Thickness", texture: material.subSurface.thicknessTexture, material: material, onSelectionChangedObservable: this.props.onSelectionChangedObservable, onDebugSelectionChangeObservable: this._onDebugSelectionChangeObservable }),
                 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 }),

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 139 - 18
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -777,6 +777,13 @@ var KHR_materials_sheen = /** @class */ (function () {
                 babylonMaterial.sheen.texture = texture;
             }));
         }
+        if (properties.roughnessFactor !== undefined) {
+            babylonMaterial.sheen.roughness = properties.roughnessFactor;
+        }
+        else {
+            babylonMaterial.sheen.roughness = 0;
+        }
+        babylonMaterial.sheen.albedoScaling = true;
         return Promise.all(promises).then(function () { });
     };
     return KHR_materials_sheen;
@@ -939,6 +946,113 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts":
+/*!****************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_instancing.ts ***!
+  \****************************************************/
+/*! exports provided: KHR_mesh_instancing */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return KHR_mesh_instancing; });
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+
+
+var NAME = "KHR_mesh_instancing";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+ * [Playground Sample](//TODO)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_mesh_instancing = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_instancing(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this._loader = loader;
+        this.enabled = this._loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_instancing.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_mesh_instancing.prototype.loadNodeAsync = function (context, node, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
+            return _this._loader.loadNodeAsync("#/nodes/" + node.index, node, function (babylonTransformNode) {
+                var promises = new Array();
+                var instanceCount = null;
+                var loadAttribute = function (attribute, assignBufferFunc) {
+                    if (extension.attributes[attribute] == undefined) {
+                        return;
+                    }
+                    var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["ArrayItem"].Get(extensionContext + "/attributes/" + attribute, _this._loader.gltf.accessors, extension.attributes[attribute]);
+                    if (instanceCount === null) {
+                        instanceCount = accessor.count;
+                    }
+                    else if (instanceCount !== accessor.count) {
+                        throw new Error(extensionContext + "/attributes: Instance buffer accessors do not have the same count.");
+                    }
+                    promises.push(_this._loader._loadFloatAccessorAsync("/accessors/" + accessor.bufferView, accessor).then(function (data) {
+                        assignBufferFunc(data);
+                    }));
+                };
+                var translationBuffer = null;
+                var rotationBuffer = null;
+                var scaleBuffer = null;
+                loadAttribute("TRANSLATION", function (data) { translationBuffer = data; });
+                loadAttribute("ROTATION", function (data) { rotationBuffer = data; });
+                loadAttribute("SCALE", function (data) { scaleBuffer = data; });
+                return Promise.all(promises).then(function () {
+                    if (instanceCount) {
+                        var instanceName = "";
+                        var instance = null;
+                        var digitLength = instanceCount.toString().length;
+                        for (var i = 0; i < instanceCount; ++i) {
+                            if (node._primitiveBabylonMeshes) {
+                                for (var j = 0; j < node._primitiveBabylonMeshes.length; ++j) {
+                                    var babylonMeshPrimitive = node._primitiveBabylonMeshes[j];
+                                    instanceName = (babylonMeshPrimitive.name || babylonMeshPrimitive.id) + "_" + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["StringTools"].PadNumber(i, digitLength);
+                                    if (babylonMeshPrimitive.isAnInstance) {
+                                        instance = babylonMeshPrimitive.sourceMesh.createInstance(instanceName);
+                                    }
+                                    else if (babylonMeshPrimitive.createInstance) {
+                                        instance = babylonMeshPrimitive.createInstance(instanceName);
+                                    }
+                                    if (instance) {
+                                        instance.setParent(babylonMeshPrimitive);
+                                        translationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(translationBuffer, i * 3, instance.position)
+                                            : instance.position.set(0, 0, 0);
+                                        rotationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArrayToRef(rotationBuffer, i * 4, instance.rotationQuaternion)
+                                            : instance.rotationQuaternion.set(0, 0, 0, 1);
+                                        scaleBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(scaleBuffer, i * 3, instance.scaling)
+                                            : instance.scaling.set(1, 1, 1);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    assign(babylonTransformNode);
+                    return babylonTransformNode;
+                });
+            });
+        });
+    };
+    return KHR_mesh_instancing;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_instancing(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
@@ -1778,7 +1892,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -1807,29 +1921,32 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
+/* harmony import */ var _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_instancing */ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_instancing"]; });
+
+/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__["KHR_mesh_quantization"]; });
 
-/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_basisu"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__["KHR_texture_transform"]; });
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__["MSFT_audio_emitter"]; });
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__["MSFT_lod"]; });
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__["MSFT_minecraftMesh"]; });
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__["MSFT_sRGBFactors"]; });
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__["ExtrasAsMetadata"]; });
 
 
 
@@ -1847,6 +1964,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -3210,6 +3328,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         return accessor._data;
     };
+    /** @hidden */
     GLTFLoader.prototype._loadFloatAccessorAsync = function (context, accessor) {
         return this._loadAccessorAsync(context, accessor, Float32Array);
     };
@@ -4007,7 +4126,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4034,6 +4153,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_instancing"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 139 - 18
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3357,6 +3357,13 @@ var KHR_materials_sheen = /** @class */ (function () {
                 babylonMaterial.sheen.texture = texture;
             }));
         }
+        if (properties.roughnessFactor !== undefined) {
+            babylonMaterial.sheen.roughness = properties.roughnessFactor;
+        }
+        else {
+            babylonMaterial.sheen.roughness = 0;
+        }
+        babylonMaterial.sheen.albedoScaling = true;
         return Promise.all(promises).then(function () { });
     };
     return KHR_materials_sheen;
@@ -3519,6 +3526,113 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts":
+/*!****************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_instancing.ts ***!
+  \****************************************************/
+/*! exports provided: KHR_mesh_instancing */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return KHR_mesh_instancing; });
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+
+
+var NAME = "KHR_mesh_instancing";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+ * [Playground Sample](//TODO)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_mesh_instancing = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_instancing(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this._loader = loader;
+        this.enabled = this._loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_instancing.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_mesh_instancing.prototype.loadNodeAsync = function (context, node, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
+            return _this._loader.loadNodeAsync("#/nodes/" + node.index, node, function (babylonTransformNode) {
+                var promises = new Array();
+                var instanceCount = null;
+                var loadAttribute = function (attribute, assignBufferFunc) {
+                    if (extension.attributes[attribute] == undefined) {
+                        return;
+                    }
+                    var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["ArrayItem"].Get(extensionContext + "/attributes/" + attribute, _this._loader.gltf.accessors, extension.attributes[attribute]);
+                    if (instanceCount === null) {
+                        instanceCount = accessor.count;
+                    }
+                    else if (instanceCount !== accessor.count) {
+                        throw new Error(extensionContext + "/attributes: Instance buffer accessors do not have the same count.");
+                    }
+                    promises.push(_this._loader._loadFloatAccessorAsync("/accessors/" + accessor.bufferView, accessor).then(function (data) {
+                        assignBufferFunc(data);
+                    }));
+                };
+                var translationBuffer = null;
+                var rotationBuffer = null;
+                var scaleBuffer = null;
+                loadAttribute("TRANSLATION", function (data) { translationBuffer = data; });
+                loadAttribute("ROTATION", function (data) { rotationBuffer = data; });
+                loadAttribute("SCALE", function (data) { scaleBuffer = data; });
+                return Promise.all(promises).then(function () {
+                    if (instanceCount) {
+                        var instanceName = "";
+                        var instance = null;
+                        var digitLength = instanceCount.toString().length;
+                        for (var i = 0; i < instanceCount; ++i) {
+                            if (node._primitiveBabylonMeshes) {
+                                for (var j = 0; j < node._primitiveBabylonMeshes.length; ++j) {
+                                    var babylonMeshPrimitive = node._primitiveBabylonMeshes[j];
+                                    instanceName = (babylonMeshPrimitive.name || babylonMeshPrimitive.id) + "_" + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["StringTools"].PadNumber(i, digitLength);
+                                    if (babylonMeshPrimitive.isAnInstance) {
+                                        instance = babylonMeshPrimitive.sourceMesh.createInstance(instanceName);
+                                    }
+                                    else if (babylonMeshPrimitive.createInstance) {
+                                        instance = babylonMeshPrimitive.createInstance(instanceName);
+                                    }
+                                    if (instance) {
+                                        instance.setParent(babylonMeshPrimitive);
+                                        translationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(translationBuffer, i * 3, instance.position)
+                                            : instance.position.set(0, 0, 0);
+                                        rotationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArrayToRef(rotationBuffer, i * 4, instance.rotationQuaternion)
+                                            : instance.rotationQuaternion.set(0, 0, 0, 1);
+                                        scaleBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(scaleBuffer, i * 3, instance.scaling)
+                                            : instance.scaling.set(1, 1, 1);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    assign(babylonTransformNode);
+                    return babylonTransformNode;
+                });
+            });
+        });
+    };
+    return KHR_mesh_instancing;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_instancing(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
@@ -4358,7 +4472,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4387,29 +4501,32 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
+/* harmony import */ var _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_instancing */ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_instancing"]; });
+
+/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__["KHR_mesh_quantization"]; });
 
-/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_basisu"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__["KHR_texture_transform"]; });
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__["MSFT_audio_emitter"]; });
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__["MSFT_lod"]; });
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__["MSFT_minecraftMesh"]; });
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__["MSFT_sRGBFactors"]; });
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__["ExtrasAsMetadata"]; });
 
 
 
@@ -4427,6 +4544,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -5790,6 +5908,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         return accessor._data;
     };
+    /** @hidden */
     GLTFLoader.prototype._loadFloatAccessorAsync = function (context, accessor) {
         return this._loadAccessorAsync(context, accessor, Float32Array);
     };
@@ -6587,7 +6706,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -6614,6 +6733,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_instancing"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 26 - 1
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -1479,7 +1479,8 @@ declare module BABYLON.GLTF2 {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -1854,6 +1855,30 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
      */
     export class KHR_mesh_quantization implements IGLTFLoaderExtension {

+ 139 - 18
dist/preview release/loaders/babylonjs.loaders.js

@@ -4737,6 +4737,13 @@ var KHR_materials_sheen = /** @class */ (function () {
                 babylonMaterial.sheen.texture = texture;
             }));
         }
+        if (properties.roughnessFactor !== undefined) {
+            babylonMaterial.sheen.roughness = properties.roughnessFactor;
+        }
+        else {
+            babylonMaterial.sheen.roughness = 0;
+        }
+        babylonMaterial.sheen.albedoScaling = true;
         return Promise.all(promises).then(function () { });
     };
     return KHR_materials_sheen;
@@ -4899,6 +4906,113 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts":
+/*!****************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_instancing.ts ***!
+  \****************************************************/
+/*! exports provided: KHR_mesh_instancing */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return KHR_mesh_instancing; });
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+
+
+var NAME = "KHR_mesh_instancing";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+ * [Playground Sample](//TODO)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_mesh_instancing = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_instancing(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this._loader = loader;
+        this.enabled = this._loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_instancing.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_mesh_instancing.prototype.loadNodeAsync = function (context, node, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) {
+            return _this._loader.loadNodeAsync("#/nodes/" + node.index, node, function (babylonTransformNode) {
+                var promises = new Array();
+                var instanceCount = null;
+                var loadAttribute = function (attribute, assignBufferFunc) {
+                    if (extension.attributes[attribute] == undefined) {
+                        return;
+                    }
+                    var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["ArrayItem"].Get(extensionContext + "/attributes/" + attribute, _this._loader.gltf.accessors, extension.attributes[attribute]);
+                    if (instanceCount === null) {
+                        instanceCount = accessor.count;
+                    }
+                    else if (instanceCount !== accessor.count) {
+                        throw new Error(extensionContext + "/attributes: Instance buffer accessors do not have the same count.");
+                    }
+                    promises.push(_this._loader._loadFloatAccessorAsync("/accessors/" + accessor.bufferView, accessor).then(function (data) {
+                        assignBufferFunc(data);
+                    }));
+                };
+                var translationBuffer = null;
+                var rotationBuffer = null;
+                var scaleBuffer = null;
+                loadAttribute("TRANSLATION", function (data) { translationBuffer = data; });
+                loadAttribute("ROTATION", function (data) { rotationBuffer = data; });
+                loadAttribute("SCALE", function (data) { scaleBuffer = data; });
+                return Promise.all(promises).then(function () {
+                    if (instanceCount) {
+                        var instanceName = "";
+                        var instance = null;
+                        var digitLength = instanceCount.toString().length;
+                        for (var i = 0; i < instanceCount; ++i) {
+                            if (node._primitiveBabylonMeshes) {
+                                for (var j = 0; j < node._primitiveBabylonMeshes.length; ++j) {
+                                    var babylonMeshPrimitive = node._primitiveBabylonMeshes[j];
+                                    instanceName = (babylonMeshPrimitive.name || babylonMeshPrimitive.id) + "_" + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["StringTools"].PadNumber(i, digitLength);
+                                    if (babylonMeshPrimitive.isAnInstance) {
+                                        instance = babylonMeshPrimitive.sourceMesh.createInstance(instanceName);
+                                    }
+                                    else if (babylonMeshPrimitive.createInstance) {
+                                        instance = babylonMeshPrimitive.createInstance(instanceName);
+                                    }
+                                    if (instance) {
+                                        instance.setParent(babylonMeshPrimitive);
+                                        translationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(translationBuffer, i * 3, instance.position)
+                                            : instance.position.set(0, 0, 0);
+                                        rotationBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArrayToRef(rotationBuffer, i * 4, instance.rotationQuaternion)
+                                            : instance.rotationQuaternion.set(0, 0, 0, 1);
+                                        scaleBuffer ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(scaleBuffer, i * 3, instance.scaling)
+                                            : instance.scaling.set(1, 1, 1);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    assign(babylonTransformNode);
+                    return babylonTransformNode;
+                });
+            });
+        });
+    };
+    return KHR_mesh_instancing;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_instancing(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
@@ -5738,7 +5852,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -5767,29 +5881,32 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
+/* harmony import */ var _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_instancing */ "./glTF/2.0/Extensions/KHR_mesh_instancing.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _KHR_mesh_instancing__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_instancing"]; });
+
+/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_9__["KHR_mesh_quantization"]; });
 
-/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_basisu"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_11__["KHR_texture_transform"]; });
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_12__["MSFT_audio_emitter"]; });
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_13__["MSFT_lod"]; });
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_14__["MSFT_minecraftMesh"]; });
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_15__["MSFT_sRGBFactors"]; });
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_16__["ExtrasAsMetadata"]; });
 
 
 
@@ -5807,6 +5924,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -7170,6 +7288,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         return accessor._data;
     };
+    /** @hidden */
     GLTFLoader.prototype._loadFloatAccessorAsync = function (context, accessor) {
         return this._loadAccessorAsync(context, accessor, Float32Array);
     };
@@ -7967,7 +8086,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_instancing, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -7994,6 +8113,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_instancing", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_instancing"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 59 - 3
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1383,7 +1383,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { Scene } from "babylonjs/scene";
     import { IProperty } from "babylonjs-gltf2interface";
-    import { IGLTF, ISampler, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IGLTF, ISampler, INode, IScene, IMesh, IAccessor, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
@@ -1568,7 +1568,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -1982,6 +1983,35 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular" {
         private _loadSpecularPropertiesAsync;
     }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_instancing" {
+    import { TransformNode } from "babylonjs/Meshes/transformNode";
+    import { Nullable } from "babylonjs/types";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { INode } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
@@ -2245,6 +2275,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_clearcoat";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
+    export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_instancing";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
@@ -4113,7 +4144,8 @@ declare module BABYLON.GLTF2 {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -4488,6 +4520,30 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
      */
     export class KHR_mesh_quantization implements IGLTFLoaderExtension {

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

@@ -1 +1 @@
-{"thinEngineOnly":113669,"engineOnly":150272,"sceneOnly":505908,"minGridMaterial":636668,"minStandardMaterial":776628}
+{"thinEngineOnly":113745,"engineOnly":150348,"sceneOnly":506060,"minGridMaterial":636921,"minStandardMaterial":777051}

+ 82 - 0
dist/preview release/viewer/babylon.module.d.ts

@@ -405,6 +405,13 @@ declare module "babylonjs/Misc/stringTools" {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module "babylonjs/Misc/deepCopier" {
@@ -3763,6 +3770,13 @@ declare module "babylonjs/Maths/math.vector" {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -8644,6 +8658,15 @@ declare module "babylonjs/Cameras/targetCamera" {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -52460,6 +52483,8 @@ declare module "babylonjs/Materials/PBR/pbrSheenConfiguration" {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -52492,6 +52517,20 @@ declare module "babylonjs/Materials/PBR/pbrSheenConfiguration" {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -53167,6 +53206,8 @@ declare module "babylonjs/Materials/PBR/pbrBaseMaterial" {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;
@@ -73817,6 +73858,13 @@ declare module BABYLON {
          * @returns the encoded string
          */
         static EncodeArrayBufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string;
+        /**
+        * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+        * @param num the number to convert and pad
+        * @param length the expected length of the string
+        * @returns the padded string
+        */
+        static PadNumber(num: number, length: number): string;
     }
 }
 declare module BABYLON {
@@ -77143,6 +77191,13 @@ declare module BABYLON {
          */
         static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion;
         /**
+         * Updates the given quaternion "result" from the starting index of the given array.
+         * @param array the array to pull values from
+         * @param offset the offset into the array to start at
+         * @param result the quaternion to store the result in
+         */
+        static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void;
+        /**
          * Create a quaternion from Euler rotation angles
          * @param x Pitch
          * @param y Yaw
@@ -81946,6 +82001,15 @@ declare module BABYLON {
          */
         noRotationConstraint: boolean;
         /**
+         * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+         * panning
+         */
+        invertRotation: boolean;
+        /**
+         * Speed multiplier for inverse camera panning
+         */
+        inverseRotationSpeed: number;
+        /**
          * Define the current target of the camera as an object or a position.
          */
         lockedTarget: any;
@@ -123752,6 +123816,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         /** @hidden */
         _areTexturesDirty: boolean;
     }
@@ -123784,6 +123850,20 @@ declare module BABYLON {
          * a is a intensity
          */
         texture: Nullable<BaseTexture>;
+        private _roughness;
+        /**
+         * Defines the sheen roughness.
+         * It is not taken into account if linkSheenWithAlbedo is true.
+         * To stay backward compatible, material roughness is used instead if sheen roughness = null
+         */
+        roughness: Nullable<number>;
+        private _albedoScaling;
+        /**
+         * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+         * It allows the strength of the sheen effect to not depend on the base color of the material,
+         * making it easier to setup and tweak the effect
+         */
+        albedoScaling: boolean;
         /** @hidden */
         private _internalMarkAllSubMeshesAsTexturesDirty;
         /** @hidden */
@@ -124376,6 +124456,8 @@ declare module BABYLON {
         SHEEN_TEXTURE: boolean;
         SHEEN_TEXTUREDIRECTUV: number;
         SHEEN_LINKWITHALBEDO: boolean;
+        SHEEN_ROUGHNESS: boolean;
+        SHEEN_ALBEDOSCALING: boolean;
         SUBSURFACE: boolean;
         SS_REFRACTION: boolean;
         SS_TRANSLUCENCY: boolean;

ファイルの差分が大きいため隠しています
+ 25 - 21
dist/preview release/viewer/babylon.viewer.js


ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 59 - 3
dist/preview release/viewer/babylonjs.loaders.module.d.ts

@@ -1383,7 +1383,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { Scene } from "babylonjs/scene";
     import { IProperty } from "babylonjs-gltf2interface";
-    import { IGLTF, ISampler, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IGLTF, ISampler, INode, IScene, IMesh, IAccessor, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
@@ -1568,7 +1568,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -1982,6 +1983,35 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular" {
         private _loadSpecularPropertiesAsync;
     }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_instancing" {
+    import { TransformNode } from "babylonjs/Meshes/transformNode";
+    import { Nullable } from "babylonjs/types";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { INode } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
@@ -2245,6 +2275,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_clearcoat";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
+    export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_instancing";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
@@ -4113,7 +4144,8 @@ declare module BABYLON.GLTF2 {
          */
         loadBufferViewAsync(context: string, bufferView: IBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync;
-        private _loadFloatAccessorAsync;
+        /** @hidden */
+        _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array>;
         private _loadIndicesAccessorAsync;
         private _loadVertexBufferViewAsync;
         private _loadVertexAccessorAsync;
@@ -4488,6 +4520,30 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+     * [Playground Sample](//TODO)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
      */
     export class KHR_mesh_quantization implements IGLTFLoaderExtension {

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

@@ -8,6 +8,8 @@
 - NME Frames are now resizable from the corners ([Kyle Belfort](https://github.com/belfortk)
 - Refactored React refs from old string API to React.createRef() API ([Kyle Belfort](https://github.com/belfortk)
 
+- Scale on one axis for `BoundingBoxGizmo` ([cedricguillemet](https://github.com/cedricguillemet))
+
 ### Engine
 
 - Allow logging of shader code when a compilation error occurs ([Popov72](https://github.com/Popov72))
@@ -20,6 +22,13 @@
 
 - Ammo.js IDL exposed property update and raycast vehicle stablization support ([MackeyK24](https://github.com/MackeyK24))
 
+### Loaders
+- Added support for glTF mesh instancing extension ([#7521](https://github.com/BabylonJS/Babylon.js/issues/7521)) ([drigax](https://github.com/Drigax))
+
+
+### Materials
+- Added the `roughness` and `albedoScaling` parameters to PBR sheen ([Popov72](https://github.com/Popov72))
+
 ## Bugs
 
 - Fix infinite loop in `GlowLayer.unReferenceMeshFromUsingItsOwnMaterial` ([Popov72](https://github.com/Popov72)

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

@@ -128,6 +128,14 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
             { label: "Alpha", value: 87 },
         ];
 
+        (material.sheen as any)._useRoughness = (material.sheen as any)._useRoughness ?? material.sheen.roughness !== null;
+        material.sheen.roughness = material.sheen.roughness ?? (material.sheen as any)._saveRoughness ?? 0;
+
+        if (!(material.sheen as any)._useRoughness) {
+            (material.sheen as any)._saveRoughness = material.sheen.roughness;
+            material.sheen.roughness = null;
+        }
+
         return (
             <div className="pane">
                 <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -208,6 +216,11 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
                             <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} />
                             <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 &&
+                                <SliderLineComponent label="Roughness" target={material.sheen} propertyName="roughness" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                            }
+                            <CheckBoxLineComponent label="Albedo scaling" target={material.sheen} propertyName="albedoScaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                         </div>
                     }
                 </LineContainerComponent>

+ 9 - 0
loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts

@@ -13,6 +13,7 @@ interface IKHR_materials_sheen {
     intensityFactor: number;
     colorFactor: number[];
     colorIntensityTexture: ITextureInfo;
+    roughnessFactor: number;
 }
 
 /**
@@ -86,6 +87,14 @@ export class KHR_materials_sheen implements IGLTFLoaderExtension {
             }));
         }
 
+        if (properties.roughnessFactor !== undefined) {
+            babylonMaterial.sheen.roughness = properties.roughnessFactor;
+        } else {
+            babylonMaterial.sheen.roughness = 0;
+        }
+
+        babylonMaterial.sheen.albedoScaling = true;
+
         return Promise.all(promises).then(() => { });
     }
 }

+ 112 - 0
loaders/src/glTF/2.0/Extensions/KHR_mesh_instancing.ts

@@ -0,0 +1,112 @@
+import { Vector3, Quaternion } from 'babylonjs/Maths/math.vector';
+import { InstancedMesh } from 'babylonjs/Meshes/instancedMesh';
+import { Mesh } from 'babylonjs/Meshes/mesh';
+import { TransformNode } from "babylonjs/Meshes/transformNode";
+import { StringTools } from 'babylonjs/Misc/stringTools';
+import { Nullable } from "babylonjs/types";
+import { GLTFLoader, ArrayItem } from "../glTFLoader";
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
+import { INode } from "../glTFLoaderInterfaces";
+
+const NAME = "KHR_mesh_instancing";
+
+interface IKHRMeshInstancing {
+    mesh?: number;
+    attributes: { [name: string]: number };
+}
+
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1691)
+ * [Playground Sample](//TODO)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+export class KHR_mesh_instancing implements IGLTFLoaderExtension {
+    /**
+     * The name of this extension.
+     */
+    public readonly name = NAME;
+
+    /**
+     * Defines whether this extension is enabled.
+     */
+    public enabled: boolean;
+
+    private _loader: GLTFLoader;
+
+    /** @hidden */
+    constructor(loader: GLTFLoader) {
+        this._loader = loader;
+        this.enabled = this._loader.isExtensionUsed(NAME);
+    }
+
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+    }
+
+    /** @hidden */
+    public loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>> {
+        return GLTFLoader.LoadExtensionAsync<IKHRMeshInstancing, TransformNode>(context, node, this.name, (extensionContext, extension) => {
+            return this._loader.loadNodeAsync(`#/nodes/${node.index}`, node, (babylonTransformNode) => {
+                const promises = new Array<Promise<any>>();
+                let instanceCount: Nullable<number> = null;
+                const loadAttribute = (attribute: string, assignBufferFunc: (data: Float32Array) => void) => {
+                    if (extension.attributes[attribute] == undefined) {
+                        return;
+                    }
+                    const accessor = ArrayItem.Get(`${extensionContext}/attributes/${attribute}`, this._loader.gltf.accessors, extension.attributes[attribute]);
+                    if (instanceCount === null) {
+                        instanceCount = accessor.count;
+                    } else if (instanceCount !== accessor.count) {
+                        throw new Error(`${extensionContext}/attributes: Instance buffer accessors do not have the same count.`);
+                    }
+                    promises.push(this._loader._loadFloatAccessorAsync(`/accessors/${accessor.bufferView}`, accessor).then((data) => {
+                        assignBufferFunc(data);
+                    }));
+                };
+                let translationBuffer: Nullable<Float32Array> = null;
+                let rotationBuffer: Nullable<Float32Array> = null;
+                let scaleBuffer: Nullable<Float32Array> = null;
+
+                loadAttribute("TRANSLATION", (data) => { translationBuffer = data; });
+                loadAttribute("ROTATION", (data) => { rotationBuffer = data; });
+                loadAttribute("SCALE", (data) => { scaleBuffer = data; });
+
+                return Promise.all(promises).then(() => {
+                    if (instanceCount) {
+                        let instanceName: string = "";
+                        let instance: Nullable<TransformNode> = null;
+                        const digitLength = instanceCount.toString().length;
+
+                        for (let i = 0; i < instanceCount; ++i) {
+                            if (node._primitiveBabylonMeshes) {
+                                for (let j = 0; j < node._primitiveBabylonMeshes.length; ++j) {
+                                    const babylonMeshPrimitive = node._primitiveBabylonMeshes[j];
+                                    instanceName = (babylonMeshPrimitive.name || babylonMeshPrimitive.id) + "_" + StringTools.PadNumber(i, digitLength);
+                                    if (babylonMeshPrimitive.isAnInstance) {
+                                        instance = (babylonMeshPrimitive as InstancedMesh).sourceMesh.createInstance(instanceName);
+                                    } else if ((babylonMeshPrimitive as Mesh).createInstance) {
+                                        instance = (babylonMeshPrimitive as Mesh).createInstance(instanceName);
+                                    }
+                                    if (instance) {
+                                        instance.setParent(babylonMeshPrimitive);
+                                        translationBuffer ? Vector3.FromArrayToRef(translationBuffer, i * 3, instance.position)
+                                            : instance.position.set(0, 0, 0);
+                                        rotationBuffer ? Quaternion.FromArrayToRef(rotationBuffer, i * 4, instance.rotationQuaternion!)
+                                            : instance.rotationQuaternion!.set(0, 0, 0, 1);
+                                        scaleBuffer ? Vector3.FromArrayToRef(scaleBuffer, i * 3, instance.scaling)
+                                            : instance.scaling.set(1, 1, 1);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    assign(babylonTransformNode);
+                    return babylonTransformNode;
+                });
+            });
+        });
+    }
+}
+
+GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_mesh_instancing(loader));

+ 1 - 0
loaders/src/glTF/2.0/Extensions/index.ts

@@ -6,6 +6,7 @@ export * from "./KHR_materials_unlit";
 export * from "./KHR_materials_clearcoat";
 export * from "./KHR_materials_sheen";
 export * from "./KHR_materials_specular";
+export * from "./KHR_mesh_instancing";
 export * from "./KHR_mesh_quantization";
 export * from "./KHR_texture_basisu";
 export * from "./KHR_texture_transform";

+ 2 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -1561,7 +1561,8 @@ export class GLTFLoader implements IGLTFLoader {
         return accessor._data;
     }
 
-    private _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array> {
+    /** @hidden */
+    public _loadFloatAccessorAsync(context: string, accessor: IAccessor): Promise<Float32Array> {
         return this._loadAccessorAsync(context, accessor, Float32Array) as Promise<Float32Array>;
     }
 

+ 25 - 9
src/Gizmos/boundingBoxGizmo.ts

@@ -248,14 +248,19 @@ export class BoundingBoxGizmo extends Gizmo {
         // Create scale cubes
         this._scaleBoxesParent = new AbstractMesh("", gizmoLayer.utilityLayerScene);
         this._scaleBoxesParent.rotationQuaternion = new Quaternion();
-        for (var i = 0; i < 2; i++) {
-            for (var j = 0; j < 2; j++) {
-                for (var k = 0; k < 2; k++) {
+        for (var i = 0; i < 3; i++) {
+            for (var j = 0; j < 3; j++) {
+                for (var k = 0; k < 3; k++) {
+                    // create box for relevant axis
+                    let zeroAxisCount = ((i === 1) ? 1 : 0) + ((j === 1) ? 1 : 0) + ((k === 1) ? 1 : 0);
+                    if (zeroAxisCount === 1 || zeroAxisCount === 3) {
+                        continue;
+                    }
                     let box = BoxBuilder.CreateBox("", { size: 1 }, gizmoLayer.utilityLayerScene);
                     box.material = this.coloredMaterial;
 
                     // Dragging logic
-                    let dragAxis = new Vector3(i == 0 ? -1 : 1, j == 0 ? -1 : 1, k == 0 ? -1 : 1);
+                    let dragAxis = new Vector3(i - 1, j - 1, k - 1);
                     var _dragBehavior = new PointerDragBehavior({ dragAxis: dragAxis });
                     _dragBehavior.moveAttached = false;
                     box.addBehavior(_dragBehavior);
@@ -270,6 +275,12 @@ export class BoundingBoxGizmo extends Gizmo {
                             PivotTools._RemoveAndStorePivotPoint(this.attachedMesh);
                             var relativeDragDistance = (event.dragDistance / this._boundingDimensions.length()) * this._anchorMesh.scaling.length();
                             var deltaScale = new Vector3(relativeDragDistance, relativeDragDistance, relativeDragDistance);
+                            if (zeroAxisCount === 2) {
+                                // scale on 1 axis when using the anchor box in the face middle
+                                deltaScale.x *= Math.abs(dragAxis.x);
+                                deltaScale.y *= Math.abs(dragAxis.y);
+                                deltaScale.z *= Math.abs(dragAxis.z);
+                            }
                             deltaScale.scaleInPlace(this._scaleDragSpeed);
                             this.updateBoundingBox();
                             if (this.scalePivot) {
@@ -487,12 +498,16 @@ export class BoundingBoxGizmo extends Gizmo {
 
     private _updateScaleBoxes() {
         var scaleBoxes = this._scaleBoxesParent.getChildMeshes();
-        for (var i = 0; i < 2; i++) {
-            for (var j = 0; j < 2; j++) {
-                for (var k = 0; k < 2; k++) {
-                    var index = ((i * 4) + (j * 2)) + k;
+        var index = 0;
+        for (var i = 0; i < 3; i++) {
+            for (var j = 0; j < 3; j++) {
+                for (var k = 0; k < 3; k++) {
+                    let zeroAxisCount = ((i === 1) ? 1 : 0) + ((j === 1) ? 1 : 0) + ((k === 1) ? 1 : 0);
+                    if (zeroAxisCount === 1 || zeroAxisCount === 3) {
+                        continue;
+                    }
                     if (scaleBoxes[index]) {
-                        scaleBoxes[index].position.set(this._boundingDimensions.x * i, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
+                        scaleBoxes[index].position.set(this._boundingDimensions.x * (i / 2), this._boundingDimensions.y * (j / 2), this._boundingDimensions.z * (k / 2));
                         scaleBoxes[index].position.addInPlace(new Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                         if (this.fixedDragMeshScreenSize && this.gizmoLayer.utilityLayerScene.activeCamera) {
                             scaleBoxes[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera.position, this._tmpVector);
@@ -502,6 +517,7 @@ export class BoundingBoxGizmo extends Gizmo {
                             scaleBoxes[index].scaling.set(this.scaleBoxSize, this.scaleBoxSize, this.scaleBoxSize);
                         }
                     }
+                    index++;
                 }
             }
         }

+ 2 - 0
src/Materials/PBR/pbrBaseMaterial.ts

@@ -214,6 +214,8 @@ export class PBRMaterialDefines extends MaterialDefines
     public SHEEN_TEXTURE = false;
     public SHEEN_TEXTUREDIRECTUV = 0;
     public SHEEN_LINKWITHALBEDO = false;
+    public SHEEN_ROUGHNESS = false;
+    public SHEEN_ALBEDOSCALING = false;
 
     public SUBSURFACE = false;
 

+ 32 - 1
src/Materials/PBR/pbrSheenConfiguration.ts

@@ -17,6 +17,8 @@ export interface IMaterialSheenDefines {
     SHEEN_TEXTURE: boolean;
     SHEEN_TEXTUREDIRECTUV: number;
     SHEEN_LINKWITHALBEDO: boolean;
+    SHEEN_ROUGHNESS: boolean;
+    SHEEN_ALBEDOSCALING: boolean;
 
     /** @hidden */
     _areTexturesDirty: boolean;
@@ -65,6 +67,26 @@ export class PBRSheenConfiguration {
     @expandToProperty("_markAllSubMeshesAsTexturesDirty")
     public texture: Nullable<BaseTexture> = null;
 
+    private _roughness: Nullable<number> = null;
+    /**
+     * Defines the sheen roughness.
+     * It is not taken into account if linkSheenWithAlbedo is true.
+     * To stay backward compatible, material roughness is used instead if sheen roughness = null
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public roughness: Nullable<number> = null;
+
+    private _albedoScaling = false;
+    /**
+     * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
+     * It allows the strength of the sheen effect to not depend on the base color of the material,
+     * making it easier to setup and tweak the effect
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public albedoScaling = false;
+
     /** @hidden */
     private _internalMarkAllSubMeshesAsTexturesDirty: () => void;
 
@@ -110,6 +132,8 @@ export class PBRSheenConfiguration {
         if (this._isEnabled) {
             defines.SHEEN = this._isEnabled;
             defines.SHEEN_LINKWITHALBEDO = this._linkSheenWithAlbedo;
+            defines.SHEEN_ROUGHNESS = this._roughness !== null;
+            defines.SHEEN_ALBEDOSCALING = this._albedoScaling;
 
             if (defines._areTexturesDirty) {
                 if (scene.texturesEnabled) {
@@ -125,6 +149,8 @@ export class PBRSheenConfiguration {
             defines.SHEEN = false;
             defines.SHEEN_TEXTURE = false;
             defines.SHEEN_LINKWITHALBEDO = false;
+            defines.SHEEN_ROUGHNESS = false;
+            defines.SHEEN_ALBEDOSCALING = false;
         }
     }
 
@@ -147,6 +173,10 @@ export class PBRSheenConfiguration {
                 this.color.g,
                 this.color.b,
                 this.intensity);
+
+            if (this._roughness !== null) {
+                uniformBuffer.updateFloat("vSheenRoughness", this._roughness);
+            }
         }
 
         // Textures
@@ -229,7 +259,7 @@ export class PBRSheenConfiguration {
      * @param uniforms defines the current uniform list.
      */
     public static AddUniforms(uniforms: string[]): void {
-        uniforms.push("vSheenColor", "vSheenInfos", "sheenMatrix");
+        uniforms.push("vSheenColor", "vSheenRoughness", "vSheenInfos", "sheenMatrix");
     }
 
     /**
@@ -238,6 +268,7 @@ export class PBRSheenConfiguration {
      */
     public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
         uniformBuffer.addUniform("vSheenColor", 4);
+        uniformBuffer.addUniform("vSheenRoughness", 1);
         uniformBuffer.addUniform("vSheenInfos", 2);
         uniformBuffer.addUniform("sheenMatrix", 16);
     }

+ 13 - 0
src/Maths/math.vector.ts

@@ -3189,6 +3189,19 @@ export class Quaternion {
     }
 
     /**
+     * Updates the given quaternion "result" from the starting index of the given array.
+     * @param array the array to pull values from
+     * @param offset the offset into the array to start at
+     * @param result the quaternion to store the result in
+     */
+    public static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Quaternion): void {
+        result.x = array[offset];
+        result.y = array[offset + 1];
+        result.z = array[offset + 2];
+        result.w = array[offset + 3];
+    }
+
+    /**
      * Create a quaternion from Euler rotation angles
      * @param x Pitch
      * @param y Yaw

+ 13 - 0
src/Misc/stringTools.ts

@@ -73,4 +73,17 @@ export class StringTools {
 
         return output;
     }
+
+    /**
+    * Converts a number to string and pads with preceeding zeroes until it is of specified length.
+    * @param num the number to convert and pad
+    * @param length the expected length of the string
+    * @returns the padded string
+    */
+    public static PadNumber(num: number, length: number): string {
+        var str = String(num);
+        while (str.length < length) { str = "0" + str; }
+        return str;
+    }
+
 }

+ 6 - 0
src/Shaders/ShadersInclude/lightFragment.fx

@@ -76,6 +76,12 @@
                 #ifdef SHEEN_LINKWITHALBEDO
                     // BE Carefull: Sheen intensity is replacing the roughness value.
                     preInfo.roughness = sheenIntensity;
+                #else
+                    #ifdef HEMILIGHT{X}
+                        preInfo.roughness = sheenRoughness;
+                    #else
+                        preInfo.roughness = adjustRoughnessFromLightProperties(sheenRoughness, light{X}.vLightSpecular.a, preInfo.lightDistance);
+                    #endif
                 #endif
                 info.sheen = computeSheenLighting(preInfo, normalW, sheenColor, specularEnvironmentR90, AARoughnessFactors.x, light{X}.vLightDiffuse.rgb);
             #endif

+ 41 - 1
src/Shaders/ShadersInclude/pbrBRDFFunctions.fx

@@ -39,6 +39,18 @@
     }
 #endif
 
+/* NOT USED
+#if defined(SHEEN) && defined(SHEEN_SOFTER)
+// Approximation of (integral on hemisphere)[f_sheen*cos(theta)*dtheta*dphi]
+float getBRDFLookupCharlieSheen(float NdotV, float perceptualRoughness)
+{
+    float c = 1.0 - NdotV;
+    float c3 = c*c*c;
+    return 0.65584461 * c3 + 1.0 / (4.16526551 + exp(-7.97291361*perceptualRoughness+6.33516894));
+}
+#endif
+*/
+
 #if !defined(ENVIRONMENTBRDF) || defined(REFLECTIONMAP_SKYBOX) || defined(ALPHAFRESNEL)
     vec3 getReflectanceFromAnalyticalBRDFLookup_Jones(float VdotN, vec3 reflectance0, vec3 reflectance90, float smoothness)
     {
@@ -48,7 +60,7 @@
     }
 #endif
 
-#if defined(SHEEN) && defined(REFLECTION)
+#if defined(SHEEN) && defined(ENVIRONMENTBRDF)
     /**
      * The sheen BRDF not containing F can be easily stored in the blue channel of the BRDF texture.
      * The blue channel contains DCharlie * VAshikhmin * NdotL as a lokkup table
@@ -136,6 +148,7 @@ float normalDistributionFunction_TrowbridgeReitzGGX(float NdotH, float alphaG)
 }
 
 #ifdef SHEEN
+    // http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
     // https://knarkowicz.wordpress.com/2018/01/04/cloth-shading/
     float normalDistributionFunction_CharlieSheen(float NdotH, float alphaG)
     {
@@ -245,6 +258,33 @@ float normalDistributionFunction_TrowbridgeReitzGGX(float NdotH, float alphaG)
     {
         return 1. / (4. * (NdotL + NdotV - NdotL * NdotV));
     }
+
+    /* NOT USED
+    #ifdef SHEEN_SOFTER
+        // http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
+        float l(float x, float alphaG)
+        {
+            float oneMinusAlphaSq = (1.0 - alphaG) * (1.0 - alphaG);
+            float a = mix(21.5473, 25.3245, oneMinusAlphaSq);
+            float b = mix(3.82987, 3.32435, oneMinusAlphaSq);
+            float c = mix(0.19823, 0.16801, oneMinusAlphaSq);
+            float d = mix(-1.97760, -1.27393, oneMinusAlphaSq);
+            float e = mix(-4.32054, -4.85967, oneMinusAlphaSq);
+            return a / (1.0 + b * pow(x, c)) + d * x + e;
+        }
+
+        float lambdaSheen(float cosTheta, float alphaG)
+        {
+            return abs(cosTheta) < 0.5 ? exp(l(cosTheta, alphaG)) : exp(2.0 * l(0.5, alphaG) - l(1.0 - cosTheta, alphaG));
+        }
+
+        float visibility_CharlieSheen(float NdotL, float NdotV, float alphaG)
+        {
+            float G = 1.0 / (1.0 + lambdaSheen(NdotV, alphaG) + lambdaSheen(NdotL, alphaG));
+            return G / (4.0 * NdotV * NdotL);
+        }
+    #endif
+    */
 #endif
 
 // ______________________________________________________________________

+ 6 - 2
src/Shaders/ShadersInclude/pbrDirectLightingFunctions.fx

@@ -143,9 +143,13 @@ vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, m
         // vec3 fresnel = fresnelSchlickGGX(info.VdotH, reflectance0, reflectance90);
         float fresnel = 1.;
         float distribution = normalDistributionFunction_CharlieSheen(NdotH, alphaG);
-        float ashikhminvisibility = visibility_Ashikhmin(info.NdotL, info.NdotV);
+        /*#ifdef SHEEN_SOFTER
+            float visibility = visibility_CharlieSheen(info.NdotL, info.NdotV, alphaG);
+        #else */
+            float visibility = visibility_Ashikhmin(info.NdotL, info.NdotV);
+        /* #endif */
 
-        float sheenTerm = fresnel * distribution * ashikhminvisibility;
+        float sheenTerm = fresnel * distribution * visibility;
         return sheenTerm * info.attenuation * info.NdotL * lightColor;
     }
 #endif

+ 3 - 0
src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx

@@ -100,6 +100,9 @@ uniform mat4 view;
 // Sheen
 #ifdef SHEEN
     uniform vec4 vSheenColor;
+    #ifdef SHEEN_ROUGHNESS
+        uniform float vSheenRoughness;
+    #endif
 
     #ifdef SHEEN_TEXTURE
         uniform vec2 vSheenInfos;

+ 1 - 0
src/Shaders/ShadersInclude/pbrUboDeclaration.fx

@@ -50,6 +50,7 @@ uniform Material
     uniform mat4 anisotropyMatrix;
 
     uniform vec4 vSheenColor;
+    uniform float vSheenRoughness;
     uniform vec2 vSheenInfos;
     uniform mat4 sheenMatrix;
 

+ 77 - 41
src/Shaders/pbr.fragment.fx

@@ -205,6 +205,7 @@ void main(void) {
         vec3 baseColor = surfaceAlbedo;
 
         #ifdef REFLECTANCE
+            // *** NOT USED ANYMORE ***
             // Following Frostbite Remapping,
             // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf page 115
             // vec3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + baseColor * metallic;
@@ -551,10 +552,17 @@ void main(void) {
             #ifdef SHEEN_TEXTURE
                 sheenColor.rgb *= toLinearSpace(sheenMapData.rgb);
             #endif
-            float sheenRoughness = roughness;
+            
+            #ifdef SHEEN_ROUGHNESS
+                float sheenRoughness = vSheenRoughness;
+            #else
+                float sheenRoughness = roughness;
+            #endif
 
             // Sheen Lobe Layering.
-            sheenIntensity *= (1. - reflectance);
+            #if !defined(SHEEN_ALBEDOSCALING)
+                sheenIntensity *= (1. - reflectance);
+            #endif
 
             // Remap F0 and sheen.
             sheenColor *= sheenIntensity;
@@ -886,8 +894,17 @@ void main(void) {
     #endif
 
     // _____________________________ Sheen Environment Oclusion __________________________
-    #if defined(SHEEN) && defined(REFLECTION)
-        vec3 sheenEnvironmentReflectance = getSheenReflectanceFromBRDFLookup(sheenColor, environmentBrdf);
+    #if defined(SHEEN) && defined(ENVIRONMENTBRDF)
+        /*#ifdef SHEEN_SOFTER
+            vec3 environmentSheenBrdf = vec3(0., 0., getBRDFLookupCharlieSheen(NdotV, sheenRoughness));
+        #else*/
+            #ifdef SHEEN_ROUGHNESS
+                vec3 environmentSheenBrdf = getBRDFLookup(NdotV, sheenRoughness);
+            #else
+                vec3 environmentSheenBrdf = environmentBrdf;
+            #endif
+        /*#endif*/
+        vec3 sheenEnvironmentReflectance = getSheenReflectanceFromBRDFLookup(sheenColor, environmentSheenBrdf);
 
         #ifdef RADIANCEOCCLUSION
             sheenEnvironmentReflectance *= seo;
@@ -900,6 +917,13 @@ void main(void) {
                 #endif
             #endif
         #endif
+
+        #if defined(SHEEN_ALBEDOSCALING)
+            // Sheen Lobe Layering.
+            // environmentSheenBrdf.b is (integral on hemisphere)[f_sheen*cos(theta)*dtheta*dphi], which happens to also be the directional albedo needed for albedo scaling.
+            // See section 6.2.3 in https://dassaultsystemes-technology.github.io/EnterprisePBRShadingModel/spec-2021x.md.html#components/sheen
+            float sheenAlbedoScaling = 1.0 - sheenIntensity * max(max(sheenColor.r, sheenColor.g), sheenColor.b) * environmentSheenBrdf.b;
+        #endif
     #endif
 
     // _________________________ Clear Coat Environment Oclusion __________________________
@@ -935,10 +959,10 @@ void main(void) {
 
             #ifdef REFLECTION
                 environmentIrradiance *= absorption;
+            #endif
 
-                #ifdef SHEEN
-                    sheenEnvironmentReflectance *= absorption;
-                #endif
+            #if defined(SHEEN) && defined(ENVIRONMENTBRDF)
+                sheenEnvironmentReflectance *= absorption;
             #endif
 
             specularEnvironmentReflectance *= absorption;
@@ -952,10 +976,10 @@ void main(void) {
 
         #ifdef REFLECTION
             environmentIrradiance *= conservationFactor;
+        #endif
 
-            #ifdef SHEEN
-                sheenEnvironmentReflectance *= conservationFactor;
-            #endif
+        #if defined(SHEEN) && defined(ENVIRONMENTBRDF)
+            sheenEnvironmentReflectance *= conservationFactor;
         #endif
 
         specularEnvironmentReflectance *= conservationFactor;
@@ -1040,6 +1064,10 @@ void main(void) {
         #endif
     #endif
 
+    #if defined(SHEEN) && defined(SHEEN_ALBEDOSCALING) && defined(ENVIRONMENTBRDF)
+        surfaceAlbedo.rgb = sheenAlbedoScaling * surfaceAlbedo.rgb;
+    #endif
+
     // _____________________________ Irradiance ______________________________________
     #ifdef REFLECTION
         vec3 finalIrradiance = environmentIrradiance;
@@ -1059,6 +1087,10 @@ void main(void) {
         #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
             finalSpecularScaled *= energyConservationFactor;
         #endif
+
+        #if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)
+            finalSpecularScaled *= sheenAlbedoScaling;
+        #endif
     #endif
 
     // _____________________________ Radiance ________________________________________
@@ -1071,6 +1103,10 @@ void main(void) {
         #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
             finalRadianceScaled *= energyConservationFactor;
         #endif
+
+        #if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)
+            finalRadianceScaled *= sheenAlbedoScaling;
+        #endif
     #endif
 
     // _____________________________ Refraction ______________________________________
@@ -1079,6 +1115,27 @@ void main(void) {
         finalRefraction *= refractionTransmittance;
     #endif
 
+    // ________________________________ Sheen ________________________________________
+    #ifdef SHEEN
+        vec3 finalSheen = sheenBase * sheenColor;
+        finalSheen = max(finalSheen, 0.0);
+
+        vec3 finalSheenScaled = finalSheen * vLightingIntensity.x * vLightingIntensity.w;
+        // #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
+            // The sheen does not use the same BRDF so not energy conservation is possible
+            // Should be less a problem as it is usually not metallic
+            // finalSheenScaled *= energyConservationFactor;
+        // #endif
+        
+        #if defined(REFLECTION) && defined(ENVIRONMENTBRDF)
+            vec3 finalSheenRadiance = environmentSheenRadiance.rgb;
+            finalSheenRadiance *= sheenEnvironmentReflectance;
+
+            // Full value needed for alpha. 
+            vec3 finalSheenRadianceScaled = finalSheenRadiance * vLightingIntensity.z;
+        #endif
+    #endif
+
     // _____________________________ Clear Coat _______________________________________
     #ifdef CLEARCOAT
         vec3 finalClearCoat = clearCoatBase;
@@ -1107,27 +1164,6 @@ void main(void) {
         #endif
     #endif
 
-    // ________________________________ Sheen ________________________________________
-    #ifdef SHEEN
-        vec3 finalSheen = sheenBase * sheenColor;
-        finalSheen = max(finalSheen, 0.0);
-
-        vec3 finalSheenScaled = finalSheen * vLightingIntensity.x * vLightingIntensity.w;
-        // #if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)
-            // The sheen does not use the same BRDF so not energy conservation is possible
-            // Should be less a problem as it is usually not metallic
-            // finalSheenScaled *= energyConservationFactor;
-        // #endif
-        
-        #ifdef REFLECTION
-            vec3 finalSheenRadiance = environmentSheenRadiance.rgb;
-            finalSheenRadiance *= sheenEnvironmentReflectance;
-
-            // Full value needed for alpha. 
-            vec3 finalSheenRadianceScaled = finalSheenRadiance * vLightingIntensity.z;
-        #endif
-    #endif
-
     // _____________________________ Highlights on Alpha _____________________________
     #ifdef ALPHABLEND
         float luminanceOverAlpha = 0.0;
@@ -1192,30 +1228,30 @@ void main(void) {
     //	finalSpecular			* vLightingIntensity.x * vLightingIntensity.w +
         finalSpecularScaled +
     #endif
-    #ifdef CLEARCOAT
-    // Computed in the previous step to help with alpha luminance.
-    //	finalClearCoat			* vLightingIntensity.x * vLightingIntensity.w +
-        finalClearCoatScaled +
-    #endif
     #ifdef SHEEN
     // Computed in the previous step to help with alpha luminance.
     //	finalSheen  			* vLightingIntensity.x * vLightingIntensity.w +
         finalSheenScaled +
     #endif
+    #ifdef CLEARCOAT
+    // Computed in the previous step to help with alpha luminance.
+    //	finalClearCoat			* vLightingIntensity.x * vLightingIntensity.w +
+        finalClearCoatScaled +
+    #endif
     #ifdef REFLECTION
     // Comupted in the previous step to help with alpha luminance.
     //	finalRadiance			* vLightingIntensity.z +
         finalRadianceScaled +
+        #if defined(SHEEN) && defined(ENVIRONMENTBRDF)
+        //  Comupted in the previous step to help with alpha luminance.
+        //  finalSheenRadiance * vLightingIntensity.z 
+            finalSheenRadianceScaled +
+        #endif
         #ifdef CLEARCOAT
         //  Comupted in the previous step to help with alpha luminance.
         //  finalClearCoatRadiance * vLightingIntensity.z 
             finalClearCoatRadianceScaled +
         #endif
-        #ifdef SHEEN
-        //  Comupted in the previous step to help with alpha luminance.
-        //  finalSheenRadiance * vLightingIntensity.z 
-            finalSheenRadianceScaled +
-        #endif
     #endif
     #ifdef SS_REFRACTION
         finalRefraction			* vLightingIntensity.z +

BIN
tests/validation/ReferenceImages/Gizmos.png


BIN
tests/validation/ReferenceImages/nested_BBG.png


BIN
tests/validation/ReferenceImages/simulatePointer.png


+ 1 - 1
tests/validation/config.json

@@ -133,7 +133,7 @@
         },
         {
             "title": "Simulate pointer",
-            "playgroundId": "#8MGKWK#78",
+            "playgroundId": "#8MGKWK#196",
             "referenceImage": "simulatePointer.png"
         },
         {