浏览代码

Merge pull request #999 from sebavan/PMREMGenerator

Pmrem generator
David Catuhe 9 年之前
父节点
当前提交
9419d02258

文件差异内容过多而无法显示
+ 32 - 22
dist/preview release/babylon.core.js


文件差异内容过多而无法显示
+ 971 - 898
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 41 - 29
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 9526 - 8446
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 40 - 29
dist/preview release/babylon.noworker.js


文件差异内容过多而无法显示
+ 41 - 4
materialsLibrary/dist/babylon.pbrMaterial.js


文件差异内容过多而无法显示
+ 2 - 2
materialsLibrary/dist/babylon.pbrMaterial.min.js


+ 3 - 0
materialsLibrary/dist/dts/babylon.pbrMaterial.d.ts

@@ -58,6 +58,9 @@ declare module BABYLON {
         useScalarInLinearSpace: boolean;
         usePhysicalLightFalloff: boolean;
         useRadianceOverAlpha: boolean;
+        useParallax: boolean;
+        useParallaxOcclusion: boolean;
+        parallaxScaleBias: number;
         disableLighting: boolean;
         private _renderTargets;
         private _worldViewProjectionMatrix;

+ 43 - 3
materialsLibrary/materials/pbr/babylon.pbrMaterial.ts

@@ -12,6 +12,8 @@ module BABYLON {
         public EMISSIVE = false;
         public REFLECTIVITY = false;
         public BUMP = false;
+        public PARALLAX = false;
+        public PARALLAXOCCLUSION = false;
         public SPECULAROVERALPHA = false;
         public CLIPPLANE = false;
         public ALPHATEST = false;
@@ -91,6 +93,8 @@ module BABYLON {
         public LODBASEDMICROSFURACE = false;
         public USEPHYSICALLIGHTFALLOFF = false;
         public RADIANCEOVERALPHA = false;
+        public USEPMREMREFLECTION = false;
+        public USEPMREMREFRACTION = false;
 
         constructor() {
             super();
@@ -266,6 +270,15 @@ module BABYLON {
         public useRadianceOverAlpha = true;
         
         @serialize()
+        public useParallax = false;
+
+        @serialize()
+        public useParallaxOcclusion = false;
+
+        @serialize()
+        public parallaxScaleBias = 0.05;
+        
+        @serialize()
         public disableLighting = false;
         
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
@@ -517,6 +530,10 @@ module BABYLON {
                             if (this.reflectionTexture instanceof HDRCubeTexture && (<HDRCubeTexture>this.reflectionTexture)) {
                                 this._defines.USESPHERICALFROMREFLECTIONMAP = true;
                                 needNormals = true;
+                                
+                                if ((<HDRCubeTexture>this.reflectionTexture).isPMREM) {
+                                    this._defines.USEPMREMREFLECTION = true;
+                                }
                             }
                         }
                     }
@@ -558,6 +575,13 @@ module BABYLON {
                     } else {
                         needUVs = true;
                         this._defines.BUMP = true;
+                        
+                        if (this.useParallax) {
+                            this._defines.PARALLAX = true;
+                            if (this.useParallaxOcclusion) {
+                                this._defines.PARALLAXOCCLUSION = true;
+                            }
+                        }
                     }
                 }
 
@@ -574,6 +598,10 @@ module BABYLON {
                         }
                         if (this.refractionTexture instanceof HDRCubeTexture) {
                             this._defines.REFRACTIONMAPINLINEARSPACE = true;
+                            
+                            if ((<HDRCubeTexture>this.refractionTexture).isPMREM) {
+                                this._defines.USEPMREMREFRACTION = true;
+                            }
                         }
                     }
                 }
@@ -712,6 +740,10 @@ module BABYLON {
                 if (this._defines.REFLECTION) {
                     fallbacks.addFallback(0, "REFLECTION");
                 }
+                
+                if (this._defines.REFRACTION) {
+                    fallbacks.addFallback(0, "REFRACTION");
+                }
 
                 if (this._defines.REFLECTIVITY) {
                     fallbacks.addFallback(0, "REFLECTIVITY");
@@ -720,6 +752,14 @@ module BABYLON {
                 if (this._defines.BUMP) {
                     fallbacks.addFallback(0, "BUMP");
                 }
+                
+                if (this._defines.PARALLAX) {
+                    fallbacks.addFallback(1, "PARALLAX");
+                }
+
+                if (this._defines.PARALLAXOCCLUSION) {
+                    fallbacks.addFallback(0, "PARALLAXOCCLUSION");
+                }
 
                 if (this._defines.SPECULAROVERALPHA) {
                     fallbacks.addFallback(0, "SPECULAROVERALPHA");
@@ -897,7 +937,7 @@ module BABYLON {
                     }
 
                     if (this.reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
-                        this._microsurfaceTextureLods.x = Math.log(this.reflectionTexture.getSize().width) * Math.LOG2E;
+                        this._microsurfaceTextureLods.x = Math.round(Math.log(this.reflectionTexture.getSize().width) * Math.LOG2E);
                         
                         if (this.reflectionTexture.isCube) {
                             this._effect.setTexture("reflectionCubeSampler", this.reflectionTexture);
@@ -963,12 +1003,12 @@ module BABYLON {
                     if (this.bumpTexture && this._myScene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled && !this.disableBumpMap) {
                         this._effect.setTexture("bumpSampler", this.bumpTexture);
 
-                        this._effect.setFloat2("vBumpInfos", this.bumpTexture.coordinatesIndex, 1.0 / this.bumpTexture.level);
+                        this._effect.setFloat3("vBumpInfos", this.bumpTexture.coordinatesIndex, 1.0 / this.bumpTexture.level, this.parallaxScaleBias);
                         this._effect.setMatrix("bumpMatrix", this.bumpTexture.getTextureMatrix());
                     }
 
                     if (this.refractionTexture && StandardMaterial.RefractionTextureEnabled) {
-                        this._microsurfaceTextureLods.y = Math.log(this.refractionTexture.getSize().width) * Math.LOG2E;
+                        this._microsurfaceTextureLods.y = Math.round(Math.log(this.refractionTexture.getSize().width) * Math.LOG2E);
                         
                         var depth = 1.0;
                         if (this.refractionTexture.isCube) {

+ 48 - 9
materialsLibrary/materials/pbr/pbr.fragment.fx

@@ -172,6 +172,14 @@ float getMipMapIndexFromAverageSlope(float maxMipLevel, float alpha)
     return clamp(mip, 0., maxMipLevel);
 }
 
+float getMipMapIndexFromAverageSlopeWithPMREM(float maxMipLevel, float alphaG)
+{
+    float specularPower = clamp(2. / alphaG - 2., 0.000001, 2048.);
+    
+    // Based on CubeMapGen for cosine power with 2048 spec default and 0.25 dropoff 
+    return clamp(- 0.5 * log2(specularPower) + 5.5, 0., maxMipLevel);
+}
+
 // From Microfacet Models for Refraction through Rough Surfaces, Walter et al. 2007
 float smithVisibilityG1_TrowbridgeReitzGGX(float dot, float alphaG)
 {
@@ -794,12 +802,8 @@ void main(void) {
     #else
         vec3 normalW = vec3(1.0, 1.0, 1.0);
     #endif
-
-
-    #ifdef BUMP
-		mat3 TBN = cotangent_frame(vNormalW * vBumpInfos.y, -viewDirectionW, vBumpUV);
-		normalW = perturbNormal(viewDirectionW, TBN, vBumpUV);
-    #endif
+    
+    #include<bumpFragment>
 
     // Ambient color
     vec3 ambientColor = vec3(1., 1., 1.);
@@ -1079,10 +1083,15 @@ vec3 surfaceRefractionColor = vec3(0., 0., 0.);
 #endif
         
 #ifdef REFRACTION
-	vec3 refractionVector = normalize(refract(-viewDirectionW, normalW, vRefractionInfos.y));
+	//vec3 refractionVector = normalize(refract(-viewDirectionW, normalW, vRefractionInfos.y));
+    vec3 refractionVector = refract(-viewDirectionW, normalW, vRefractionInfos.y);
     
     #ifdef LODBASEDMICROSFURACE
-        float lodRefraction = getMipMapIndexFromAverageSlope(vMicrosurfaceTextureLods.y, alphaG);
+        #ifdef USEPMREMREFRACTION
+            float lodRefraction = getMipMapIndexFromAverageSlopeWithPMREM(vMicrosurfaceTextureLods.y, alphaG);
+        #else
+            float lodRefraction = getMipMapIndexFromAverageSlope(vMicrosurfaceTextureLods.y, alphaG);
+        #endif
     #endif
     
     #ifdef REFRACTIONMAP_3D
@@ -1091,6 +1100,19 @@ vec3 surfaceRefractionColor = vec3(0., 0., 0.);
         if (dot(refractionVector, viewDirectionW) < 1.0)
         {
             #ifdef LODBASEDMICROSFURACE
+                #ifdef USEPMREMREFRACTION
+                    // Empiric Threshold
+                    if (microSurface > 0.5)
+                    {
+                        // Bend to not reach edges.
+                        float scaleRefraction = 1. - exp2(lodRefraction) / exp2(vMicrosurfaceTextureLods.y); // CubemapSize is the size of the base mipmap
+                        float maxRefraction = max(max(abs(refractionVector.x), abs(refractionVector.y)), abs(refractionVector.z));
+                        if (abs(refractionVector.x) != maxRefraction) refractionVector.x *= scaleRefraction;
+                        if (abs(refractionVector.y) != maxRefraction) refractionVector.y *= scaleRefraction;
+                        if (abs(refractionVector.z) != maxRefraction) refractionVector.z *= scaleRefraction;
+                    }
+                #endif
+                
                 surfaceRefractionColor = textureCubeLodEXT(refractionCubeSampler, refractionVector, lodRefraction).rgb * vRefractionInfos.x;
             #else
                 surfaceRefractionColor = textureCube(refractionCubeSampler, refractionVector, bias).rgb * vRefractionInfos.x;
@@ -1125,12 +1147,29 @@ vec3 environmentIrradiance = vReflectionColor.rgb;
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
 
     #ifdef LODBASEDMICROSFURACE
-        float lodReflection = getMipMapIndexFromAverageSlope(vMicrosurfaceTextureLods.x, alphaG);
+        #ifdef USEPMREMREFLECTION
+            float lodReflection = getMipMapIndexFromAverageSlopeWithPMREM(vMicrosurfaceTextureLods.x, alphaG);
+        #else
+            float lodReflection = getMipMapIndexFromAverageSlope(vMicrosurfaceTextureLods.x, alphaG);
+        #endif
     #endif
     
     #ifdef REFLECTIONMAP_3D
         
         #ifdef LODBASEDMICROSFURACE
+            #ifdef USEPMREMREFLECTION
+                // Empiric Threshold
+                if (microSurface > 0.5)
+                {
+                    // Bend to not reach edges.
+                    float scaleReflection = 1. - exp2(lodReflection) / exp2(vMicrosurfaceTextureLods.x); // CubemapSize is the size of the base mipmap
+                    float maxReflection = max(max(abs(vReflectionUVW.x), abs(vReflectionUVW.y)), abs(vReflectionUVW.z));
+                    if (abs(vReflectionUVW.x) != maxReflection) vReflectionUVW.x *= scaleReflection;
+                    if (abs(vReflectionUVW.y) != maxReflection) vReflectionUVW.y *= scaleReflection;
+                    if (abs(vReflectionUVW.z) != maxReflection) vReflectionUVW.z *= scaleReflection;
+                }
+            #endif
+                
             environmentRadiance = textureCubeLodEXT(reflectionCubeSampler, vReflectionUVW, lodReflection).rgb * vReflectionInfos.x;
         #else
             environmentRadiance = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;

+ 3 - 0
materialsLibrary/test/add/addpbr.js

@@ -6,6 +6,9 @@ window.preparePBR = function() {
 	pbr.albedoTexture.vScale = 5;
     
     var hdrTexture = new BABYLON.HDRCubeTexture("textures/hdr/environment.hdr", scene, 512);
+    
+    // Uncomment for PMREM Generation
+    // var hdrTexture = new BABYLON.HDRCubeTexture("textures/hdr/environment.hdr", scene, 128, false, true, false, true);
     pbr.reflectionTexture = hdrTexture;
     pbr.refractionTexture = hdrTexture;
     pbr.linkRefractionWithTransparency = true;

文件差异内容过多而无法显示
+ 1153 - 44
materialsLibrary/test/refs/babylon.max.js


+ 19 - 7
src/Materials/Textures/babylon.hdrCubeTexture.js

@@ -7,21 +7,25 @@ var BABYLON;
 (function (BABYLON) {
     var HDRCubeTexture = (function (_super) {
         __extends(HDRCubeTexture, _super);
-        function HDRCubeTexture(url, scene, size, noMipmap, generateHarmonics, useInGammaSpace) {
+        function HDRCubeTexture(url, scene, size, noMipmap, generateHarmonics, useInGammaSpace, usePMREMGenerator) {
             if (noMipmap === void 0) { noMipmap = false; }
             if (generateHarmonics === void 0) { generateHarmonics = true; }
             if (useInGammaSpace === void 0) { useInGammaSpace = false; }
+            if (usePMREMGenerator === void 0) { usePMREMGenerator = false; }
             _super.call(this, scene);
             this.coordinatesMode = BABYLON.Texture.CUBIC_MODE;
             this._useInGammaSpace = false;
             this._generateHarmonics = true;
             this.sphericalPolynomial = null;
+            this.isPMREM = false;
             this.name = url;
             this.url = url;
             this._noMipmap = noMipmap;
             this.hasAlpha = false;
             this._size = size;
             this._useInGammaSpace = useInGammaSpace;
+            this._usePMREMGenerator = usePMREMGenerator;
+            this.isPMREM = usePMREMGenerator;
             if (!url) {
                 return;
             }
@@ -84,10 +88,17 @@ var BABYLON;
                 }
                 return results;
             };
-            this._texture = this.getScene().getEngine().createRawCubeTexture(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, BABYLON.Engine.TEXTURETYPE_FLOAT, this._noMipmap, callback);
+            var mipmapGenerator = null;
+            if (!this._noMipmap && this._usePMREMGenerator) {
+                mipmapGenerator = function (data) {
+                    var generator = new BABYLON.Internals.PMREMGenerator(data, _this._size, _this._size, 0, 3, _this.getScene().getEngine().getCaps().textureFloat, 2048, 0.25, false, true);
+                    return generator.filterCubeMap();
+                };
+            }
+            this._texture = this.getScene().getEngine().createRawCubeTexture(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, BABYLON.Engine.TEXTURETYPE_FLOAT, this._noMipmap, callback, mipmapGenerator);
         };
         HDRCubeTexture.prototype.clone = function () {
-            var newTexture = new HDRCubeTexture(this.url, this.getScene(), this._size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace);
+            var newTexture = new HDRCubeTexture(this.url, this.getScene(), this._size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
             // Base texture
             newTexture.level = this.level;
             newTexture.wrapU = this.wrapU;
@@ -113,7 +124,7 @@ var BABYLON;
         HDRCubeTexture.Parse = function (parsedTexture, scene, rootUrl) {
             var texture = null;
             if (parsedTexture.name && !parsedTexture.isRenderTarget) {
-                texture = new BABYLON.HDRCubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.size, texture.generateHarmonics, texture.useInGammaSpace);
+                texture = new BABYLON.HDRCubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.size, texture.generateHarmonics, texture.useInGammaSpace, texture.usePMREMGenerator);
                 texture.name = parsedTexture.name;
                 texture.hasAlpha = parsedTexture.hasAlpha;
                 texture.level = parsedTexture.level;
@@ -134,14 +145,15 @@ var BABYLON;
             serializationObject.coordinatesMode = this.coordinatesMode;
             serializationObject.useInGammaSpace = this._useInGammaSpace;
             serializationObject.generateHarmonics = this._generateHarmonics;
+            serializationObject.usePMREMGenerator = this._usePMREMGenerator;
             return serializationObject;
         };
         HDRCubeTexture._facesMapping = [
-            "left",
-            "down",
-            "front",
             "right",
             "up",
+            "front",
+            "left",
+            "down",
             "back"
         ];
         return HDRCubeTexture;

+ 32 - 7
src/Materials/Textures/babylon.hdrcubetexture.ts

@@ -9,19 +9,22 @@ module BABYLON {
         private _extensions: string[];
         private _textureMatrix: Matrix;
         private _size: number;
+        private _usePMREMGenerator: boolean;
 
         private static _facesMapping = [
-            "left",
-            "down",
-            "front",
             "right",
             "up",
+            "front",
+            "left",
+            "down",
             "back"
         ];
 
         public sphericalPolynomial: SphericalPolynomial = null;
+        
+        public isPMREM = false;
 
-        constructor(url: string, scene: Scene, size: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false) {
+        constructor(url: string, scene: Scene, size: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false) {
             super(scene);
 
             this.name = url;
@@ -30,6 +33,8 @@ module BABYLON {
             this.hasAlpha = false;
             this._size = size;
             this._useInGammaSpace = useInGammaSpace;
+            this._usePMREMGenerator = usePMREMGenerator;
+            this.isPMREM = usePMREMGenerator;
 
             if (!url) {
                 return;
@@ -104,13 +109,32 @@ module BABYLON {
                 }
                 return results;
             }
+            
+            var mipmapGenerator = null;
+            if (!this._noMipmap && this._usePMREMGenerator)
+            {
+                mipmapGenerator = (data: ArrayBufferView[]) => { 
+                    var generator = new BABYLON.Internals.PMREMGenerator(data,
+                        this._size,
+                        this._size,
+                        0,
+                        3,
+                        this.getScene().getEngine().getCaps().textureFloat,
+                        2048,
+                        0.25,
+                        false,
+                        true);
+                        
+                    return generator.filterCubeMap();
+                };
+            }
 
-            this._texture = (<any>this.getScene().getEngine()).createRawCubeTexture(this.url, this.getScene(), this._size, Engine.TEXTUREFORMAT_RGB, Engine.TEXTURETYPE_FLOAT, this._noMipmap, callback);
+            this._texture = (<any>this.getScene().getEngine()).createRawCubeTexture(this.url, this.getScene(), this._size, Engine.TEXTUREFORMAT_RGB, Engine.TEXTURETYPE_FLOAT, this._noMipmap, callback, mipmapGenerator);
         }
 
         public clone(): HDRCubeTexture {
             var newTexture = new HDRCubeTexture(this.url, this.getScene(), this._size, this._noMipmap,
-                this._generateHarmonics, this._useInGammaSpace);
+                this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
 
             // Base texture
             newTexture.level = this.level;
@@ -144,7 +168,7 @@ module BABYLON {
             var texture = null;
             if (parsedTexture.name && !parsedTexture.isRenderTarget) {
                 texture = new BABYLON.HDRCubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.size,
-                    texture.generateHarmonics, texture.useInGammaSpace);
+                    texture.generateHarmonics, texture.useInGammaSpace, texture.usePMREMGenerator);
                 texture.name = parsedTexture.name;
                 texture.hasAlpha = parsedTexture.hasAlpha;
                 texture.level = parsedTexture.level;
@@ -167,6 +191,7 @@ module BABYLON {
             serializationObject.coordinatesMode = this.coordinatesMode;
             serializationObject.useInGammaSpace = this._useInGammaSpace;
             serializationObject.generateHarmonics = this._generateHarmonics;
+            serializationObject.usePMREMGenerator = this._usePMREMGenerator;
 
             return serializationObject;
         }

+ 6 - 0
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -343,6 +343,12 @@ var BABYLON;
         CannonJSPlugin.prototype.setVelocity = function (impostor, velocity) {
             impostor.physicsBody.velocity.copy(velocity);
         };
+        CannonJSPlugin.prototype.sleepBody = function (impostor) {
+            impostor.physicsBody.sleep();
+        };
+        CannonJSPlugin.prototype.wakeUpBody = function (impostor) {
+            impostor.physicsBody.wakeUp();
+        };
         CannonJSPlugin.prototype.dispose = function () {
             //nothing to do, actually.
         };

+ 6 - 0
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -252,6 +252,12 @@ var BABYLON;
         OimoJSPlugin.prototype.setVelocity = function (impostor, velocity) {
             impostor.physicsBody.linearVelocity.init(velocity.x, velocity.y, velocity.z);
         };
+        OimoJSPlugin.prototype.sleepBody = function (impostor) {
+            impostor.physicsBody.sleep();
+        };
+        OimoJSPlugin.prototype.wakeUpBody = function (impostor) {
+            impostor.physicsBody.awake();
+        };
         OimoJSPlugin.prototype.dispose = function () {
             this.world.clear();
         };

+ 18 - 4
src/Physics/babylon.physicsImpostor.js

@@ -44,9 +44,9 @@ var BABYLON;
                 var otherImpostor = _this._physicsEngine.getImpostorWithPhysicsBody(e.body);
                 if (otherImpostor) {
                     _this._onPhysicsCollideCallbacks.filter(function (obj) {
-                        return obj.otherImpostor === otherImpostor;
+                        return obj.otherImpostors.indexOf(otherImpostor) !== -1;
                     }).forEach(function (obj) {
-                        obj.callback(_this, obj.otherImpostor);
+                        obj.callback(_this, otherImpostor);
                     });
                 }
             };
@@ -198,10 +198,12 @@ var BABYLON;
          * register a function that will be executed when this impostor collides against a different body.
          */
         PhysicsImpostor.prototype.registerOnPhysicsCollide = function (collideAgainst, func) {
-            this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostor: collideAgainst });
+            var collidedAgainstList = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];
+            this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostors: collidedAgainstList });
         };
         PhysicsImpostor.prototype.unregisterOnPhysicsCollide = function (collideAgainst, func) {
-            var index = this._onPhysicsCollideCallbacks.indexOf({ callback: func, otherImpostor: collideAgainst });
+            var collidedAgainstList = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];
+            var index = this._onPhysicsCollideCallbacks.indexOf({ callback: func, otherImpostors: collidedAgainstList });
             if (index > -1) {
                 this._onPhysicsCollideCallbacks.splice(index, 1);
             }
@@ -238,6 +240,18 @@ var BABYLON;
             });
             this._physicsEngine.addJoint(this, otherImpostor, joint);
         };
+        /**
+         * Will keep this body still, in a sleep mode.
+         */
+        PhysicsImpostor.prototype.sleep = function () {
+            this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+        };
+        /**
+         * Wake the body up.
+         */
+        PhysicsImpostor.prototype.wakeUp = function () {
+            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+        };
         PhysicsImpostor.prototype.dispose = function (disposeChildren) {
             if (disposeChildren === void 0) { disposeChildren = true; }
             this.physicsBody = null;

+ 4 - 4
src/Tools/HDR/babylon.tools.cubemapToSphericalPolynomial.js

@@ -92,10 +92,10 @@ var BABYLON;
                 return BABYLON.SphericalPolynomial.getSphericalPolynomialFromHarmonics(sphericalHarmonics);
             };
             CubeMapToSphericalPolynomialTools.FileFaces = [
-                new FileFaceOrientation("left", new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, -1), new BABYLON.Vector3(0, -1, 0)),
-                new FileFaceOrientation("right", new BABYLON.Vector3(-1, 0, 0), new BABYLON.Vector3(0, 0, 1), new BABYLON.Vector3(0, -1, 0)),
-                new FileFaceOrientation("down", new BABYLON.Vector3(0, 1, 0), new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, 1)),
-                new FileFaceOrientation("up", new BABYLON.Vector3(0, -1, 0), new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, -1)),
+                new FileFaceOrientation("right", new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, -1), new BABYLON.Vector3(0, -1, 0)),
+                new FileFaceOrientation("left", new BABYLON.Vector3(-1, 0, 0), new BABYLON.Vector3(0, 0, 1), new BABYLON.Vector3(0, -1, 0)),
+                new FileFaceOrientation("up", new BABYLON.Vector3(0, 1, 0), new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, 1)),
+                new FileFaceOrientation("down", new BABYLON.Vector3(0, -1, 0), new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, 0, -1)),
                 new FileFaceOrientation("front", new BABYLON.Vector3(0, 0, 1), new BABYLON.Vector3(1, 0, 0), new BABYLON.Vector3(0, -1, 0)),
                 new FileFaceOrientation("back", new BABYLON.Vector3(0, 0, -1), new BABYLON.Vector3(-1, 0, 0), new BABYLON.Vector3(0, -1, 0)) // -Z bottom
             ];

+ 4 - 4
src/Tools/HDR/babylon.tools.cubemaptosphericalpolynomial.ts

@@ -18,10 +18,10 @@ module BABYLON.Internals {
     export class CubeMapToSphericalPolynomialTools {        
 
         private static FileFaces: FileFaceOrientation[] = [
-            new FileFaceOrientation("left", new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)), // +X east
-            new FileFaceOrientation("right", new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, -1, 0)), // -X west
-            new FileFaceOrientation("down", new Vector3(0, 1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1)), // +Y north
-            new FileFaceOrientation("up", new Vector3(0, -1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, -1)), // -Y south
+            new FileFaceOrientation("right", new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)), // +X east
+            new FileFaceOrientation("left", new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, -1, 0)), // -X west
+            new FileFaceOrientation("up", new Vector3(0, 1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1)), // +Y north
+            new FileFaceOrientation("down", new Vector3(0, -1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, -1)), // -Y south
             new FileFaceOrientation("front", new Vector3(0, 0, 1), new Vector3(1, 0, 0), new Vector3(0, -1, 0)), // +Z top
             new FileFaceOrientation("back", new Vector3(0, 0, -1), new Vector3(-1, 0, 0), new Vector3(0, -1, 0))// -Z bottom
         ];

+ 4 - 4
src/Tools/HDR/babylon.tools.panoramaToCubemap.js

@@ -96,25 +96,25 @@ var BABYLON;
                 new BABYLON.Vector3(1.0, 1.0, 1.0),
                 new BABYLON.Vector3(-1.0, 1.0, 1.0)
             ];
-            PanoramaToCubeMapTools.FACE_LEFT = [
+            PanoramaToCubeMapTools.FACE_RIGHT = [
                 new BABYLON.Vector3(1.0, -1.0, -1.0),
                 new BABYLON.Vector3(1.0, -1.0, 1.0),
                 new BABYLON.Vector3(1.0, 1.0, -1.0),
                 new BABYLON.Vector3(1.0, 1.0, 1.0)
             ];
-            PanoramaToCubeMapTools.FACE_RIGHT = [
+            PanoramaToCubeMapTools.FACE_LEFT = [
                 new BABYLON.Vector3(-1.0, -1.0, 1.0),
                 new BABYLON.Vector3(-1.0, -1.0, -1.0),
                 new BABYLON.Vector3(-1.0, 1.0, 1.0),
                 new BABYLON.Vector3(-1.0, 1.0, -1.0)
             ];
-            PanoramaToCubeMapTools.FACE_UP = [
+            PanoramaToCubeMapTools.FACE_DOWN = [
                 new BABYLON.Vector3(-1.0, 1.0, -1.0),
                 new BABYLON.Vector3(1.0, 1.0, -1.0),
                 new BABYLON.Vector3(-1.0, 1.0, 1.0),
                 new BABYLON.Vector3(1.0, 1.0, 1.0)
             ];
-            PanoramaToCubeMapTools.FACE_DOWN = [
+            PanoramaToCubeMapTools.FACE_UP = [
                 new BABYLON.Vector3(-1.0, -1.0, 1.0),
                 new BABYLON.Vector3(1.0, -1.0, 1.0),
                 new BABYLON.Vector3(-1.0, -1.0, -1.0),

+ 4 - 4
src/Tools/HDR/babylon.tools.panoramaToCubemap.ts

@@ -23,25 +23,25 @@ module BABYLON.Internals {
             new Vector3(1.0, 1.0, 1.0),
             new Vector3(-1.0, 1.0, 1.0)
         ];
-        private static FACE_LEFT = [
+        private static FACE_RIGHT = [
             new Vector3(1.0, -1.0, -1.0),
             new Vector3(1.0, -1.0, 1.0),
             new Vector3(1.0, 1.0, -1.0),
             new Vector3(1.0, 1.0, 1.0)
         ];
-        private static FACE_RIGHT = [
+        private static FACE_LEFT = [
             new Vector3(-1.0, -1.0, 1.0),
             new Vector3(-1.0, -1.0, -1.0),
             new Vector3(-1.0, 1.0, 1.0),
             new Vector3(-1.0, 1.0, -1.0)
         ];
-        private static FACE_UP = [
+        private static FACE_DOWN = [
             new Vector3(-1.0, 1.0, -1.0),
             new Vector3(1.0, 1.0, -1.0),
             new Vector3(-1.0, 1.0, 1.0),
             new Vector3(1.0, 1.0, 1.0)
         ];
-        private static FACE_DOWN = [
+        private static FACE_UP = [
             new Vector3(-1.0, -1.0, 1.0),
             new Vector3(1.0, -1.0, 1.0),
             new Vector3(-1.0, -1.0, -1.0),

文件差异内容过多而无法显示
+ 1018 - 1
src/Tools/HDR/babylon.tools.pmremgenerator.js


文件差异内容过多而无法显示
+ 1199 - 2
src/Tools/HDR/babylon.tools.pmremgenerator.ts


+ 31 - 6
src/babylon.engine.js

@@ -1575,7 +1575,7 @@ var BABYLON;
             }
             return texture;
         };
-        Engine.prototype.createRawCubeTexture = function (url, scene, size, format, type, noMipmap, callback) {
+        Engine.prototype.createRawCubeTexture = function (url, scene, size, format, type, noMipmap, callback, mipmmapGenerator) {
             var _this = this;
             var gl = this._gl;
             var texture = gl.createTexture();
@@ -1604,12 +1604,37 @@ var BABYLON;
                 ];
                 gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
                 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
-                for (var index = 0; index < facesIndex.length; index++) {
-                    var faceData = rgbeDataArrays[index];
-                    gl.texImage2D(facesIndex[index], 0, internalFormat, width, height, 0, internalFormat, textureType, faceData);
-                }
                 if (!noMipmap && isPot) {
-                    gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                    if (mipmmapGenerator) {
+                        var arrayTemp = [];
+                        // Data are known to be in +X +Y +Z -X -Y -Z
+                        // mipmmapGenerator data is expected to be order in +X -X +Y -Y +Z -Z
+                        arrayTemp.push(rgbeDataArrays[0]); // +X
+                        arrayTemp.push(rgbeDataArrays[3]); // -X
+                        arrayTemp.push(rgbeDataArrays[1]); // +Y
+                        arrayTemp.push(rgbeDataArrays[4]); // -Y
+                        arrayTemp.push(rgbeDataArrays[2]); // +Z
+                        arrayTemp.push(rgbeDataArrays[5]); // -Z
+                        var mipData = mipmmapGenerator(arrayTemp);
+                        for (var level = 0; level < mipData.length; level++) {
+                            var mipSize = width >> level;
+                            // mipData is order in +X -X +Y -Y +Z -Z
+                            gl.texImage2D(facesIndex[0], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][0]);
+                            gl.texImage2D(facesIndex[1], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][2]);
+                            gl.texImage2D(facesIndex[2], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][4]);
+                            gl.texImage2D(facesIndex[3], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][1]);
+                            gl.texImage2D(facesIndex[4], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][3]);
+                            gl.texImage2D(facesIndex[5], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][5]);
+                        }
+                    }
+                    else {
+                        // Data are known to be in +X +Y +Z -X -Y -Z
+                        for (var index = 0; index < facesIndex.length; index++) {
+                            var faceData = rgbeDataArrays[index];
+                            gl.texImage2D(facesIndex[index], 0, internalFormat, width, height, 0, internalFormat, textureType, faceData);
+                        }
+                        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                    }
                 }
                 else {
                     noMipmap = true;

+ 37 - 7
src/babylon.engine.ts

@@ -1913,7 +1913,9 @@
             return texture;
         }
 
-        public createRawCubeTexture(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean, callback: (ArrayBuffer) => ArrayBufferView[]): WebGLTexture {
+        public createRawCubeTexture(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
+            callback: (ArrayBuffer) => ArrayBufferView[],
+            mipmmapGenerator: ((faces: ArrayBufferView[]) => ArrayBufferView[][])): WebGLTexture {
             var gl = this._gl;
             var texture = gl.createTexture();
             scene._addPendingData(texture);
@@ -1950,13 +1952,41 @@
                 gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
                 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
 
-                for (var index = 0; index < facesIndex.length; index++) {
-                    var faceData = rgbeDataArrays[index];
-                    gl.texImage2D(facesIndex[index], 0, internalFormat, width, height, 0, internalFormat, textureType, faceData);
-                }
-
                 if (!noMipmap && isPot) {
-                    gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                    if (mipmmapGenerator) {
+                        
+                        var arrayTemp: ArrayBufferView[] = [];
+                        // Data are known to be in +X +Y +Z -X -Y -Z
+                        // mipmmapGenerator data is expected to be order in +X -X +Y -Y +Z -Z
+                        arrayTemp.push(rgbeDataArrays[0]); // +X
+                        arrayTemp.push(rgbeDataArrays[3]); // -X
+                        arrayTemp.push(rgbeDataArrays[1]); // +Y
+                        arrayTemp.push(rgbeDataArrays[4]); // -Y
+                        arrayTemp.push(rgbeDataArrays[2]); // +Z
+                        arrayTemp.push(rgbeDataArrays[5]); // -Z
+                        
+                        var mipData = mipmmapGenerator(arrayTemp);
+                        for (var level = 0; level < mipData.length; level++) {
+                            var mipSize = width >> level;
+                            
+                            // mipData is order in +X -X +Y -Y +Z -Z
+                            gl.texImage2D(facesIndex[0], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][0]);
+                            gl.texImage2D(facesIndex[1], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][2]);
+                            gl.texImage2D(facesIndex[2], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][4]);
+                            gl.texImage2D(facesIndex[3], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][1]);
+                            gl.texImage2D(facesIndex[4], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][3]);
+                            gl.texImage2D(facesIndex[5], level, internalFormat, mipSize, mipSize, 0, internalFormat, textureType, mipData[level][5]);
+                        }
+                    }
+                    else {
+                        // Data are known to be in +X +Y +Z -X -Y -Z
+                        for (var index = 0; index < facesIndex.length; index++) {
+                            var faceData = rgbeDataArrays[index];
+                            gl.texImage2D(facesIndex[index], 0, internalFormat, width, height, 0, internalFormat, textureType, faceData);
+                        }
+                        
+                        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+                    }
                 }
                 else {
                     noMipmap = true;