Ver código fonte

DefaultRenderingPipeline - step 1

David Catuhe 8 anos atrás
pai
commit
7c74c9f0b4

Diferenças do arquivo suprimidas por serem muito extensas
+ 3364 - 3338
dist/preview release/babylon.d.ts


Diferenças do arquivo suprimidas por serem muito extensas
+ 3364 - 3338
dist/preview release/babylon.module.d.ts


+ 5 - 3
dist/preview release/loaders/babylon.stlFileLoader.d.ts

@@ -5,9 +5,11 @@ declare module BABYLON {
         facetsPattern: RegExp;
         normalPattern: RegExp;
         vertexPattern: RegExp;
-        extensions: string;
+        extensions: ISceneLoaderPluginExtensions;
         importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]): boolean;
-        load(scene: Scene, data: string, rootUrl: string): boolean;
-        private parseSolid(mesh, solidData);
+        load(scene: Scene, data: any, rootUrl: string): boolean;
+        private isBinary(data);
+        private parseBinary(mesh, data);
+        private parseASCII(mesh, solidData);
     }
 }

+ 80 - 8
dist/preview release/loaders/babylon.stlFileLoader.js

@@ -7,14 +7,31 @@ var BABYLON;
             this.facetsPattern = /facet([\s\S]*?)endfacet/g;
             this.normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
             this.vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-            this.extensions = ".stl";
+            // force data to come in as an ArrayBuffer
+            // we'll convert to string if it looks like it's an ASCII .stl
+            this.extensions = {
+                ".stl": { isBinary: true },
+            };
         }
         STLFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
             var matches;
-            if (typeof data !== "string") {
-                BABYLON.Tools.Error("STL format not recognized. Ensure it's ASCII formatted");
-                return false;
+            if (this.isBinary(data)) {
+                // binary .stl
+                var babylonMesh = new BABYLON.Mesh("stlmesh", scene);
+                this.parseBinary(babylonMesh, data);
+                if (meshes) {
+                    meshes.push(babylonMesh);
+                }
+                return true;
+            }
+            // ASCII .stl
+            // convert to string
+            var array_buffer = new Uint8Array(data);
+            var str = '';
+            for (var i = 0; i < data.byteLength; i++) {
+                str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
             }
+            data = str;
             while (matches = this.solidPattern.exec(data)) {
                 var meshName = matches[1];
                 var meshNameFromEnd = matches[3];
@@ -38,8 +55,10 @@ var BABYLON;
                 // stl mesh name can be empty as well
                 meshName = meshName || "stlmesh";
                 var babylonMesh = new BABYLON.Mesh(meshName, scene);
-                this.parseSolid(babylonMesh, matches[2]);
-                meshes.push(babylonMesh);
+                this.parseASCII(babylonMesh, matches[2]);
+                if (meshes) {
+                    meshes.push(babylonMesh);
+                }
             }
             return true;
         };
@@ -50,9 +69,62 @@ var BABYLON;
             }
             return result;
         };
