Browse Source

Fix Polynomial map format and type

Sebastien Vandenberghe 8 years ago
parent
commit
5da25bfb81

+ 36 - 52
src/Tools/HDR/babylon.cubemapToSphericalPolynomial.ts

@@ -43,12 +43,20 @@ module BABYLON.Internals {
             }
 
             var size = texture.getSize().width;
-            var right = <Float32Array>texture.readPixels(0);
-            var left = <Float32Array>texture.readPixels(1);
-            var up = <Float32Array>texture.readPixels(2);
-            var down = <Float32Array>texture.readPixels(3);
-            var front = <Float32Array>texture.readPixels(4);
-            var back = <Float32Array>texture.readPixels(5);
+            var right = texture.readPixels(0);
+            var left = texture.readPixels(1);
+            var up = texture.readPixels(2);
+            var down = texture.readPixels(3);
+            var front = texture.readPixels(4);
+            var back = texture.readPixels(5);
+
+            var gammaSpace = texture.gammaSpace;
+            // Always read as RGBA.
+            var format = Engine.TEXTUREFORMAT_RGBA;
+            var type = Engine.TEXTURETYPE_UNSIGNED_INT;
+            if (texture.textureType && texture.textureType !== Engine.TEXTURETYPE_UNSIGNED_INT) {
+                type = Engine.TEXTURETYPE_FLOAT;
+            }
 
             var cubeInfo: CubeMapInfo = {
                 size,
@@ -58,6 +66,9 @@ module BABYLON.Internals {
                 down,
                 front,
                 back,
+                format,
+                type,
+                gammaSpace,
             };
 
             return this.ConvertCubeMapToSphericalPolynomial(cubeInfo);
@@ -89,7 +100,7 @@ module BABYLON.Internals {
                 // TODO: we could perform the summation directly into a SphericalPolynomial (SP), which is more efficient than SphericalHarmonic (SH).
                 // This is possible because during the summation we do not need the SH-specific properties, e.g. orthogonality.
                 // Because SP is still linear, so summation is fine in that basis.
-
+                const stride = cubeInfo.format === Engine.TEXTUREFORMAT_RGBA ? 4 : 3;
                 for (var y = 0; y < cubeInfo.size; y++) {
                     var u = minUV;
 
@@ -103,55 +114,28 @@ module BABYLON.Internals {
 
                         var deltaSolidAngle = Math.pow(1.0 + u * u + v * v, -3.0 / 2.0);
 
-                        if (1) {
-                            var r = dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0];
-                            var g = dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1];
-                            var b = dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2];
-
-                            var color = new Color3(r, g, b);
+                        var r = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 0];
+                        var g = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 1];
+                        var b = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 2];
 
-                            sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);
+                        // Handle Integer types.
+                        if (cubeInfo.type === Engine.TEXTURETYPE_UNSIGNED_INT) {
+                            r /= 255;
+                            g /= 255;
+                            b /= 255;
                         }
-                        else {
-
-                            if (faceIndex == 0) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 0;
-                            }
-                            else if (faceIndex == 1) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 0;
-                            }
-                            else if (faceIndex == 2) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 1;
-                            }
-                            else if (faceIndex == 3) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 0;
-                            }
-                            else if (faceIndex == 4) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 1;
-                            }
-                            else if (faceIndex == 5) {
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0] = 0;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1] = 1;
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2] = 1;
-                            }
-
-                            var color = new Color3(dataArray[(y * cubeInfo.size * 3) + (x * 3) + 0],
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 1],
-                                dataArray[(y * cubeInfo.size * 3) + (x * 3) + 2]);
-
-                            sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);
+
+                        // Handle Gamma space textures.
+                        if (cubeInfo.gammaSpace) {
+                            r = Math.pow(r, ToLinearSpace);
+                            g = Math.pow(g, ToLinearSpace);
+                            b = Math.pow(b, ToLinearSpace);
                         }
 
