Browse Source

formatting uniforms in 2 buffer, dynamic and static

Benjamin Guignabert 8 years ago
parent
commit
34da134bdf

File diff suppressed because it is too large
+ 4090 - 4079
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 4090 - 4079
dist/preview release/babylon.module.d.ts


+ 79 - 17
src/Materials/babylon.effect.ts

@@ -82,8 +82,17 @@
         private static _uniqueIdSeed = 0;
         private _engine: Engine;
         private _uniformsNames: string[];
-        private _uniformBufferPerPass: WebGLBuffer;
-        private _uniformBufferPerScene: WebGLBuffer;
+        private _uniformBufferDynamic: WebGLBuffer;
+        private _uniformBufferStatic: WebGLBuffer;
+        private _uniformBufferDynamicCache: Float32Array;
+        private _uniformBufferStaticCache: Float32Array;
+        private _uniformBufferDynamicNames: string[] = [];
+        private _uniformBufferDynamicLocations: number[] = [];
+        private _uniformBufferStaticNames: string[] = [];
+        private _uniformBufferStaticLocations: number[] = [];
+        private _uniformCurrentStaticPointer: number = 0;
+        private _uniformCurrentDynamicPointer: number = 0;
+        private _uniformOrder: string[];
         private _samplers: string[];
         private _isReady = false;
         private _compilationError = "";
@@ -415,8 +424,8 @@
                 this.bindUniformBlock();
 
                 this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
-                this._uniformBufferPerPass = engine.createUniformBuffer(this.formatUniforms(8));
-                this._uniformBufferPerScene = engine.createUniformBuffer(this.formatUniforms(4));
+                this._uniformBufferDynamic = engine.createUniformBuffer(this.formatUniforms(8));
+                this._uniformBufferStatic = engine.createUniformBuffer(this.formatUniforms(4));
 
                 this._attributes = engine.getAttributes(this._program, attributesNames);
 
@@ -587,21 +596,42 @@
             return new Float32Array(length);
         };
 
