Browse Source

improved PBR

David catuhe 9 years ago
parent
commit
7e7213dd89

File diff suppressed because it is too large
+ 102 - 94
materialsLibrary/dist/babylon.pbrMaterial.js


File diff suppressed because it is too large
+ 3 - 3
materialsLibrary/dist/babylon.pbrMaterial.min.js


+ 116 - 114
materialsLibrary/materials/pbr/babylon.pbrMaterial.ts

@@ -52,9 +52,7 @@ module BABYLON {
         public SHADOWPCF1 = false;
         public SHADOWPCF2 = false;
         public SHADOWPCF3 = false;
-        public DIFFUSEFRESNEL = false;
         public OPACITYFRESNEL = false;
-        public REFLECTIONFRESNEL = false;
         public EMISSIVEFRESNEL = false;
         public FRESNEL = false;
         public NORMAL = false;
@@ -62,15 +60,12 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
-        public GLOSSINESS = false;
-        public ROUGHNESS = false;
+        public GLOSSINESSFROMSPECULARMAP = false;
         public EMISSIVEASILLUMINATION = false;
         public LINKEMISSIVEWITHDIFFUSE = false;
-        public REFLECTIONFRESNELFROMSPECULAR = false;
         public LIGHTMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public REFLECTIONMAP_3D = false;
@@ -82,6 +77,10 @@ module BABYLON {
         public REFLECTIONMAP_EXPLICIT = false;
         public REFLECTIONMAP_EQUIRECTANGULAR = false;
         public INVERTCUBICMAP = false;
+        public LOGARITHMICDEPTH = false;
+        public CAMERATONEMAP = false;
+        public CAMERACONTRAST = false;
+        public OVERLOADEDVALUES = false;
 
         constructor() {
             super();
@@ -94,7 +93,7 @@ module BABYLON {
         public directIntensity: number = 1.0;
         public emissiveIntensity: number = 1.0;
         public environmentIntensity: number = 1.0;
-        public _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, 0.0);
+        private _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, 0.0);
 
         public shadowIntensity: number = 1.0;
         public shadeIntensity: number = 1.0;
@@ -132,22 +131,18 @@ module BABYLON {
         public ambientColor = new Color3(0, 0, 0);
         public diffuseColor = new Color3(1, 1, 1);
         public specularColor = new Color3(1, 1, 1);
-        public specularPower = 64;
+        public reflectionColor = new Color3(0.5, 0.5, 0.5);
+        public glossiness = 0.5;
         public emissiveColor = new Color3(0, 0, 0);
         public useAlphaFromDiffuseTexture = false;
         public useEmissiveAsIllumination = false;
         public linkEmissiveWithDiffuse = false;
-        public useReflectionFresnelFromSpecular = false;
         public useSpecularOverAlpha = true;
         public disableLighting = false;
 
-        public roughness = 0;
-
         public useLightmapAsShadowmap = false;
-
-        public diffuseFresnelParameters: FresnelParameters;
+        
         public opacityFresnelParameters: FresnelParameters;
-        public reflectionFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
 
         public useGlossinessFromSpecularMapAlpha = false;
@@ -162,6 +157,8 @@ module BABYLON {
         private _defines = new PBRMaterialDefines();
         private _cachedDefines = new PBRMaterialDefines();
 
+        private _useLogarithmicDepth: boolean;
+
         constructor(name: string, scene: Scene) {
             super(name, scene);
 
@@ -178,6 +175,14 @@ module BABYLON {
             }
         }
 
+        public get useLogarithmicDepth(): boolean {
+            return this._useLogarithmicDepth;
+        }
+
+        public set useLogarithmicDepth(value: boolean) {
+            this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+        }
+
         public needAlphaBlending(): boolean {
             return (this.alpha < 1.0) || (this.opacityTexture != null) || this._shouldUseAlphaFromDiffuseTexture() || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled;
         }
@@ -299,6 +304,7 @@ module BABYLON {
         private static _scaledDiffuse = new Color3();
         private static _scaledSpecular = new Color3();
         private static _scaledEmissive = new Color3();
+        private static _scaledReflection = new Color3();
 
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
@@ -367,7 +373,7 @@ module BABYLON {
             }
 
             var scene = this.getScene();
-            
+
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                     if (this._checkCache(scene, mesh, useInstances)) {
@@ -422,10 +428,6 @@ module BABYLON {
                         needNormals = true;
                         this._defines.REFLECTION = true;
 
-                        if (this.roughness > 0) {
-                            this._defines.ROUGHNESS = true;
-                        }
-
                         if (this.reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
                             this._defines.INVERTCUBICMAP = true;
                         }
@@ -484,7 +486,7 @@ module BABYLON {
                     } else {
                         needUVs = true;
                         this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
+                        this._defines.GLOSSINESSFROMSPECULARMAP = this.useGlossinessFromSpecularMapAlpha;
                     }
                 }
             }
@@ -519,8 +521,24 @@ module BABYLON {
                 this._defines.LINKEMISSIVEWITHDIFFUSE = true;
             }
 
-            if (this.useReflectionFresnelFromSpecular) {
-                this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
+            if (this.useLogarithmicDepth) {
+                this._defines.LOGARITHMICDEPTH = true;
+            }
+
+            if (this.cameraContrast != 1) {
+                this._defines.CAMERACONTRAST = true;
+            }
+
+            if (this.cameraExposure != 1) {
+                this._defines.CAMERATONEMAP = true;
+            }
+
+            if (this.overloadedSmoothnessIntensity > 0 ||
+                this.overloadedEmissiveIntensity > 0 ||
+                this.overloadedSpecularIntensity > 0 ||
+                this.overloadedDiffuseIntensity > 0 ||
+                this.overloadedAmbientIntensity > 0) {
+                this._defines.OVERLOADEDVALUES = true;
             }
 
             // Point size
@@ -539,23 +557,13 @@ module BABYLON {
 
             if (StandardMaterial.FresnelEnabled) {
                 // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled ||
-                    this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
-                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled ||
-                    this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._defines.DIFFUSEFRESNEL = true;
-                    }
+                if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
+                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
 
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                         this._defines.OPACITYFRESNEL = true;
                     }
 
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._defines.REFLECTIONFRESNEL = true;
-                    }
-
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                         this._defines.EMISSIVEFRESNEL = true;
                     }
@@ -590,9 +598,8 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -601,7 +608,7 @@ module BABYLON {
                 }
             }
 
-            // Get correct effect      
+            // Get correct effect
             if (!this._defines.isEqual(this._cachedDefines)) {
                 this._defines.cloneTo(this._cachedDefines);
 
@@ -629,6 +636,14 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
+                if (this._defines.POINTSIZE) {
+                    fallbacks.addFallback(0, "POINTSIZE");
+                }
+
+                if (this._defines.LOGARITHMICDEPTH) {
+                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
+                }
+
                 for (let lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
                     if (!this._defines["LIGHT" + lightIndex]) {
                         continue;
@@ -655,28 +670,20 @@ module BABYLON {
                     fallbacks.addFallback(0, "SPECULARTERM");
                 }
 
-                if (this._defines.DIFFUSEFRESNEL) {
-                    fallbacks.addFallback(1, "DIFFUSEFRESNEL");
-                }
-
                 if (this._defines.OPACITYFRESNEL) {
-                    fallbacks.addFallback(2, "OPACITYFRESNEL");
-                }
-
-                if (this._defines.REFLECTIONFRESNEL) {
-                    fallbacks.addFallback(3, "REFLECTIONFRESNEL");
+                    fallbacks.addFallback(1, "OPACITYFRESNEL");
                 }
 
                 if (this._defines.EMISSIVEFRESNEL) {
-                    fallbacks.addFallback(4, "EMISSIVEFRESNEL");
+                    fallbacks.addFallback(2, "EMISSIVEFRESNEL");
                 }
 
                 if (this._defines.FRESNEL) {
-                    fallbacks.addFallback(4, "FRESNEL");
+                    fallbacks.addFallback(3, "FRESNEL");
                 }
 
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -698,9 +705,13 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
 
                 if (this._defines.INSTANCES) {
@@ -718,7 +729,7 @@ module BABYLON {
                 var join = this._defines.toString();
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
+                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor", "vReflectionColor",
                         "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -728,9 +739,9 @@ module BABYLON {
                         "mBones",
                         "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
                         "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
-                        "roughness",
-                        "vPBRLightingIntensity", "vPBRShadowIntensity", "vPBROverloadedIntensity", "vPBRCameraInfos", "vPBROverloadedDiffuse", "vPBROverloadedSpecular", "vPBROverloadedEmissive", "vPBROverloadedSmoothness"
+                        "opacityParts", "emissiveLeftColor", "emissiveRightColor",
+                        "vLightingIntensity", "vShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedDiffuse", "vOverloadedSpecular", "vOverloadedEmissive", "vOverloadedSmoothness",
+                        "logarithmicDepthConstant"
                     ],
                     ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -786,21 +797,10 @@ module BABYLON {
             if (this._myScene.getCachedMaterial() !== (<BABYLON.Material>this)) {
 
                 if (StandardMaterial.FresnelEnabled) {
-                    // Fresnel
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
-                        this._effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
-                    }
-
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                         this._effect.setColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
                     }
 
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
-                        this._effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
-                    }
-
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                         this._effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
                         this._effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
@@ -837,7 +837,7 @@ module BABYLON {
                     }
 
                     this._effect.setMatrix("reflectionMatrix", this.reflectionTexture.getReflectionTextureMatrix());
-                    this._effect.setFloat2("vReflectionInfos", this.reflectionTexture.level, this.roughness);
+                    this._effect.setFloat2("vReflectionInfos", this.reflectionTexture.level, 0);
                 }
 
                 if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
@@ -891,12 +891,16 @@ module BABYLON {
                 this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
 
                 if (this._defines.SPECULARTERM) {
-                    this._effect.setColor4("vSpecularColor", PBRMaterial._scaledSpecular, this.specularPower);
+                    this._effect.setColor4("vSpecularColor", PBRMaterial._scaledSpecular, this.glossiness);
                 }
 
                 // GAMMA CORRECTION.
                 this.emissiveColor.toLinearSpaceToRef(PBRMaterial._scaledEmissive); 
                 this._effect.setColor3("vEmissiveColor", PBRMaterial._scaledEmissive);
+
+                // GAMMA CORRECTION.
+                this.reflectionColor.toLinearSpaceToRef(PBRMaterial._scaledReflection);
+                this._effect.setColor3("vReflectionColor", PBRMaterial._scaledReflection);
             }
 
             // GAMMA CORRECTION.
@@ -918,39 +922,43 @@ module BABYLON {
                 this._effect.setFloat4("vFogInfos", this._myScene.fogMode, this._myScene.fogStart, this._myScene.fogEnd, this._myScene.fogDensity);
                 this._effect.setColor3("vFogColor", this._myScene.fogColor);
             }
-            
 
             this._lightingInfos.x = this.directIntensity;
             this._lightingInfos.y = this.emissiveIntensity;
             this._lightingInfos.z = this.environmentIntensity;
-            this._effect.setVector4("vPBRLightingIntensity", this._lightingInfos);
+            this._effect.setVector4("vLightingIntensity", this._lightingInfos);
 
             this._shadowInfos.x = this.shadowIntensity;
             this._shadowInfos.y = this.shadeIntensity;
-            this._effect.setVector4("vPBRShadowIntensity", this._shadowInfos);
+            this._effect.setVector4("vShadowIntensity", this._shadowInfos);
 
             this._cameraInfos.x = this.cameraExposure;
             this._cameraInfos.y = this.cameraContrast;
-            this._effect.setVector4("vPBRCameraInfos", this._cameraInfos);
+            this._effect.setVector4("vCameraInfos", this._cameraInfos);
 
             this._overloadedIntensity.x = this.overloadedAmbientIntensity;
             this._overloadedIntensity.y = this.overloadedDiffuseIntensity;
             this._overloadedIntensity.z = this.overloadedSpecularIntensity;
             this._overloadedIntensity.w = this.overloadedEmissiveIntensity;
-            this._effect.setVector4("vPBROverloadedIntensity", this._overloadedIntensity);
+            this._effect.setVector4("vOverloadedIntensity", this._overloadedIntensity);
 
             this.overloadedAmbient.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedAmbient", this._tempColor);
+            this._effect.setColor3("vOverloadedAmbient", this._tempColor);
             this.overloadedDiffuse.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedDiffuse", this._tempColor);
+            this._effect.setColor3("vOverloadedDiffuse", this._tempColor);
             this.overloadedSpecular.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedSpecular", this._tempColor);
+            this._effect.setColor3("vOverloadedSpecular", this._tempColor);
             this.overloadedEmissive.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedEmissive", this._tempColor);
+            this._effect.setColor3("vOverloadedEmissive", this._tempColor);
 
             this._overloadedSmoothness.x = this.overloadedSmoothness;
             this._overloadedSmoothness.y = this.overloadedSmoothnessIntensity;
-            this._effect.setVector3("vPBROverloadedSmoothness", this._overloadedSmoothness);
+            this._effect.setVector3("vOverloadedSmoothness", this._overloadedSmoothness);
+
+            // Log. depth
+            if (this._defines.LOGARITHMICDEPTH) {
+                this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(this._myScene.activeCamera.maxZ + 1.0) / Math.LN2));
+            }
 
             super.bind(world, mesh);
 
@@ -1029,7 +1037,31 @@ module BABYLON {
             // Base material
             this.copyTo(newPBRMaterial);
 
-            // PBR material
+            newPBRMaterial.directIntensity = this.directIntensity;
+            newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
+            newPBRMaterial.environmentIntensity = this.environmentIntensity;
+        
+            newPBRMaterial.shadowIntensity = this.shadowIntensity;
+            newPBRMaterial.shadeIntensity = this.shadeIntensity;
+        
+            newPBRMaterial.cameraExposure = this.cameraExposure;
+            newPBRMaterial.cameraContrast = this.cameraContrast;
+        
+            newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
+            newPBRMaterial.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
+            newPBRMaterial.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
+            newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
+            newPBRMaterial.overloadedAmbient = this.overloadedAmbient;
+            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse;
+            newPBRMaterial.overloadedSpecular = this.overloadedSpecular;
+            newPBRMaterial.overloadedEmissive = this.overloadedEmissive;
+
+            newPBRMaterial.overloadedSmoothness = this.overloadedSmoothness;
+            newPBRMaterial.overloadedSmoothnessIntensity = this.overloadedSmoothnessIntensity;
+        
+            newPBRMaterial.disableBumpMap = this.disableBumpMap;
+
+            // Standard material
             if (this.diffuseTexture && this.diffuseTexture.clone) {
                 newPBRMaterial.diffuseTexture = this.diffuseTexture.clone();
             }
@@ -1059,48 +1091,18 @@ module BABYLON {
             newPBRMaterial.ambientColor = this.ambientColor.clone();
             newPBRMaterial.diffuseColor = this.diffuseColor.clone();
             newPBRMaterial.specularColor = this.specularColor.clone();
-            newPBRMaterial.specularPower = this.specularPower;
+            newPBRMaterial.reflectionColor = this.reflectionColor.clone();
+            newPBRMaterial.glossiness = this.glossiness;
             newPBRMaterial.emissiveColor = this.emissiveColor.clone();
             newPBRMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
             newPBRMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
             newPBRMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
-            newPBRMaterial.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
-            newPBRMaterial.roughness = this.roughness;
-
-            newPBRMaterial.diffuseFresnelParameters = this.diffuseFresnelParameters.clone();
+            
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
-            newPBRMaterial.reflectionFresnelParameters = this.reflectionFresnelParameters.clone();
             newPBRMaterial.opacityFresnelParameters = this.opacityFresnelParameters.clone();
-            
-            newPBRMaterial.directIntensity = this.directIntensity;
-            newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
-            newPBRMaterial.environmentIntensity = this.environmentIntensity;
-    
-            newPBRMaterial.shadowIntensity = this.shadowIntensity;
-            newPBRMaterial.shadeIntensity = this.shadeIntensity;
-    
-            newPBRMaterial.cameraExposure = this.cameraExposure;
-            newPBRMaterial.cameraContrast = this.cameraContrast;
-    
-            newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
-            newPBRMaterial.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
-            newPBRMaterial.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
-            newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
-            newPBRMaterial.overloadedAmbient = this.overloadedAmbient.clone();
-            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse.clone();
-            newPBRMaterial.overloadedSpecular = this.overloadedSpecular.clone();
-            newPBRMaterial.overloadedEmissive = this.overloadedEmissive.clone();
-    
-            newPBRMaterial.overloadedSmoothness = this.overloadedSmoothness;
-            newPBRMaterial.overloadedSmoothnessIntensity = this.overloadedSmoothnessIntensity;
-        
-            newPBRMaterial.disableBumpMap = this.disableBumpMap;
 
             return newPBRMaterial;
         }
     }
-} 
-
-
-/* jshint ignore:end */
+} 

+ 137 - 65
materialsLibrary/materials/pbr/legacypbr.fragment.fx

@@ -7,20 +7,24 @@ uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
 uniform vec4 vDiffuseColor;
 
-// PBR CUSTOM CONTROLS
-uniform vec4 vPBRLightingIntensity;
-uniform vec4 vPBRShadowIntensity;
-uniform vec4 vPBRCameraInfos;
-
-uniform vec4 vPBROverloadedIntensity;
-uniform vec3 vPBROverloadedAmbient;
-uniform vec3 vPBROverloadedDiffuse;
-uniform vec3 vPBROverloadedSpecular;
-uniform vec3 vPBROverloadedEmissive;
-uniform vec3 vPBROverloadedSmoothness;
+// CUSTOM CONTROLS
+uniform vec4 vLightingIntensity;
+uniform vec4 vShadowIntensity;
+uniform vec3 vReflectionColor;
+uniform vec4 vCameraInfos;
+
+#ifdef OVERLOADEDVALUES
+uniform vec4 vOverloadedIntensity;
+uniform vec3 vOverloadedAmbient;
+uniform vec3 vOverloadedDiffuse;
+uniform vec3 vOverloadedSpecular;
+uniform vec3 vOverloadedEmissive;
+uniform vec3 vOverloadedSmoothness;
+#endif
 
 // PBR CUSTOM CONSTANTS
 const float kPi = 3.1415926535897932384626433832795;
+#define FRESNEL_MAXIMUM_ON_ROUGH 0.25;
 
 // PBR HELPER METHODS
 float Square(float value)
@@ -70,6 +74,13 @@ vec3 fresnelSchlickGGX(float VdotH, vec3 reflectance0, vec3 reflectance90)
     return reflectance0 + (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotH, 0., 1.), 5.0);
 }
 