-        STLFileLoader.prototype.parseSolid = function (mesh, solidData) {
-            var normals = [];
+        STLFileLoader.prototype.isBinary = function (data) {
+            // check if file size is correct for binary stl
+            var faceSize, nFaces, reader;
+            reader = new DataView(data);
+            faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
+            nFaces = reader.getUint32(80, true);
+            if (80 + (32 / 8) + (nFaces * faceSize) === reader.byteLength) {
+                return true;
+            }
+            // check characters higher than ASCII to confirm binary
+            var fileLength = reader.byteLength;
+            for (var index = 0; index < fileLength; index++) {
+                if (reader.getUint8(index, false) > 127) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        STLFileLoader.prototype.parseBinary = function (mesh, data) {
+            var reader = new DataView(data);
+            var faces = reader.getUint32(80, true);
+            var dataOffset = 84;
+            var faceLength = 12 * 4 + 2;
+            var offset = 0;
+            var positions = new Float32Array(faces * 3 * 3);
+            var normals = new Float32Array(faces * 3 * 3);
+            var indices = new Uint32Array(faces * 3);
+            var indicesCount = 0;
+            for (var face = 0; face < faces; face++) {
+                var start = dataOffset + face * faceLength;
+                var normalX = reader.getFloat32(start, true);
+                var normalY = reader.getFloat32(start + 4, true);
+                var normalZ = reader.getFloat32(start + 8, true);
+                for (var i = 1; i <= 3; i++) {
+                    var vertexstart = start + i * 12;
+                    // ordering is intentional to match ascii import
+                    positions[offset] = reader.getFloat32(vertexstart, true);
+                    positions[offset + 2] = reader.getFloat32(vertexstart + 4, true);
+                    positions[offset + 1] = reader.getFloat32(vertexstart + 8, true);
+                    normals[offset] = normalX;
+                    normals[offset + 2] = normalY;
+                    normals[offset + 1] = normalZ;
+                    offset += 3;
+                }
+                indices[indicesCount] = indicesCount++;
+                indices[indicesCount] = indicesCount++;
+                indices[indicesCount] = indicesCount++;
+            }
+            mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions);
+            mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals);
+            mesh.setIndices(indices);
+            mesh.computeWorldMatrix(true);
+        };
+        STLFileLoader.prototype.parseASCII = function (mesh, solidData) {
             var positions = [];
+            var normals = [];
             var indices = [];
             var indicesCount = 0;
             //load facets, ignoring loop as the standard doesn't define it can contain more than vertices

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/loaders/babylon.stlFileLoader.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.legacyPbrMaterial.js

@@ -1270,7 +1270,7 @@ var BABYLON;
         };
         LegacyPBRMaterial.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.legacyPBRMaterial";
+            serializationObject.customType = "BABYLON.LegacyPBRMaterial";
             return serializationObject;
         };
         // Statics

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/materialsLibrary/babylon.legacyPbrMaterial.min.js


+ 189 - 26
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -2,42 +2,89 @@
     export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
         private _scene: Scene;     
 
-        /**
-        * The FxaaPostProcess Id
-        * @type {string}
-        */
+        readonly PassPostProcessId: string = "PassPostProcessEffect";           
+        readonly HighLightsPostProcessId: string = "HighLightsPostProcessEffect";  
+        readonly BlurXPostProcessId: string = "BlurXPostProcessEffect";  
+        readonly BlurYPostProcessId: string = "BlurYPostProcessEffect";  
+        readonly CopyBackPostProcessId: string = "CopyBackPostProcessEffect";  
+        readonly ImageProcessingPostProcessId: string = "ImageProcessingPostProcessEffect";  
         readonly FxaaPostProcessId: string = "FxaaPostProcessEffect";           
+        readonly FinalMergePostProcessId: string = "FinalMergePostProcessEffect";
 
         // Post-processes
+		public pass: BABYLON.PassPostProcess;
+		public highlights: BABYLON.HighlightsPostProcess;
+		public blurX: BABYLON.BlurPostProcess;
+		public blurY: BABYLON.BlurPostProcess;
+		public copyBack: BABYLON.PassPostProcess;
         public fxaa: FxaaPostProcess;
         public imageProcessing: ImageProcessingPostProcess;
+		public finalMerge: BABYLON.PassPostProcess;        
 
         // IAnimatable
         public animations: Animation[] = [];        
 
         // Values       
+        private _bloomEnabled: boolean = false;
         private _fxaaEnabled: boolean = false;
         private _imageProcessingEnabled: boolean = false;
+        private _defaultPipelineTextureType: number;
+        private _bloomScale: number = 0.6;
+
+        /**
+		 * Specifies the size of the bloom blur kernel, relative to the final output size
+		 */
+        @serialize()
+		public bloomKernel: number = 64;
+
+        /**
+		 * Specifies the weight of the bloom in the final rendering
+		 */
+        @serialize()
+		public bloomWeight: number = 0.15;        
 
         @serialize()
         private _hdr: boolean;
 