+                        var color = new Color3(r, g, b);
+
+                        sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);
+
                         totalSolidAngle += deltaSolidAngle;
 
                         u += du;

+ 35 - 13
src/Tools/HDR/babylon.panoramaToCubemap.ts

@@ -5,39 +5,39 @@ module BABYLON.Internals {
     export interface CubeMapInfo {
         /**
          * The pixel array for the front face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        front: Float32Array;
+        front: ArrayBufferView;
         
         /**
          * The pixel array for the back face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        back: Float32Array;
+        back: ArrayBufferView;
         
         /**
          * The pixel array for the left face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        left: Float32Array;
+        left: ArrayBufferView;
         
         /**
          * The pixel array for the right face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        right: Float32Array;
+        right: ArrayBufferView;
         
         /**
          * The pixel array for the up face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        up: Float32Array;
+        up: ArrayBufferView;
         
         /**
          * The pixel array for the down face.
-         * This is stored in RGB, left to right, up to down format.
+         * This is stored in format, left to right, up to down format.
          */
-        down: Float32Array;
+        down: ArrayBufferView;
         
         /**
          * The size of the cubemap stored.
@@ -45,6 +45,25 @@ module BABYLON.Internals {
          * Each faces will be size * size pixels.
          */
         size: number;
+
+        /**
+         * The format of the texture.
+         * 
+         * RGBA, RGB.
+         */
+        format: number;
+
+        /**
+         * The type of the texture data.
+         * 
+         * UNSIGNED_INT, FLOAT.
+         */
+        type: number;
+
+        /**
+         * Specifies whether the texture is in gamma space.
+         */
+        gammaSpace: boolean;
     }
 
     /**
@@ -121,7 +140,10 @@ module BABYLON.Internals {
                 right: textureRight,
                 up: textureUp,
                 down: textureDown,
-                size: size
+                size: size,
+                type: Engine.TEXTURETYPE_FLOAT,
+                format: Engine.TEXTUREFORMAT_RGB,
+                gammaSpace: false,
             };
         }
 

+ 8 - 9
src/babylon.engine.ts

@@ -2465,7 +2465,7 @@
 
                          var loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && !noMipmap && ((info.width >> (info.mipmapCount - 1)) === 1);
                          prepareWebGLTexture(texture, this._gl, scene, info.width, info.height, invertY, !loadMipmap, info.isFourCC, () => {
-                        //     Internals.DDSTools.UploadDDSLevels(this, data, info, loadMipmap, 1);
+                             Internals.DDSTools.UploadDDSLevels(this, data, info, loadMipmap, 1);
                          }, samplingMode);
                     };
                 }
@@ -3953,27 +3953,26 @@
             gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);
 
             if (faceIndex > -1) {
-                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture, lodIndex);            
+                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture, lodIndex);
             } else {
                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, lodIndex);
             }
 
-            let readFormat = (texture.type !== undefined) ? this._getRGBABufferInternalSizedFormat(texture.type) : gl.RGBA;
+            let readFormat = (texture.format !== undefined) ? this._getRGBABufferInternalSizedFormat(texture.format) : gl.RGBA;
             let readType = (texture.type !== undefined) ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;
             let buffer: ArrayBufferView;
 
             switch (readType) {
                 case gl.UNSIGNED_BYTE:
                     buffer = new Uint8Array(4 * width * height);
+                    readType = gl.UNSIGNED_BYTE;
                     break;
-                case gl.FLOAT:
+                default:
                     buffer = new Float32Array(4 * width * height);
-                    break;            
-                case gl.HALF_FLOAT_OES:
-                    buffer = new Uint16Array(4 * width * height);
-                    break;                          
+                    readType = gl.FLOAT;
+                    break;
             }
-            gl.readPixels(0, 0, width, height, readFormat, readType, buffer);
+            gl.readPixels(0, 0, width, height, gl.RGBA, readType, buffer);
             
             gl.bindFramebuffer(gl.FRAMEBUFFER, null);