+vec3 FresnelSchlickEnvironmentGGX(float VdotN, vec3 reflectance0, vec3 reflectance90, float smoothness)
+{
+    // Schlick fresnel approximation, extended with basic smoothness term so that rough surfaces do not approach reflectance90 at grazing angle
+    float weight = mix(FRESNEL_MAXIMUM_ON_ROUGH, 1.0, smoothness);
+    return reflectance0 + weight * (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotN, 0., 1.), 5.0);
+}
+
 // Cook Torance Specular computation.
 vec3 computeSpecularTerm(float NdotH, float NdotL, float NdotV, float VdotH, float roughness, vec3 specularColor)
 {
@@ -121,38 +132,42 @@ vec3 toGammaSpace(vec3 color)
     return vec3(pow(color.r, 1.0 / 2.2), pow(color.g, 1.0 / 2.2), pow(color.b, 1.0 / 2.2));
 }
 
-vec3 toneMaps(vec3 color)
-{
-    color = max(color, 0.0);
-
-    // TONE MAPPING / EXPOSURE
-    color.rgb = color.rgb * vPBRCameraInfos.x;
-
-    float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
-    vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
-    color.rgb = mix(color.rgb, tonemapped, 1.0);
-    return color;
-}
+#ifdef CAMERATONEMAP
+    vec3 toneMaps(vec3 color)
+    {
+        color = max(color, 0.0);
 
-vec4 contrasts(vec4 color)
-{
-    color = clamp(color, 0.0, 1.0);
+        // TONE MAPPING / EXPOSURE
+        color.rgb = color.rgb * vCameraInfos.x;
 
-    vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
-    float contrast = vPBRCameraInfos.y;
-    if (contrast < 1.0)
-    {
-        // Decrease contrast: interpolate towards zero-contrast image (flat grey)
-        color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
+        vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
+        color.rgb = mix(color.rgb, tonemapped, 1.0);
+        return color;
     }
-    else
+#endif
+
+#ifdef CAMERACONTRAST
+    vec4 contrasts(vec4 color)
     {
-        // Increase contrast: apply simple shoulder-toe high contrast curve
-        color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        color = clamp(color, 0.0, 1.0);
+
+        vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
+        float contrast = vCameraInfos.y;
+        if (contrast < 1.0)
+        {
+            // Decrease contrast: interpolate towards zero-contrast image (flat grey)
+            color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        }
+        else
+        {
+            // Increase contrast: apply simple shoulder-toe high contrast curve
+            color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        }
+
+        return color;
     }
-
-    return color;
-}
+#endif
 // END PBR HELPER METHODS
 
 #ifdef SPECULARTERM
@@ -448,7 +463,9 @@ void main(void) {
     baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
-    baseColor.rgb = mix(baseColor.rgb, vPBROverloadedDiffuse, vPBROverloadedIntensity.y);
+#ifdef OVERLOADEDVALUES
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+#endif
 
 #ifdef VERTEXCOLOR
     baseColor.rgb *= vColor.rgb;
@@ -466,7 +483,9 @@ void main(void) {
 
 #ifdef AMBIENT
     baseAmbientColor = texture2D(ambientSampler, vAmbientUV).rgb * vAmbientInfos.y;
-    baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vPBROverloadedAmbient, vPBROverloadedIntensity.x);
+    #ifdef OVERLOADEDVALUES
+        baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vOverloadedAmbient, vOverloadedIntensity.x);
+    #endif
 #endif
 
     // Specular map
@@ -474,24 +493,41 @@ void main(void) {
     float glossiness = vSpecularColor.a;
     vec3 specularColor = vSpecularColor.rgb;
 
-#ifdef SPECULAR
-    vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
-    specularColor *= toLinearSpace(specularMapColor.rgb);
-#ifdef GLOSSINESS
-    glossiness = specularMapColor.a;
-#endif
-#endif
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
-    glossiness = computeDefaultGlossiness(glossiness, specularColor);
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
-    #else
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
+
+    #ifdef SPECULAR
+            vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
+            specularColor = toLinearSpace(specularMapColor.rgb);
+
+        #ifdef OVERLOADEDVALUES
+                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        #endif
+
+        #ifdef GLOSSINESSFROMSPECULARMAP
+                glossiness = specularMapColor.a;
+        #else
+                glossiness = computeDefaultGlossiness(glossiness, specularColor);
+        #endif
+    #endif
+
+    #ifdef OVERLOADEDVALUES
+            glossiness = mix(glossiness, vOverloadedSmoothness.x, vOverloadedSmoothness.y);
+    #endif
+#else
     float glossiness = 0.;
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+            glossiness = mix(glossiness, vOverloadedSmoothness.x, vOverloadedSmoothness.y);
+    #endif
+
     vec3 specularColor = vec3(0., 0., 0);
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    #ifdef OVERLOADEDVALUES
+            specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 #endif
 
-    // Apply Energy Conservation.
+    // Apply Energy Conservation taking in account the environment level only if the environment is present.
     float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
@@ -506,7 +542,10 @@ void main(void) {
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
-    vec3 shadowedOnly = vPBROverloadedDiffuse;
+#ifdef OVERLOADEDVALUES
+    vec3 shadowedOnly = vOverloadedDiffuse;
+#endif
+
 #ifdef SPECULARTERM
     vec3 specularBase = vec3(0., 0., 0.);
 #endif
@@ -528,7 +567,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -551,7 +592,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -574,7 +617,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -597,15 +642,27 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
 #endif
 #endif
 
-    // Reflection
-    vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vReflectionColor.rgb;
+vec3 ambientReflectionColor = vReflectionColor.rgb;
+
+reflectionColor *= vLightingIntensity.z;
+ambientReflectionColor *= vLightingIntensity.z;
+
+// Compute reflection specular fresnel
+vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
+vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
+reflectionColor *= specularEnvironmentReflectanceViewer;
 
 #ifdef OPACITY
     vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
@@ -628,7 +685,9 @@ void main(void) {
 #ifdef EMISSIVE
     vec3 emissiveColorTex = texture2D(emissiveSampler, vEmissiveUV).rgb;
     emissiveColor = toLinearSpace(emissiveColorTex.rgb) * emissiveColor * vEmissiveInfos.y;
-    emissiveColor = mix(emissiveColor, vPBROverloadedEmissive, vPBROverloadedIntensity.w);
+    #ifdef OVERLOADEDVALUES
+        emissiveColor = mix(emissiveColor, vOverloadedEmissive, vOverloadedIntensity.w);
+    #endif
 #endif
 
     // Composition
@@ -636,12 +695,16 @@ void main(void) {
     vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
 #else
     #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+            vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
     #else
-        vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+            vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
 #endif
 
+// diffuse lighting from environment 0.2 replaces Harmonic...
+// Ambient Reflection already includes the environment intensity.
+finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
+
 #ifdef SPECULARTERM
     vec3 finalSpecular = specularBase * specularColor;
 #else
@@ -652,20 +715,29 @@ void main(void) {
     alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif
 
-    // Composition
+// Composition
+// Reflection already includes the environment intensity.
 #ifdef EMISSIVEASILLUMINATION
-    vec4 color = vec4(finalDiffuse * baseAmbientColor * vPBRLightingIntensity.x + finalSpecular * vPBRLightingIntensity.x + reflectionColor * vPBRLightingIntensity.z + emissiveColor * vPBRLightingIntensity.y, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor + emissiveColor * vLightingIntensity.y, alpha);
 #else
-    vec4 color = vec4(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor, alpha);
 #endif
 
     color = max(color, 0.0);
 
+#ifdef CAMERATONEMAP
     color.rgb = toneMaps(color.rgb);
+#endif
+
     color.rgb = toGammaSpace(color.rgb);
+
+#ifdef CAMERACONTRAST
     color = contrasts(color);
+#endif
 
-    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vPBRShadowIntensity.y));
+#ifdef OVERLOADEDVALUES
+    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vShadowIntensity.y));
+#endif
 
     gl_FragColor = color;
-}
+}

