Explorar o código

Added postprocess.enablePixelPerfectMode to avoid texture scaling/stretching when dealing with non-power of 2 resolutions

David Catuhe %!s(int64=9) %!d(string=hai) anos
pai
achega
7378387e6b

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 8 - 8
dist/preview release/babylon.core.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 3533 - 3519
dist/preview release/babylon.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 15 - 15
dist/preview release/babylon.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 36 - 7
dist/preview release/babylon.max.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 15 - 15
dist/preview release/babylon.noworker.js


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

@@ -4,7 +4,7 @@
     - Added support for HDR cubemaps ([sebavan](https://github.com/sebavan))
     - Support for shaders includes ([deltakosh](https://github.com/deltakosh))
     - new mesh type : `LineSystem` ([jerome](https://github.com/jbousquie))
-    - SerializationHelper for complex classes using TypeScript decorators  ([deltakosh](https://github.com/deltakosh))
+    - SerializationHelper for complex classes using TypeScript decorators ([deltakosh](https://github.com/deltakosh))
     - StandardMaterial now supports Parallax and Parallax Occlusion Mapping ([nockawa](https://github.com/nockawa))
     - Animations blending. See [demo here](http://www.babylonjs-playground.com/#2BLI9T#3). More [info here](NEED DOC!) ([deltakosh](https://github.com/deltakosh))
     - New debuger tool: SkeletonViewer. See [demo here](Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8) (Adam & [deltakosh](https://github.com/deltakosh))
@@ -15,6 +15,7 @@
     - Unity3D exporter: Added support for export and run (local webserver) ([davrous](https://github.com/davrous), [deltakosh](https://github.com/deltakosh))
     - Moved PBR Material to core ([deltakosh](https://github.com/deltakosh))
   - **Updates**
+    - Added postprocess.enablePixelPerfectMode to avoid texture scaling/stretching when dealing with non-power of 2 resolutions. cannot be used on post-processes chain ([deltakosh](https://github.com/deltakosh))
     - Added skeleton.getBoneIndexByName(boneName: string) [dad72](https://github.com/dad72)
     - Added node._children to track children hierarchy ([deltakosh](https://github.com/deltakosh))
     - Added Camera.ForceAttachControlToAlwaysPreventDefault to help embedding Babylon.js in iFrames ([deltakosh](https://github.com/deltakosh))

+ 13 - 1
src/Mesh/babylon.mesh.js

@@ -1044,7 +1044,7 @@ var BABYLON;
             }
         };
         /**
-         * Returns as a new array
+         * Returns as a new array populated with the mesh material and/or skeleton, if any.
          */
         Mesh.prototype.getAnimatables = function () {
             var results = [];
@@ -1479,6 +1479,11 @@ var BABYLON;
             });
         };
         // Statics
+        /**
+         * Returns a new `Mesh` object what is a deep copy of the passed mesh.
+         * The parameter `parsedMesh` is the mesh to be copied.
+         * The parameter `rootUrl` is a string, it's the root URL to prefix the `delayLoadingFile` property with
+         */
         Mesh.Parse = function (parsedMesh, scene, rootUrl) {
             var mesh = new Mesh(parsedMesh.name, scene);
             mesh.id = parsedMesh.id;
@@ -2221,6 +2226,10 @@ var BABYLON;
             return this;
         };
         // Tools
+        /**
+         * Returns an object `{min: Vector3, max: Vector3}`
+         * This min and max `Vector3` are the minimum and maximum vectors of each mesh bounding box from the passed array, in the World system
+         */
         Mesh.MinMax = function (meshes) {
             var minVector = null;
             var maxVector = null;
@@ -2240,6 +2249,9 @@ var BABYLON;
                 max: maxVector
             };
         };
+        /**
+         * Returns a `Vector3`, the center of the `{min: Vector3, max: Vector3}` or the center of MinMax vector3 computed from a mesh array.
+         */
         Mesh.Center = function (meshesOrMinMaxVector) {
             var minMaxVector = meshesOrMinMaxVector.min !== undefined ? meshesOrMinMaxVector : Mesh.MinMax(meshesOrMinMaxVector);
             return BABYLON.Vector3.Center(minMaxVector.min, minMaxVector.max);

+ 20 - 3
src/PostProcess/babylon.postProcess.js

@@ -7,9 +7,15 @@ var BABYLON;
             this.name = name;
             this.width = -1;
             this.height = -1;
+            /*
+                Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+                Can only be used on a single postprocess or on the last one of a chain.
+            */
+            this.enablePixelPerfectMode = false;
             this._reusable = false;
             this._textures = new BABYLON.SmartArray(2);
             this._currentRenderTextureInd = 0;
+            this._scaleRatio = new BABYLON.Vector2(1, 1);
             if (camera != null) {
                 this._camera = camera;
                 this._scene = camera.getScene();
@@ -27,6 +33,7 @@ var BABYLON;
             this._samplers.push("textureSampler");
             this._fragmentUrl = fragmentUrl;
             this._parameters = parameters || [];
+            this._parameters.push("scale");
             this.updateEffect(defines);
         }
         PostProcess.prototype.updateEffect = function (defines) {
@@ -39,8 +46,10 @@ var BABYLON;
             camera = camera || this._camera;
             var scene = camera.getScene();
             var maxSize = camera.getEngine().getCaps().maxTextureSize;
-            var desiredWidth = this._renderRatio.width || ((sourceTexture ? sourceTexture._width : this._engine.getRenderingCanvas().width) * this._renderRatio) | 0;
-            var desiredHeight = this._renderRatio.height || ((sourceTexture ? sourceTexture._height : this._engine.getRenderingCanvas().height) * this._renderRatio) | 0;
+            var requiredWidth = ((sourceTexture ? sourceTexture._width : this._engine.getRenderingCanvas().width) * this._renderRatio) | 0;
+            var requiredHeight = ((sourceTexture ? sourceTexture._height : this._engine.getRenderingCanvas().height) * this._renderRatio) | 0;
+            var desiredWidth = this._renderRatio.width || requiredWidth;
+            var desiredHeight = this._renderRatio.height || requiredHeight;
             if (this.renderTargetSamplingMode !== BABYLON.Texture.NEAREST_SAMPLINGMODE) {
                 if (!this._renderRatio.width) {
                     desiredWidth = BABYLON.Tools.GetExponentOfTwo(desiredWidth, maxSize);
@@ -66,7 +75,14 @@ var BABYLON;
                     this.onSizeChanged();
                 }
             }
-            this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd]);
+            if (this.enablePixelPerfectMode) {
+                this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);
+                this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd], 0, requiredWidth, requiredHeight);
+            }
+            else {
+                this._scaleRatio.copyFromFloats(1, 1);
+                this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd]);
+            }
             if (this.onActivate) {
                 this.onActivate(camera);
             }
@@ -101,6 +117,7 @@ var BABYLON;
             // Texture
             this._effect._bindTexture("textureSampler", this._textures.data[this._currentRenderTextureInd]);
             // Parameters
+            this._effect.setVector2("scale", this._scaleRatio);
             if (this.onApply) {
                 this.onApply(this._effect);
             }

+ 23 - 3
src/PostProcess/babylon.postProcess.ts

@@ -10,6 +10,12 @@
         public renderTargetSamplingMode: number;
         public clearColor: Color4;
 
+        /*
+            Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+            Can only be used on a single postprocess or on the last one of a chain.
+        */ 
+        public enablePixelPerfectMode = false;
+
         private _camera: Camera;
         private _scene: Scene;
         private _engine: Engine;
@@ -22,6 +28,7 @@
         private _samplers: string[];
         private _fragmentUrl: string;
         private _parameters: string[];
+        private _scaleRatio = new Vector2(1, 1);
 
         constructor(public name: string, fragmentUrl: string, parameters: string[], samplers: string[], ratio: number|any, camera: Camera, samplingMode: number = Texture.NEAREST_SAMPLINGMODE, engine?: Engine, reusable?: boolean, defines?: string, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             if (camera != null) {
@@ -45,6 +52,8 @@
             this._fragmentUrl = fragmentUrl;
             this._parameters = parameters || [];
 
+            this._parameters.push("scale");
+
             this.updateEffect(defines);
         }
 
@@ -65,8 +74,11 @@
             var scene = camera.getScene();
             var maxSize = camera.getEngine().getCaps().maxTextureSize;
 
-            var desiredWidth = this._renderRatio.width || ((sourceTexture ? sourceTexture._width : this._engine.getRenderingCanvas().width) * this._renderRatio) | 0;
-            var desiredHeight = this._renderRatio.height || ((sourceTexture ? sourceTexture._height : this._engine.getRenderingCanvas().height) * this._renderRatio) | 0;
+            var requiredWidth = ((sourceTexture ? sourceTexture._width : this._engine.getRenderingCanvas().width) * this._renderRatio) | 0;
+            var requiredHeight = ((sourceTexture ? sourceTexture._height : this._engine.getRenderingCanvas().height) * this._renderRatio) | 0;
+
+            var desiredWidth = this._renderRatio.width || requiredWidth;
+            var desiredHeight = this._renderRatio.height || requiredHeight;
 
             if (this.renderTargetSamplingMode !== Texture.NEAREST_SAMPLINGMODE) {
                 if (!this._renderRatio.width) {
@@ -98,7 +110,14 @@
                 }
             }
 
-            this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd]);
+            if (this.enablePixelPerfectMode) {
+                this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);
+                this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd], 0, requiredWidth, requiredHeight);
+            }
+            else {
+                this._scaleRatio.copyFromFloats(1, 1);
+                this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd]);
+            }
 
             if (this.onActivate) {
                 this.onActivate(camera);
@@ -136,6 +155,7 @@
             this._effect._bindTexture("textureSampler", this._textures.data[this._currentRenderTextureInd]);
 
             // Parameters
+            this._effect.setVector2("scale", this._scaleRatio);
             if (this.onApply) {
                 this.onApply(this._effect);
             }

+ 3 - 1
src/Shaders/postprocess.vertex.fx

@@ -1,6 +1,8 @@
 // Attributes
 attribute vec2 position;
 
+
+uniform vec2 scale;
 // Output
 varying vec2 vUV;
 
@@ -8,6 +10,6 @@ const vec2 madd = vec2(0.5, 0.5);
 
 void main(void) {	
 
-	vUV = position * madd + madd;
+	vUV = (position * madd + madd) * scale;
 	gl_Position = vec4(position, 0.0, 1.0);
 }

+ 2 - 2
src/babylon.engine.js

@@ -635,7 +635,7 @@ var BABYLON;
                 }
             }
         };
-        Engine.prototype.bindFramebuffer = function (texture, faceIndex) {
+        Engine.prototype.bindFramebuffer = function (texture, faceIndex, requiredWidth, requiredHeight) {
             this._currentRenderTarget = texture;
             var gl = this._gl;
             gl.bindFramebuffer(gl.FRAMEBUFFER, texture._framebuffer);
@@ -645,7 +645,7 @@ var BABYLON;
             else {
                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
             }
-            this._gl.viewport(0, 0, texture._width, texture._height);
+            this._gl.viewport(0, 0, requiredWidth || texture._width, requiredHeight || texture._height);
             this.wipeCaches();
         };
         Engine.prototype.unBindFramebuffer = function (texture, disableGenerateMipMaps) {

+ 2 - 2
src/babylon.engine.ts

@@ -750,7 +750,7 @@
             }
         }
 
-        public bindFramebuffer(texture: WebGLTexture, faceIndex?: number): void {
+        public bindFramebuffer(texture: WebGLTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number): void {
             this._currentRenderTarget = texture;
 
             var gl = this._gl;
@@ -762,7 +762,7 @@
                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
             }
 
-            this._gl.viewport(0, 0, texture._width, texture._height);
+            this._gl.viewport(0, 0, requiredWidth || texture._width, requiredHeight || texture._height);
 
             this.wipeCaches();
         }