-        public set FxaaEnabled(enabled: boolean) {
-            if (this._fxaaEnabled === enabled) {
+        public set bloomScale(value: number) {
+            if (this._bloomScale === value) {
                 return;
             }
-            this._fxaaEnabled = enabled;
+            this._bloomScale = value;
 
-            if (enabled) {
-                this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.FxaaPostProcessId, this._scene.cameras);
+            this._buildPipeline();
+        }   
+        
+        @serialize()
+        public get bloomScale(): number {
+            return this._bloomScale;
+        }          
+
+        public set bloomEnabled(enabled: boolean) {
+            if (this._bloomEnabled === enabled) {
+                return;
             }
-            else {
-                this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.FxaaPostProcessId, this._scene.cameras);
+            this._bloomEnabled = enabled;
+
+            this._buildPipeline();
+        }   
+        
+        @serialize()
+        public get bloomEnabled(): boolean {
+            return this._bloomEnabled;
+        }        
+
+        public set fxaaEnabled(enabled: boolean) {
+            if (this._fxaaEnabled === enabled) {
+                return;
             }
+            this._fxaaEnabled = enabled;
+
+            this._buildPipeline();
         }
 
         @serialize()
-        public get FxaaEnabled(): boolean {
+        public get fxaaEnabled(): boolean {
             return this._fxaaEnabled;
         }
 
@@ -57,29 +104,145 @@
             this._scene = scene;
 
             // Misc
-            var floatTextureType = scene.getEngine().getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
-
-            // fxaa
-            this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, floatTextureType);
-            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.FxaaPostProcessId, () => { return this.fxaa; }, true));
+            this._defaultPipelineTextureType = scene.getEngine().getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
 
-            // Finish
+            // Attach
             scene.postProcessRenderPipelineManager.addPipeline(this);
 
-            if (cameras !== null) {
-                scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
-            }
+            this._buildPipeline();
+        }
+
+        private _buildPipeline() {
+            var engine = this._scene.getEngine();
 
-            // Deactivate
-            this.FxaaEnabled = false;
+            this._disposePostProcesses();
+            this._reset();
+
+			if (this.bloomEnabled) {
+				this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.PassPostProcessId, () => { return this.pass; }, true));
+
+				if (!this._hdr) { // Need to enhance highlights if not using float rendering
+					this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                    this.addEffect(new PostProcessRenderEffect(engine, this.HighLightsPostProcessId, () => { return this.highlights; }, true));
+					this.highlights.autoClear = false;
+					this.highlights.alwaysForcePOT = true;
+				}
+
+				this.blurX = new BABYLON.BlurPostProcess("horizontal blur", new BABYLON.Vector2(1.0, 0), 10.0, this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.BlurXPostProcessId, () => { return this.blurX; }, true));
+				this.blurX.alwaysForcePOT = true;
+				this.blurX.autoClear = false;
+				this.blurX.onActivateObservable.add(() => {
+					let dw = this.blurX.width / engine.getRenderWidth();
+					this.blurX.kernel = this.bloomKernel * dw;
+				});
+
+				this.blurY = new BABYLON.BlurPostProcess("vertical blur", new BABYLON.Vector2(0, 1.0), 10.0, this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.BlurYPostProcessId, () => { return this.blurY; }, true));
+				this.blurY.alwaysForcePOT = true;
+				this.blurY.autoClear = false;
+				this.blurY.onActivateObservable.add(() => {
+					let dh = this.blurY.height / engine.getRenderHeight();
+					this.blurY.kernel = this.bloomKernel * dh;
+				});				
+
+				this.copyBack = new BABYLON.PassPostProcess("bloomBlendBlit", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);			
+                this.addEffect(new PostProcessRenderEffect(engine, this.CopyBackPostProcessId, () => { return this.copyBack; }, true));
+				this.copyBack.alwaysForcePOT = true;
+				if (this._hdr) {
+					this.copyBack.alphaMode = BABYLON.Engine.ALPHA_INTERPOLATE;
+					let w = this.bloomWeight;
+					this.copyBack.alphaConstants = new BABYLON.Color4(w, w, w, w);			
+				} else {
+					this.copyBack.alphaMode = BABYLON.Engine.ALPHA_SCREENMODE;
+				}
+				this.copyBack.autoClear = false;
+			}
+
+			this.imageProcessing = new BABYLON.ImageProcessingPostProcess("imageProcessing",  1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+			if (this._hdr) {
+				this.addEffect(new PostProcessRenderEffect(engine, this.ImageProcessingPostProcessId, () => { return this.imageProcessing; }, true));
+			}
+
+			if (this.fxaaEnabled) {
+                this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.FxaaPostProcessId, () => { return this.fxaa; }, true));               
+				this.fxaa.autoClear = false;
+			} else {
+				this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.FinalMergePostProcessId, () => { return this.finalMerge; }, true)); 
+				this.finalMerge.autoClear = false;
+			}
+
+			if (this.bloomEnabled) {
+				if (this._hdr) { // Share render targets to save memory
+					this.copyBack.shareOutputWith(this.blurX);		
+					this.imageProcessing.shareOutputWith(this.pass);			
+					this.imageProcessing.autoClear = false;
+				} else  {
+					if (this.fxaa) {
+						this.fxaa.shareOutputWith(this.pass);		
+					} else {
+						this.finalMerge.shareOutputWith(this.pass);	
+					} 
+				}
+			}
+
+            if (this._cameras !== null) {
+                this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
+            }            
         }