+ 37 - 20
materialsLibrary/materials/pbr/legacypbr.vertex.fx

@@ -12,9 +12,16 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
+
+#if NUM_BONE_INFLUENCERS > 0
+uniform mat4 mBones[BonesPerMesh];
+
 attribute vec4 matricesIndices;
 attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniforms
@@ -52,10 +59,6 @@ uniform vec2 vSpecularInfos;
 uniform mat4 specularMatrix;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 // Output
 varying vec3 vPositionW;
 varying vec3 vNormalW;
@@ -70,22 +73,36 @@ varying float fClipDistance;
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = world * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = world * (m0 + m1 + m2);
-#endif 
+    mat4 finalWorld = world;
 
-#else
-	finalWorld = world;
+#if NUM_BONE_INFLUENCERS > 0
+    mat4 influence;
+    influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+#if NUM_BONE_INFLUENCERS > 1
+    influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+#endif 
+#if NUM_BONE_INFLUENCERS > 2
+    influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+    influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
+
+#if NUM_BONE_INFLUENCERS > 4
+    influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+#endif
+#if NUM_BONE_INFLUENCERS > 5
+    influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+    influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+    influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
+
+    finalWorld = finalWorld * influence;
 #endif
 
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);

+ 154 - 124
materialsLibrary/materials/pbr/pbr.fragment.fx

