Forráskód Böngészése

uniform buffers added for lights

Benjamin Guignabert 8 éve
szülő
commit
e3489adc57

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 7323 - 7314
dist/preview release/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 7323 - 7314
dist/preview release/babylon.module.d.ts


+ 10 - 2
src/Lights/babylon.directionalLight.ts

@@ -42,6 +42,14 @@ module BABYLON {
             this.position = direction.scale(-1.0);
             this.direction = direction;
         }
+
+        protected _buildUniformLayout(): void {
+             this._uniformBuffer.addUniform("vLightData", 4);
+             this._uniformBuffer.addUniform("vLightDiffuse", 4);
+             this._uniformBuffer.addUniform("vLightSpecular", 3);
+             this._uniformBuffer.addUniform("shadowsInfo", 3);
+        }
+
         /**
          * Returns the string "DirectionalLight".  
          */
@@ -171,10 +179,10 @@ module BABYLON {
                     this._transformedDirection = Vector3.Zero();
                 }
                 Vector3.TransformNormalToRef(this.direction, this.parent.getWorldMatrix(), this._transformedDirection);
-                effect.setFloat4(directionUniformName, this._transformedDirection.x, this._transformedDirection.y, this._transformedDirection.z, 1);
+                this._uniformBuffer.updateFloat4(directionUniformName, this._transformedDirection.x, this._transformedDirection.y, this._transformedDirection.z, 1);
                 return this;
             }
-            effect.setFloat4(directionUniformName, this.direction.x, this.direction.y, this.direction.z, 1);
+            this._uniformBuffer.updateFloat4(directionUniformName, this.direction.x, this.direction.y, this.direction.z, 1);
             return this;
         }
 

+ 11 - 2
src/Lights/babylon.hemisphericLight.ts

@@ -18,6 +18,15 @@
             super(name, scene);
             this.direction = direction;
         }
+
+        protected _buildUniformLayout(): void {
+            this._uniformBuffer.addUniform("vLightData", 4);
+            this._uniformBuffer.addUniform("vLightDiffuse", 4);
+            this._uniformBuffer.addUniform("vLightSpecular", 3);
+            this._uniformBuffer.addUniform("vLightDirection", 4);
+            this._uniformBuffer.addUniform("shadowsInfo", 3);
+        }
+
         /**
          * Returns the string "HemisphericLight".  
          */
@@ -43,12 +52,12 @@
          */
         public transferToEffect(effect: Effect, directionUniformName: string, groundColorUniformName: string): HemisphericLight {
             var normalizeDirection = Vector3.Normalize(this.direction);
-            effect.setFloat4(directionUniformName,
+            this._uniformBuffer.updateFloat4(directionUniformName,
                 normalizeDirection.x,
                 normalizeDirection.y,
                 normalizeDirection.z,
                 0.0);
-            effect.setColor3(groundColorUniformName, this.groundColor.scale(this.intensity));
+            this._uniformBuffer.updateColor3(groundColorUniformName, this.groundColor.scale(this.intensity));
             return this;
         }
 

+ 10 - 0
src/Lights/babylon.light.ts

@@ -91,6 +91,9 @@
         public _excludedMeshesIds = new Array<string>();
         public _includedOnlyMeshesIds = new Array<string>();
 
+        // Light uniform buffer
+        public _uniformBuffer: UniformBuffer;
+
         /**
          * Creates a Light object in the scene.  
          * Documentation : http://doc.babylonjs.com/tutorials/lights  
@@ -98,7 +101,14 @@
         constructor(name: string, scene: Scene) {
             super(name, scene);
             this.getScene().addLight(this);
+            this._uniformBuffer = new UniformBuffer(scene.getEngine(), null, true);
+            this._buildUniformLayout();
+        }
+
+        protected _buildUniformLayout(): void {
+            // Overridden
         }
+
         /**
          * Returns the string "Light".  
          */

+ 10 - 2
src/Lights/babylon.pointLight.ts

@@ -27,6 +27,14 @@
             super(name, scene);
             this.position = position;
         }
+
+        protected _buildUniformLayout(): void {
+            this._uniformBuffer.addUniform("vLightData", 4);
+            this._uniformBuffer.addUniform("vLightDiffuse", 4);
+            this._uniformBuffer.addUniform("vLightSpecular", 3);
+            this._uniformBuffer.addUniform("shadowsInfo", 3);
+        }
+
         /**
          * Returns the string "PointLight"
          */