-        public setUniformBufferScene(cameraPositionFormatted: Float32Array): Effect {
-            this._engine.setUniformBuffer(this._uniformBufferPerScene, cameraPositionFormatted);
-
-            return this;
-        }
+        public addUniform(name: string, size: number, dynamic: boolean): void {
+            var uniformNames, uniformLocations, index;
+            if (dynamic) {
+                uniformNames = this._uniformBufferDynamicNames;
+                uniformLocations = this._uniformBufferDynamicLocations;
+                index = this._uniformCurrentDynamicPointer;
+            } else {
+                uniformNames = this._uniformBufferStaticNames;
+                uniformLocations = this._uniformBufferStaticLocations;                
+                index = this._uniformCurrentStaticPointer;
+            }
+            uniformNames.push(name);
+            uniformLocations.push(index);
 
-        public setUniformBufferPass(materialFormatted: Float32Array): Effect {
-            this._engine.setUniformBuffer(this._uniformBufferPerPass, materialFormatted);
+            // std140 layout forces uniform to be multiple of 16 bytes (4 floats)
+            var correctedSize = Math.ceil(size / 4) * 4;
+            index += correctedSize;
 
-            return this;
+            if (dynamic) {
+                this._uniformBufferDynamicCache = new Float32Array(index);
+            } else {
+                this._uniformBufferStaticCache = new Float32Array(index); 
+            }
         };
 
+        public updateUniformBufferStatic(): void {
+            this._engine.setUniformBuffer(this._uniformBufferStatic, this._uniformBufferStaticCache);
+        }
+
+        public updateUniformBufferDynamic(): void {
+            this._engine.setUniformBuffer(this._uniformBufferDynamic, this._uniformBufferDynamicCache);
+        }
+
         public bindUniformBuffers(): void {
-            this._engine.bindUniformBufferBase(this._uniformBufferPerPass, 0);
-            this._engine.bindUniformBufferBase(this._uniformBufferPerScene, 1);
+            this._engine.bindUniformBufferBase(this._uniformBufferDynamic, 0);
+            this._engine.bindUniformBufferBase(this._uniformBufferStatic, 1);
         }
 
         public bindUniformBlock(): void {
@@ -760,7 +790,17 @@
 
         public setVector3(uniformName: string, vector3: Vector3): Effect {
             if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {
-                this._engine.setFloat3(this.getUniform(uniformName), vector3.x, vector3.y, vector3.z);
+                var index;
+                var location;
+                if ((index = this._uniformBufferDynamicNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferDynamicLocations[index];
+                    vector3.toArray(this._uniformBufferDynamicCache, location);
+                } else if ((index = this._uniformBufferStaticNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferStaticLocations[index];
+                    vector3.toArray(this._uniformBufferStaticCache, location);
+                } else {
+                    this._engine.setFloat3(this.getUniform(uniformName), vector3.x, vector3.y, vector3.z);
+                }
             }
             return this;
         }
@@ -788,14 +828,36 @@
 
         public setColor3(uniformName: string, color3: Color3): Effect {
             if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
-                this._engine.setColor3(this.getUniform(uniformName), color3);
+                var index;
+                var location;
+                if ((index = this._uniformBufferDynamicNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferDynamicLocations[index];
+                    color3.toArray(this._uniformBufferDynamicCache, location);
+                } else if ((index = this._uniformBufferStaticNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferStaticLocations[index];
+                    color3.toArray(this._uniformBufferStaticCache, location);
+                } else {
+                    this._engine.setColor3(this.getUniform(uniformName), color3);
+                }
             }
             return this;
         }
 
         public setColor4(uniformName: string, color3: Color3, alpha: number): Effect {
             if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
-                this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
+                var index;
+                var location;
+                if ((index = this._uniformBufferDynamicNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferDynamicLocations[index];
+                    color3.toArray(this._uniformBufferDynamicCache, location);
+                    this._uniformBufferDynamicCache[location + 3] = alpha;
+                } else if ((index = this._uniformBufferStaticNames.indexOf(uniformName)) !== -1) {
+                    location = this._uniformBufferStaticLocations[index];
+                    color3.toArray(this._uniformBufferStaticCache, location);
+                    this._uniformBufferStaticCache[location + 3] = alpha;
+                } else {
+                    this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
+                }
             }
             return this;
         }

+ 15 - 7
src/Materials/babylon.standardMaterial.ts

@@ -692,6 +692,8 @@
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
+
+                this.buildUniformLayout();
             }
             if (!this._effect.isReady()) {
                 return false;
@@ -711,6 +713,16 @@
             return true;
         }
 
+        public buildUniformLayout(): void {
+            this._effect.addUniform("vDiffuseColor", 4, false);
+            this._effect.addUniform("vAmbientColor", 3, false);
+            if (this._defines.SPECULARTERM) {
+                this._effect.addUniform("vSpecularColor", 3, false);
+            }
+
+            // Dynamic uniforms
+            this._effect.addUniform("vEyePosition", 3, true);
+        }
 
         public unbind(): void {
             if (this.reflectionTexture && this.reflectionTexture.isRenderTarget) {
@@ -875,19 +887,14 @@
                     scene.activeCamera.position.toArray(cameraPos);
                 }
 
-                this._effect.setUniformBufferScene(new Float32Array(cameraPos.concat(0.0)));
+                this._effect.updateUniformBufferDynamic();
+                this._effect.bindUniformBuffers();
             }
 
             if (scene.getCachedMaterial() !== this || !this.isFrozen) {
                 // Diffuse
                 this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
-                // ADDED
-                this._effect.setUniformBufferPass(new Float32Array([
-                    this.diffuseColor.r, this.diffuseColor.g, this.diffuseColor.b, this.alpha * mesh.visibility,
-                    this._globalAmbientColor.r, this._globalAmbientColor.g, this._globalAmbientColor.b, 0.0]));
-                this._effect.bindUniformBuffers();
-
                 // Lights
                 if (scene.lightsEnabled && !this.disableLighting) {
                     MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
@@ -908,6 +915,7 @@
                 if (this.cameraColorCurves) {
                     ColorCurves.Bind(this.cameraColorCurves, this._effect);
                 }
+                this._effect.updateUniformBufferStatic();
             }
 
             super.bind(world, mesh);

+ 1 - 1
src/Math/babylon.math.ts

@@ -88,7 +88,7 @@
          * Stores in the passed array from the passed starting index the red, green, blue values as successive elements.  
          * Returns the Color3.  
          */
-        public toArray(array: number[], index?: number): Color3 {
+        public toArray(array: number[] | Float32Array, index?: number): Color3 {
             if (index === undefined) {
                 index = 0;
             }

+ 16 - 12
src/Shaders/default.fragment.fx

@@ -8,15 +8,19 @@ struct Material
 {
   	vec4 vDiffuseColor;
   	vec3 vAmbientColor;
+  	#ifdef SPECULARTERM
+  	vec4 vSpecularColor;
+  	#endif
+  	vec3 vEmissiveColor;
 };
 
-uniform PerPass {
-	Material material;
-}  u_PerPass;
-
-uniform PerScene {
+uniform Dynamic {
 	Camera camera;
-}  u_PerScene;
+}  uDynamic;
+
+uniform Static {
+	Material material;
+}  uStatic;
 
 
 #ifdef BUMP
@@ -178,14 +182,14 @@ uniform vec4 reflectionRightColor;
 void main(void) {
 #include<clipPlaneFragment>
 
-	vec3 viewDirectionW = normalize(u_PerScene.camera.vEyePosition - vPositionW);
+	vec3 viewDirectionW = normalize(uDynamic.camera.vEyePosition - vPositionW);
 
 	// Base color
 	vec4 baseColor = vec4(1., 1., 1., 1.);
-	vec3 diffuseColor = u_PerPass.material.vDiffuseColor.rgb;
+	vec3 diffuseColor = uStatic.material.vDiffuseColor.rgb;
 
 	// Alpha
-	float alpha = u_PerPass.material.vDiffuseColor.a;
+	float alpha = uStatic.material.vDiffuseColor.a;
 
 	// Bump
 #ifdef NORMAL
@@ -375,12 +379,12 @@ void main(void) {
 
 	// Composition
 #ifdef EMISSIVEASILLUMINATION
-	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + u_PerPass.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + uStatic.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
 #else
 #ifdef LINKEMISSIVEWITHDIFFUSE
-	vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + u_PerPass.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+	vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + uStatic.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
 #else
-	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + u_PerPass.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + uStatic.material.vAmbientColor, 0.0, 1.0) * baseColor.rgb;
 #endif
 #endif
 

+ 5 - 5
src/babylon.engine.ts

@@ -1811,11 +1811,11 @@
         }
 
         public bindUniformBlock(shaderProgram: WebGLProgram): void {
-            var uniformPerPassLocation = this._gl.getUniformBlockIndex(shaderProgram, 'PerPass');
-            var uniformPerSceneLocation = this._gl.getUniformBlockIndex(shaderProgram, 'PerScene');
-            
-            this._gl.uniformBlockBinding(shaderProgram, uniformPerPassLocation, 0);
-            this._gl.uniformBlockBinding(shaderProgram, uniformPerSceneLocation, 1);
+            var uniformDynamicLocation = this._gl.getUniformBlockIndex(shaderProgram, 'Dynamic');
+            var uniformStaticLocation = this._gl.getUniformBlockIndex(shaderProgram, 'Static');
+
+            this._gl.uniformBlockBinding(shaderProgram, uniformDynamicLocation, 0);
+            this._gl.uniformBlockBinding(shaderProgram, uniformStaticLocation, 1);
 
         };