@@ -1,4 +1,12 @@
-precision highp float;
+#ifdef BUMP
+#extension GL_OES_standard_derivatives : enable
+#endif
+
+#ifdef LOGARITHMICDEPTH
+#extension GL_EXT_frag_depth : enable
+#endif
+
+precision highp float;
 
 // Constants
 #define RECIPROCAL_PI2 0.15915494
@@ -6,19 +14,22 @@
 
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
+uniform vec3 vReflectionColor;
 uniform vec4 vDiffuseColor;
 
-// PBR CUSTOM CONTROLS
-uniform vec4 vPBRLightingIntensity;
-uniform vec4 vPBRShadowIntensity;
-uniform vec4 vPBRCameraInfos;
+// CUSTOM CONTROLS
+uniform vec4 vLightingIntensity;
+uniform vec4 vShadowIntensity;
+uniform vec4 vCameraInfos;
 
-uniform vec4 vPBROverloadedIntensity;
-uniform vec3 vPBROverloadedAmbient;
-uniform vec3 vPBROverloadedDiffuse;
-uniform vec3 vPBROverloadedSpecular;
-uniform vec3 vPBROverloadedEmissive;
-uniform vec3 vPBROverloadedSmoothness;
+#ifdef OVERLOADEDVALUES
+    uniform vec4 vOverloadedIntensity;
+    uniform vec3 vOverloadedAmbient;
+    uniform vec3 vOverloadedDiffuse;
+    uniform vec3 vOverloadedSpecular;
+    uniform vec3 vOverloadedEmissive;
+    uniform vec3 vOverloadedSmoothness;
+#endif
 
 // PBR CUSTOM CONSTANTS
 const float kPi = 3.1415926535897932384626433832795;