-        // Dispose
-        public dispose(): void {
+
+        private _disposePostProcesses(): void {
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
 
-                this.fxaa.dispose(camera);
+                if (this.pass) {
+                    this.pass.dispose(camera);
+                    this.pass = null;
+                }
+
+                if (this.highlights) {
+                    this.highlights.dispose(camera);
+                    this.highlights = null;
+                }        
+
+                if (this.blurX) {
+                    this.blurX.dispose(camera);
+                    this.blurX = null;
+                }      
+
+                if (this.blurY) {
+                    this.blurY.dispose(camera);
+                    this.blurY = null;
+                }         
+
+                if (this.copyBack) {
+                    this.copyBack.dispose(camera);
+                    this.copyBack = null;
+                }   
+
+                if (this.imageProcessing) {
+                    this.imageProcessing.dispose(camera);
+                    this.imageProcessing = null;
+                }                                                                
+
+                if (this.fxaa) {
+                    this.fxaa.dispose(camera);
+                    this.fxaa = null;
+                }
+
+                if (this.finalMerge) {
+                    this.finalMerge.dispose(camera);
+                    this.finalMerge = null;
+                }                
             }
+        }
+
+        // Dispose
+        public dispose(): void {
+            this._disposePostProcesses();
 
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
 

+ 9 - 4
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts

@@ -2,8 +2,8 @@ module BABYLON {
     export class PostProcessRenderPipeline {
         private _engine: Engine;
 
-        private _renderEffects: any;
-        private _renderEffectsForIsolatedPass: any;
+        private _renderEffects: PostProcessRenderEffect[];
+        private _renderEffectsForIsolatedPass: PostProcessRenderEffect[];
 
         protected _cameras: Camera[];
 
@@ -18,8 +18,8 @@ module BABYLON {
             this._engine = engine;
             this._name = name;
 
-            this._renderEffects = {};
-            this._renderEffectsForIsolatedPass = {};
+            this._renderEffects = new Array<PostProcessRenderEffect>();
+            this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();
 
             this._cameras = [];
         }
@@ -175,6 +175,11 @@ module BABYLON {
             }
         }
 
+        public _reset(): void {
+            this._renderEffects = new Array<PostProcessRenderEffect>();
+            this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();
+        }
+
         public dispose() {
            // Must be implemented by children 
         }

+ 8 - 5
src/PostProcess/babylon.blurPostProcess.ts

@@ -7,6 +7,10 @@
 		 * Sets the length in pixels of the blur sample region
 		 */
 		public set kernel(v: number) {
+			if (this._idealKernel === v) {
+				return;
+			}
+
 			v = Math.max(v, 1);
 			this._idealKernel = v;
 			this._kernel = this._nearestBestKernel(v);
@@ -109,11 +113,10 @@
                 defines += `#define KERNEL_DEP_WEIGHT${depCount} ${this._glslFloat(weights[i])}\r\n`;
                 depCount++;
 			}
-
-            this._indexParameters.varyingCount = varyingCount;
-            this._indexParameters.depCount = depCount;
-
-            this.updateEffect(defines);
+            this.updateEffect(defines, null, null, {
+				varyingCount: varyingCount,
+				depCount: depCount
+			});
         }
 
         /**

+ 3 - 1
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -4,6 +4,8 @@
 		public colorGradingWeight: number = 1.0;
 		public colorCurves = new ColorCurves();
 
+        public cameraFov = 0.5;
+
 		public vignetteStretch = 0;
 		public vignetteCentreX = 0;
 		public vignetteCentreY = 0;
@@ -76,7 +78,7 @@
                 ColorCurves.Bind(this.colorCurves, effect);
 
                 // Vignette
-                let vignetteScaleY = Math.tan(this.getCamera().fov * 0.5);
+                let vignetteScaleY = Math.tan(this.cameraFov * 0.5);
                 let vignetteScaleX = vignetteScaleY * aspectRatio;
 
                 let vignetteScaleGeometricMean = Math.sqrt(vignetteScaleX * vignetteScaleY);