@@ -64,7 +72,7 @@
             if (this.parent && this.parent.getWorldMatrix) {
                 this.computeTransformedPosition();
 
-                effect.setFloat4(positionUniformName,
+                this._uniformBuffer.updateFloat4(positionUniformName,
                     this.transformedPosition.x,
                     this.transformedPosition.y,
                     this.transformedPosition.z,
@@ -72,7 +80,7 @@
                 return this;
             }
 
-            effect.setFloat4(positionUniformName, this.position.x, this.position.y, this.position.z, 0);
+            this._uniformBuffer.updateFloat4(positionUniformName, this.position.x, this.position.y, this.position.z, 0);
             return this;
         }
         /**

+ 12 - 3
src/Lights/babylon.spotLight.ts

@@ -42,6 +42,15 @@
             this.angle = angle;
             this.exponent = exponent;
         }
+
+        protected _buildUniformLayout(): void {
+            this._uniformBuffer.addUniform("vLightData", 4);
+            this._uniformBuffer.addUniform("vLightDiffuse", 4);
+            this._uniformBuffer.addUniform("vLightSpecular", 3);
+            this._uniformBuffer.addUniform("vLightGround", 3);
+            this._uniformBuffer.addUniform("shadowsInfo", 3);
+        }
+        
         /**
          * Returns the string "SpotLight".  
          */
@@ -131,7 +140,7 @@
                 
                 Vector3.TransformNormalToRef(this.direction, this.parent.getWorldMatrix(), this._transformedDirection);
 
-                effect.setFloat4(positionUniformName,
+                this._uniformBuffer.updateFloat4(positionUniformName,
                     this.transformedPosition.x,
                     this.transformedPosition.y,
                     this.transformedPosition.z,
@@ -139,7 +148,7 @@
 
                 normalizeDirection = Vector3.Normalize(this._transformedDirection);
             } else {
-                effect.setFloat4(positionUniformName,
+                this._uniformBuffer.updateFloat4(positionUniformName,
                     this.position.x,
                     this.position.y,
                     this.position.z,
@@ -148,7 +157,7 @@
                 normalizeDirection = Vector3.Normalize(this.direction);
             }
 
-            effect.setFloat4(directionUniformName,
+            this._uniformBuffer.updateFloat4(directionUniformName,
                 normalizeDirection.x,
                 normalizeDirection.y,
                 normalizeDirection.z,

+ 12 - 5
src/Materials/babylon.effect.ts

@@ -81,6 +81,7 @@
 
         private static _uniqueIdSeed = 0;
         private _engine: Engine;
+        private _uniformBuffersNames: string[];
         private _uniformsNames: string[];
         private _uniformOrder: string[];
         private _samplers: string[];
@@ -99,6 +100,9 @@
             this._engine = engine;
             this.name = baseName;
             this.defines = defines;
+            // TODO
+            this._uniformBuffersNames = ["Material", "Light0"];
+
             this._uniformsNames = uniformsNames.concat(samplers);
             this._samplers = samplers;
             this._attributesNames = attributesNames;
@@ -411,7 +415,10 @@
                 var engine = this._engine;
 
                 this._program = engine.createShaderProgram(vertexSourceCode, fragmentSourceCode, defines);
-                this.bindUniformBlock();
+
+                for (var i = 0; i < this._uniformBuffersNames.length; i++) {
+                    this.bindUniformBlock(this._uniformBuffersNames[i], i);
+                }
 
                 this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
 
@@ -579,12 +586,12 @@
             return changed;
         }
 
-        public bindUniformBuffer(buffer: WebGLBuffer): void {
-            this._engine.bindUniformBufferBase(buffer, 0);
+        public bindUniformBuffer(buffer: WebGLBuffer, name: string): void {
+            this._engine.bindUniformBufferBase(buffer, this._uniformBuffersNames.indexOf(name));
         }
 
-        public bindUniformBlock(): void {
-            this._engine.bindUniformBlock(this._program);
+        public bindUniformBlock(blockName: string, index: number): void {
+            this._engine.bindUniformBlock(this._program, blockName, index);
         }
 
         public setIntArray(uniformName: string, array: Int32Array): Effect {

+ 9 - 8
src/Materials/babylon.materialHelper.ts

@@ -224,7 +224,7 @@
                     }
                 }
                 effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.depthScale);
+                light._uniformBuffer.updateFloat3("shadowsInfo", shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.depthScale);
             }
 
             return depthValuesAlreadySet;
@@ -233,16 +233,16 @@
         public static BindLightProperties(light: Light, effect: Effect, lightIndex: number): void {
             if (light instanceof PointLight) {
                 // Point Light
-                light.transferToEffect(effect, "vLightData" + lightIndex);
+                light.transferToEffect(effect, "vLightData");
             } else if (light instanceof DirectionalLight) {
                 // Directional Light
-                light.transferToEffect(effect, "vLightData" + lightIndex);
+                light.transferToEffect(effect, "vLightData");
             } else if (light instanceof SpotLight) {
                 // Spot Light
-                light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
+                light.transferToEffect(effect, "vLightData", "vLightDirection");
             } else if (light instanceof HemisphericLight) {
                 // Hemispheric Light
-                light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
+                light.transferToEffect(effect, "vLightData", "vLightGround");
             }
         }
 
@@ -263,17 +263,18 @@
                 MaterialHelper.BindLightProperties(light, effect, lightIndex);
 
                 light.diffuse.scaleToRef(light.intensity, Tmp.Color3[0]);
-                effect.setColor4("vLightDiffuse" + lightIndex, Tmp.Color3[0], light.range);
+                light._uniformBuffer.updateColor4("vLightDiffuse", Tmp.Color3[0], light.range);
                 if (defines["SPECULARTERM"]) {
                     light.specular.scaleToRef(light.intensity, Tmp.Color3[1]);
-                    effect.setColor3("vLightSpecular" + lightIndex, Tmp.Color3[1]);
+                    light._uniformBuffer.updateColor3("vLightSpecular", Tmp.Color3[1]);
                 }
 
                 // Shadows
                 if (scene.shadowsEnabled) {
                     depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
                 }
-
+                light._uniformBuffer.update();
+                effect.bindUniformBuffer(light._uniformBuffer.getBuffer(), "Light" + lightIndex);
                 lightIndex++;
 
                 if (lightIndex === maxSimultaneousLights)

+ 2 - 1
src/Materials/babylon.standardMaterial.ts

@@ -888,10 +888,11 @@ module BABYLON {
                 // Diffuse
                 this._uniformBuffer.updateColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             }
+            
             this._uniformBuffer.update();
             
             if (scene.getCachedMaterial() !== this) {
-                this._effect.bindUniformBuffer(this._uniformBuffer.getBuffer());
+                this._effect.bindUniformBuffer(this._uniformBuffer.getBuffer(), "Material");
 
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 

+ 9 - 4
src/Materials/babylon.uniformBuffer.ts

@@ -4,6 +4,7 @@ module BABYLON {
         private _buffer: WebGLBuffer;
         private _data: number[];
         private _dynamic: boolean;
+        private _uniformName: string;
         private _uniformNames: string[];
         private _uniformLocations: number[];
         private _uniformSizes: number[];
@@ -72,7 +73,6 @@ module BABYLON {
                 return;
             }
             // This function must be called in the order of the shader layout !
-
             // size can be the size of the uniform, or data directly
             var data;
             if (size instanceof Array) {
@@ -103,14 +103,19 @@ module BABYLON {
             this._needSync = true;
         }
 
+        public addMatrix(name: string, mat: Matrix) {
+            this.addUniform(name, Array.prototype.slice.call(mat.toArray()));
+        }
+
         public addFloat2(name: string, x: number, y: number) {
             var temp = [x, y];
             this.addUniform(name, temp);
         }
-        public addMatrix(name: string, mat: Matrix) {
-            this.addUniform(name, Array.prototype.slice.call(mat.toArray()));
-        }
 
+        public addFloat3(name: string, x: number, y: number, z: number) {
+            var temp = [x, y, z];
+            this.addUniform(name, temp);
+        }
 
         public addColor3(name: string, color: Color3) {
             var temp = [];

+ 9 - 12
src/Shaders/ShadersInclude/lightFragment.fx

@@ -2,38 +2,35 @@
     #if defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})
         //No light calculation
     #else
-        #ifndef SPECULARTERM
-            vec3 vLightSpecular{X} = vec3(0.);
-        #endif
         #ifdef SPOTLIGHT{X}
-            info = computeSpotLighting(viewDirectionW, normalW, vLightData{X}, vLightDirection{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
+            info = computeSpotLighting(viewDirectionW, normalW, light{X}.vLightData, light{X}.vLightDirection, light{X}.vLightDiffuse.rgb, light{X}.vLightSpecular, light{X}.vLightDiffuse.a, glossiness);
         #endif
         #ifdef HEMILIGHT{X}
-            info = computeHemisphericLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightGround{X}, glossiness);
+            info = computeHemisphericLighting(viewDirectionW, normalW, light{X}.vLightData, light{X}.vLightDiffuse.rgb, light{X}.vLightSpecular, light{X}.vLightGround, glossiness);
         #endif
         #if defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})
-            info = computeLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
+            info = computeLighting(viewDirectionW, normalW, light{X}.vLightData, light{X}.vLightDiffuse.rgb, light{X}.vLightSpecular, light{X}.vLightDiffuse.a, glossiness);
         #endif
     #endif
 	#ifdef SHADOW{X}
 		#ifdef SHADOWESM{X}
 			#if defined(POINTLIGHT{X})
-				shadow = computeShadowWithESMCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.x, shadowsInfo{X}.z);
+				shadow = computeShadowWithESMCube(light{X}.vLightData.xyz, shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.z);
 			#else
-				shadow = computeShadowWithESM(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.x, shadowsInfo{X}.z);
+				shadow = computeShadowWithESM(vPositionFromLight{X}, shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.z);
 			#endif
 		#else	
 			#ifdef SHADOWPCF{X}
 				#if defined(POINTLIGHT{X})
-					shadow = computeShadowWithPCFCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.x);
+					shadow = computeShadowWithPCFCube(light{X}.vLightData.xyz, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.x);
 				#else
-					shadow = computeShadowWithPCF(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.x);
+					shadow = computeShadowWithPCF(vPositionFromLight{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.x);
 				#endif
 			#else
 				#if defined(POINTLIGHT{X})
-					shadow = computeShadowCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.x);
+					shadow = computeShadowCube(light{X}.vLightData.xyz, shadowSampler{X}, light{X}.shadowsInfo.x);
 				#else
-					shadow = computeShadow(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.x);
+					shadow = computeShadow(vPositionFromLight{X}, shadowSampler{X}, light{X}.shadowsInfo.x);
 				#endif
 			#endif
 		#endif

+ 21 - 18
src/Shaders/ShadersInclude/lightFragmentDeclaration.fx

@@ -1,22 +1,25 @@
 #ifdef LIGHT{X}
-	uniform vec4 vLightData{X};
-	uniform vec4 vLightDiffuse{X};
-	#ifdef SPECULARTERM
-		uniform vec3 vLightSpecular{X};
-	#endif
-	#ifdef SHADOW{X}
-		#if defined(SPOTLIGHT{X}) || defined(DIRLIGHT{X})
-			varying vec4 vPositionFromLight{X};
-			uniform sampler2D shadowSampler{X};
-		#else
-			uniform samplerCube shadowSampler{X};
+	uniform Light{X}
+	{
+		vec4 vLightData;
+		vec4 vLightDiffuse;
+		vec3 vLightSpecular;
+		#ifdef SPOTLIGHT{X}
+			vec4 vLightDirection;
 		#endif
-		uniform vec3 shadowsInfo{X};
-	#endif
-	#ifdef SPOTLIGHT{X}
-		uniform vec4 vLightDirection{X};
-	#endif
-	#ifdef HEMILIGHT{X}
-		uniform vec3 vLightGround{X};
+		#ifdef HEMILIGHT{X}
+			vec3 vLightGround;
+		#endif
+		vec3 shadowsInfo;
+	} light{X};
+
+#ifdef SHADOW{X}
+	#if defined(SPOTLIGHT{X}) || defined(DIRLIGHT{X})
+		varying vec4 vPositionFromLight{X};
+		uniform sampler2D shadowSampler{X};
+	#else
+		uniform samplerCube shadowSampler{X};
 	#endif
+#endif
+
 #endif

+ 1 - 0
src/Shaders/default.fragment.fx

@@ -1,4 +1,5 @@
 layout(std140, column_major) uniform;
+
 uniform Material
 {
 	

+ 3 - 3
src/babylon.engine.ts

@@ -1859,10 +1859,10 @@
             return results;
         }
 
-        public bindUniformBlock(shaderProgram: WebGLProgram): void {
-            var uniformLocation = this._gl.getUniformBlockIndex(shaderProgram, 'Material');
+        public bindUniformBlock(shaderProgram: WebGLProgram, blockName: string, index: number): void {
+            var uniformLocation = this._gl.getUniformBlockIndex(shaderProgram, blockName);
 
-            this._gl.uniformBlockBinding(shaderProgram, uniformLocation, 0);
+            this._gl.uniformBlockBinding(shaderProgram, uniformLocation, index);
         };
 
         public getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[] {