@@ -130,40 +141,44 @@ vec3 toGammaSpace(vec3 color)
     return vec3(pow(color.r, 1.0 / 2.2), pow(color.g, 1.0 / 2.2), pow(color.b, 1.0 / 2.2));
 }
 
-vec3 toneMaps(vec3 color)
-{
-    color = max(color, 0.0);
-
-    // TONE MAPPING / EXPOSURE
-    color.rgb = color.rgb * vPBRCameraInfos.x;
-
-    float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
-    // PI Test
-    // tuning *=  kPi;
-    vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
-    color.rgb = mix(color.rgb, tonemapped, 1.0);
-    return color;
-}
+#ifdef CAMERATONEMAP
+    vec3 toneMaps(vec3 color)
+    {
+        color = max(color, 0.0);
 
-vec4 contrasts(vec4 color)
-{
-    color = clamp(color, 0.0, 1.0);
+        // TONE MAPPING / EXPOSURE
+        color.rgb = color.rgb * vCameraInfos.x;
 
-    vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
-    float contrast = vPBRCameraInfos.y;
-    if (contrast < 1.0)
-    {
-        // Decrease contrast: interpolate towards zero-contrast image (flat grey)
-        color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
+        // PI Test
+        // tuning *=  kPi;
+        vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
+        color.rgb = mix(color.rgb, tonemapped, 1.0);
+        return color;
     }
-    else
+#endif
+
+#ifdef CAMERACONTRAST
+    vec4 contrasts(vec4 color)
     {
-        // Increase contrast: apply simple shoulder-toe high contrast curve
-        color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        color = clamp(color, 0.0, 1.0);
+
+        vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
+        float contrast = vCameraInfos.y;
+        if (contrast < 1.0)
+        {
+            // Decrease contrast: interpolate towards zero-contrast image (flat grey)
+            color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        }
+        else
+        {
+            // Increase contrast: apply simple shoulder-toe high contrast curve
+            color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        }
+
+        return color;
     }
-
-    return color;
-}
+#endif
 // END PBR HELPER METHODS
 
 #ifdef SPECULARTERM
@@ -321,11 +336,6 @@ float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float
 }
 #endif
 
-#ifdef DIFFUSEFRESNEL
-uniform vec4 diffuseLeftColor;
-uniform vec4 diffuseRightColor;
-#endif
-
 #ifdef OPACITYFRESNEL
 uniform vec4 opacityParts;
 #endif
@@ -412,11 +422,6 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 #endif
 }
 
-#ifdef REFLECTIONFRESNEL
-uniform vec4 reflectionLeftColor;
-uniform vec4 reflectionRightColor;
-#endif
-
 #endif
 
 // Shadows
@@ -442,7 +447,7 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 
     if (depth > shadow)
     {
-        return mix(1.0, darkness, vPBRShadowIntensity.x);
+        return mix(1.0, darkness, vShadowIntensity.x);
     }
     return 1.0;
 }
@@ -473,7 +478,7 @@ float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, fl
     if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
     if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
 
-    return  min(1.0, mix(1.0, visibility + darkness, vPBRShadowIntensity.x));
+    return  min(1.0, mix(1.0, visibility + darkness, vShadowIntensity.x));
 }
 #endif
 
@@ -493,7 +498,7 @@ float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float dark
 
     if (depth.z > shadow)
     {
-        return mix(1.0, darkness, vPBRShadowIntensity.x);
+        return mix(1.0, darkness, vShadowIntensity.x);
     }
     return 1.;
 }
@@ -525,7 +530,7 @@ float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, flo
     if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
     if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
 
-    return  min(1.0, mix(1.0, visibility + darkness, vPBRShadowIntensity.x));
+    return  min(1.0, mix(1.0, visibility + darkness, vShadowIntensity.x));
 }
 
 // Thanks to http://devmaster.net/
@@ -562,7 +567,7 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
     vec4 texel = texture2D(shadowSampler, uv);
 
     vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-    return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vPBRShadowIntensity.x));
+    return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vShadowIntensity.x));
 }
 #endif
 
@@ -570,7 +575,6 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 
 // Bump
 #ifdef BUMP
-#extension GL_OES_standard_derivatives : enable
 varying vec2 vBumpUV;
 uniform vec2 vBumpInfos;
 uniform sampler2D bumpSampler;
@@ -608,6 +612,11 @@ vec3 perturbNormal(vec3 viewDir)
 varying float fClipDistance;
 #endif
 
+#ifdef LOGARITHMICDEPTH
+uniform float logarithmicDepthConstant;
+varying float vFragmentDepth;
+#endif
+
 // Fog
 #ifdef FOG
 
@@ -788,8 +797,9 @@ void main(void) {
     baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
-    baseColor.rgb = mix(baseColor.rgb, vPBROverloadedDiffuse, vPBROverloadedIntensity.y);
-
+#ifdef OVERLOADEDVALUES
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+#endif
 
 #ifdef VERTEXCOLOR
     baseColor.rgb *= vColor.rgb;
@@ -812,36 +822,52 @@ void main(void) {
 
 #ifdef AMBIENT
     baseAmbientColor = texture2D(ambientSampler, vAmbientUV).rgb * vAmbientInfos.y;
-    baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vPBROverloadedAmbient, vPBROverloadedIntensity.x);
+    
+    #ifdef OVERLOADEDVALUES
+        baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vOverloadedAmbient, vOverloadedIntensity.x);
+    #endif
 #endif
 
     // Specular map
 #ifdef SPECULARTERM
     float glossiness = vSpecularColor.a;
     vec3 specularColor = vSpecularColor.rgb;
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 
     #ifdef SPECULAR
         vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
         specularColor = toLinearSpace(specularMapColor.rgb);
-        specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
 
-        #ifdef GLOSSINESS
+        #ifdef OVERLOADEDVALUES
+                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        #endif
+
+        #ifdef GLOSSINESSFROMSPECULARMAP
             glossiness = specularMapColor.a;
         #else
             glossiness = computeDefaultGlossiness(glossiness, specularColor);
         #endif
     #endif
 
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedSmoothness.x, vOverloadedSmoothness.y);
+    #endif
 #else
     float glossiness = 0.;
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedSmoothness.x, vOverloadedSmoothness.y);
+    #endif
+    
     vec3 specularColor = vec3(0., 0., 0);
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 #endif
 
-    // Apply Energy Conservation.
+    // Apply Energy Conservation taking in account the environment level only if the environment is present.
     float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
@@ -856,7 +882,9 @@ void main(void) {
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
-    vec3 shadowedOnly = vPBROverloadedDiffuse;
+#ifdef OVERLOADEDVALUES
+    vec3 shadowedOnly = vOverloadedDiffuse;
+#endif
 
 #ifdef SPECULARTERM
     vec3 specularBase = vec3(0., 0., 0.);
@@ -898,7 +926,9 @@ void main(void) {
     shadow = 1.;
 #endif
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -941,7 +971,9 @@ void main(void) {
 #endif
 
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -984,7 +1016,9 @@ void main(void) {
 #endif
 
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -1026,43 +1060,38 @@ void main(void) {
     shadow = 1.;
 #endif
 
-
     diffuseBase += info.diffuse * shadow;
+#ifdef OVERLOADEDVALUES
     shadowedOnly *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
 #endif
 #endif
 
-    // Reflection
-    vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vReflectionColor.rgb;
+vec3 ambientReflectionColor = vReflectionColor.rgb;
 
 #ifdef REFLECTION
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
-    vec3 ambientReflectionColor = vec3(0.1, 0.1, 0.1);
 
     #ifdef REFLECTIONMAP_3D
         float bias = 0.;
 
-        #ifdef ROUGHNESS
-            bias = 20.;
-            
-            #ifdef SPECULARTERM
-                bias *= (1.0 - glossiness);
-            #endif
+        #ifdef SPECULARTERM
+            // Go mat -> blurry reflexion according to glossiness
+            bias = 20. * (1.0 - glossiness);
         #endif
 
-            reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
-            reflectionColor = toLinearSpace(reflectionColor.rgb);
-
-            ambientReflectionColor = textureCube(reflectionCubeSampler, normalW, 20.).rgb;
-            ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
+        reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
+        reflectionColor = toLinearSpace(reflectionColor.rgb);
 
-            reflectionColor = reflectionColor * vReflectionInfos.y;
-            //reflectionColor = reflectionColor * vReflectionInfos.y * shadow;
+        ambientReflectionColor = textureCube(reflectionCubeSampler, normalW, 20.).rgb * vReflectionInfos.x;
+        ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
     #else
-            vec2 coords = vReflectionUVW.xy;
+        vec2 coords = vReflectionUVW.xy;
 
         #ifdef REFLECTIONMAP_PROJECTION
             coords /= vReflectionUVW.z;
@@ -1073,33 +1102,29 @@ void main(void) {
         reflectionColor = texture2D(reflection2DSampler, coords).rgb * vReflectionInfos.x;
         reflectionColor = toLinearSpace(reflectionColor.rgb);
 
-        ambientReflectionColor = texture2D(reflection2DSampler, coords, 10.).rgb;
+        ambientReflectionColor = texture2D(reflection2DSampler, coords, 20.).rgb * vReflectionInfos.x;
         ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
     #endif
-
-    #ifdef REFLECTIONFRESNEL
-        #ifdef REFLECTIONFRESNELFROMSPECULAR
-            // Compute reflection specular fresnel
-            vec3 specularEnvironmentR0 = specularColor.rgb;
-            vec3 specularEnvironmentR90 = reflectionLeftColor.rgb;
-            vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
-            reflectionColor *= specularEnvironmentReflectanceViewer;
-        #else
-            float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
-            reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-        #endif
-    #endif
 #endif
 
+reflectionColor *= vLightingIntensity.z;
+ambientReflectionColor *= vLightingIntensity.z;
+
+// Compute reflection specular fresnel
+vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
+vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
+reflectionColor *= specularEnvironmentReflectanceViewer;
+
 #ifdef OPACITY
     vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
 
-#ifdef OPACITYRGB
-    opacityMap.rgb = opacityMap.rgb * vec3(0.3, 0.59, 0.11);
-    alpha *= (opacityMap.x + opacityMap.y + opacityMap.z)* vOpacityInfos.y;
-#else
-    alpha *= opacityMap.a * vOpacityInfos.y;
-#endif
+    #ifdef OPACITYRGB
+        opacityMap.rgb = opacityMap.rgb * vec3(0.3, 0.59, 0.11);
+        alpha *= (opacityMap.x + opacityMap.y + opacityMap.z)* vOpacityInfos.y;
+    #else
+        alpha *= opacityMap.a * vOpacityInfos.y;
+    #endif
 
 #endif
 
@@ -1118,7 +1143,10 @@ void main(void) {
 #ifdef EMISSIVE
     vec3 emissiveColorTex = texture2D(emissiveSampler, vEmissiveUV).rgb;
     emissiveColor = toLinearSpace(emissiveColorTex.rgb) * emissiveColor * vEmissiveInfos.y;
-    emissiveColor = mix(emissiveColor, vPBROverloadedEmissive, vPBROverloadedIntensity.w);
+
+    #ifdef OVERLOADEDVALUES
+        emissiveColor = mix(emissiveColor, vOverloadedEmissive, vOverloadedIntensity.w);
+    #endif
 #endif
 
 #ifdef EMISSIVEFRESNEL
@@ -1127,28 +1155,20 @@ void main(void) {
     emissiveColor *= emissiveLeftColor.rgb * (1.0 - emissiveFresnelTerm) + emissiveFresnelTerm * emissiveRightColor.rgb;
 #endif
 
-    // Fresnel
-#ifdef DIFFUSEFRESNEL
-    float diffuseFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, diffuseRightColor.a, diffuseLeftColor.a);
-
-    diffuseBase *= diffuseLeftColor.rgb * (1.0 - diffuseFresnelTerm) + diffuseFresnelTerm * diffuseRightColor.rgb;
-#endif
-
     // Composition
 #ifdef EMISSIVEASILLUMINATION
     vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
 #else
     #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
     #else
-        vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
 #endif
 
-#ifdef REFLECTION
-    // diffuse lighting from environment
-    finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2 * vPBRLightingIntensity.z;
-#endif
+// diffuse lighting from environment 0.2 replaces Harmonic...
+// Ambient Reflection already includes the environment intensity.
+finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 
 #ifdef SPECULARTERM
     vec3 finalSpecular = specularBase * specularColor;
@@ -1160,11 +1180,12 @@ void main(void) {
     alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif
 
-    // Composition
+// Composition
+// Reflection already includes the environment intensity.
 #ifdef EMISSIVEASILLUMINATION
-    vec4 color = vec4(finalDiffuse * baseAmbientColor * vPBRLightingIntensity.x + finalSpecular * vPBRLightingIntensity.x + reflectionColor * vPBRLightingIntensity.z + emissiveColor * vPBRLightingIntensity.y, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor + emissiveColor * vLightingIntensity.y, alpha);
 #else
-    vec4 color = vec4(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor, alpha);
 #endif
 
 #ifdef LIGHTMAP
@@ -1181,13 +1202,22 @@ void main(void) {
     float fog = CalcFogFactor();
     color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
 #endif
+
     color = max(color, 0.0);
 
+#ifdef CAMERATONEMAP
     color.rgb = toneMaps(color.rgb);
+#endif
+
     color.rgb = toGammaSpace(color.rgb);
+
+#ifdef CAMERACONTRAST
     color = contrasts(color);
+#endif
 
-    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vPBRShadowIntensity.y));
+#ifdef OVERLOADEDVALUES
+    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vShadowIntensity.y));
+#endif
 
     // Normal Display.
     // gl_FragColor = vec4(normalW * 0.5 + 0.5, 1.0);
@@ -1215,4 +1245,4 @@ void main(void) {
     //gl_FragColor = vec4(test.x, test.y, 1.0, 1.0);
 
     gl_FragColor = color;
-}
+}

+ 46 - 17
materialsLibrary/materials/pbr/pbr.vertex.fx

@@ -14,9 +14,15 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
+#if NUM_BONE_INFLUENCERS > 0
+uniform mat4 mBones[BonesPerMesh];
+
 attribute vec4 matricesIndices;
 attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniforms
@@ -75,10 +81,6 @@ uniform vec2 vBumpInfos;
 uniform mat4 bumpMatrix;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -129,32 +131,53 @@ varying vec3 vPositionUVW;
 varying vec3 vDirectionW;
 #endif
 
+#ifdef LOGARITHMICDEPTH
+uniform float logarithmicDepthConstant;
+varying float vFragmentDepth;
+#endif
+
 void main(void) {
-    mat4 finalWorld;
 
 #ifdef REFLECTIONMAP_SKYBOX
     vPositionUVW = position;
 #endif 
 
 #ifdef INSTANCES
-    finalWorld = mat4(world0, world1, world2, world3);
+    mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-    finalWorld = world;
+    mat4 finalWorld = world;
 #endif
 
-#ifdef BONES
-    mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-    mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-    mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
+#if NUM_BONE_INFLUENCERS > 0
+    mat4 influence;
+    influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
 
-#ifdef BONES4
-    mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-    finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-    finalWorld = finalWorld * (m0 + m1 + m2);
+#if NUM_BONE_INFLUENCERS > 1
+    influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
 #endif 
+#if NUM_BONE_INFLUENCERS > 2
+    influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+    influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
+
+#if NUM_BONE_INFLUENCERS > 4
+    influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+#endif
+#if NUM_BONE_INFLUENCERS > 5
+    influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+    influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+    influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
 
+    finalWorld = finalWorld * influence;
 #endif
+
     gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
     vec4 worldPos = finalWorld * vec4(position, 1.0);
@@ -288,4 +311,10 @@ void main(void) {
 #ifdef POINTSIZE
     gl_PointSize = pointSize;
 #endif
+
+    // Log. depth
+#ifdef LOGARITHMICDEPTH
+    vFragmentDepth = 1.0 + gl_Position.w;
+    gl_Position.z = log2(max(0.000001, vFragmentDepth)) * logarithmicDepthConstant;
+#endif
 }

+ 37 - 8
materialsLibrary/test/add/addpbr.js

@@ -4,8 +4,7 @@ window.preparePBR = function() {
 	pbr.diffuseTexture.uScale = 5;
 	pbr.diffuseTexture.vScale = 5;
 	pbr.specularColor = BABYLON.Color3.Gray();
-	pbr.specularPower = 0.8;
-	pbr.roughness = 6.0;
+	pbr.glossiness = 0.5;
 	
 	pbr.reflectionFresnelParameters = new BABYLON.FresnelParameters();
 	pbr.useReflectionFresnelFromSpecular = true;
@@ -14,16 +13,46 @@ window.preparePBR = function() {
 	
 	pbr.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/TropicalSunnyDay", scene);
 					
-	registerRangeUI("pbr", "specularPower", 0, 1, function(value) {
-		pbr.specularPower = value;
+	registerRangeUI("pbr", "directIntensity", 0, 1, function(value) {
+		pbr.directIntensity = value;
 	}, function() {
-		return pbr.specularPower;
+		return pbr.directIntensity;
 	});
 	
-	registerRangeUI("pbr", "roughness", 0, 10, function(value) {
-		pbr.roughness = value;
+	registerRangeUI("pbr", "emissiveIntensity", 0, 1, function(value) {
+		pbr.emissiveIntensity = value;
 	}, function() {
-		return pbr.roughness;
+		return pbr.emissiveIntensity;
+	});
+	
+	registerRangeUI("pbr", "environmentIntensity", 0, 1, function(value) {
+		pbr.environmentIntensity = value;
+	}, function() {
+		return pbr.environmentIntensity;
+	});
+	
+	registerRangeUI("pbr", "shadowIntensity", 0, 1, function(value) {
+		pbr.shadowIntensity = value;
+	}, function() {
+		return pbr.shadowIntensity;
+	});
+	
+	registerRangeUI("pbr", "shadeIntensity", 0, 1, function(value) {
+		pbr.shadeIntensity = value;
+	}, function() {
+		return pbr.shadeIntensity;
+	});
+	
+	registerRangeUI("pbr", "cameraExposure", 0, 1, function(value) {
+		pbr.cameraExposure = value;
+	}, function() {
+		return pbr.cameraExposure;
+	});
+	
+	registerRangeUI("pbr", "glossiness", 0, 1, function(value) {
+		pbr.glossiness = value;
+	}, function() {
+		return pbr.glossiness;
 	});
 		
 	return pbr;