瀏覽代碼

Merge pull request #1253 from sebavan/StandardMaterialUpgrade

Add Color Grading and Color Curves in standard
David Catuhe 9 年之前
父節點
當前提交
7a5f384bc4

+ 238 - 0
materialsLibrary/test/add/addpbr.js

@@ -0,0 +1,238 @@
+window.preparePBR = function() {
+	var pbr = new BABYLON.PBRMaterial("pbr", scene);
+
+	pbr.albedoTexture = new BABYLON.Texture("textures/amiga.jpg", scene);
+	pbr.albedoTexture.uScale = 5;
+	pbr.albedoTexture.vScale = 5;
+    
+    var hdrTexture = new BABYLON.HDRCubeTexture("textures/hdr/environment.hdr", scene, 512);
+
+    var colorGradingTexture = new BABYLON.ColorGradingTexture("textures/ColorGrading.3DL", scene);
+    
+    // Uncomment for PMREM Generation
+    // var hdrTexture = new BABYLON.HDRCubeTexture("textures/hdr/environment.hdr", scene, 128, false, true, false, true);
+    pbr.reflectionTexture = hdrTexture;
+    pbr.refractionTexture = hdrTexture;
+    pbr.linkRefractionWithTransparency = true;
+    pbr.indexOfRefraction = 0.52;
+    
+	pbr.reflectivityColor = new BABYLON.Color3(0.3, 0.3, 0.3);
+	pbr.microSurface = 0.9;
+    
+    // Skybox
+    var hdrSkybox = BABYLON.Mesh.CreateBox("hdrSkyBox", 1000.0, scene);
+    var hdrSkyboxMaterial = new BABYLON.PBRMaterial("skyBox", scene);
+    hdrSkyboxMaterial.backFaceCulling = false;
+    hdrSkyboxMaterial.reflectionTexture = hdrTexture.clone();
+    hdrSkyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
+    hdrSkyboxMaterial.microSurface = 1;
+    hdrSkyboxMaterial.specularColor = new BABYLON.Color3(1, 1, 1);
+    hdrSkyboxMaterial.disableLighting = true;
+    hdrSkyboxMaterial.cameraExposure = 0.6;
+    hdrSkyboxMaterial.cameraContrast = 1.6;
+    hdrSkyboxMaterial.directIntensity = 0;
+    hdrSkybox.material = hdrSkyboxMaterial;
+    hdrSkybox.infiniteDistance = true;
+    hdrSkybox.setEnabled(false);
+    
+	registerButtonUI("pbr", "Default", function() {
+		setRangeValues({
+		  "directIntensity": 1,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 1,
+		  "specularIntensity": 1,
+		  "ShadowIntensity": 1,
+		  "ShadeIntensity": 1,
+		  "cameraExposure": 1,
+		  "cameraContrast": 1,
+		  "microSurface": 0.9,
+		  "reflectivityColorR": 0.3,
+		  "reflectivityColorG": 0.3,
+		  "reflectivityColorB": 0.3,
+		  "albedoColorR": 1,
+		  "albedoColorG": 1,
+		  "albedoColorB": 1,
+		  "albedoColorLevel": 0
+		});
+	});
+    registerButtonUI("pbr", "Env Irradiance", function() {
+		setRangeValues({
+		  "directIntensity": 0,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 1,
+		  "specularIntensity": 1,
+		  "ShadowIntensity": 1,
+		  "ShadeIntensity": 1,
+		  "cameraExposure": 1,
+		  "cameraContrast": 1,
+		  "microSurface": 0,
+		  "reflectivityColorR": 0,
+		  "reflectivityColorG": 0,
+		  "reflectivityColorB": 0,
+		  "albedoColorR": 1,
+		  "albedoColorG": 1,
+		  "albedoColorB": 1,
+		  "albedoColorLevel": 1
+		});
+        
+        hdrSkybox.setEnabled(true);
+	});
+	registerButtonUI("pbr", "Rough Gold", function() {
+		setRangeValues({
+		  "directIntensity": 1.3439461727881254,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
+		  "ShadowIntensity": 1,
+		  "ShadeIntensity": 1,
+		  "cameraExposure": 0.7153261887420668,
+		  "cameraContrast": 1.6474178892241538,
+		  "microSurface": 0.42269274789303946,
+		  "reflectivityColorR": 1,
+		  "reflectivityColorG": 0.8453854957860789,
+		  "reflectivityColorB": 0.5093989525890475,
+		  "albedoColorR": 0,
+		  "albedoColorG": 0,
+		  "albedoColorB": 0,
+		  "albedoColorLevel": 1
+		});
+	});
+	registerButtonUI("pbr", "Plastic", function() {
+		setRangeValues({
+		  "directIntensity": 0.9971213540040931,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
+		  "ShadowIntensity": 0.975444802830091,
+		  "ShadeIntensity": 0.8020323934380749,
+		  "cameraExposure": 0.7586792910900708,
+		  "cameraContrast": 1.5823882357021477,
+		  "microSurface": 0.8562237713730799,
+		  "reflectivityColorR": 0.05,
+		  "reflectivityColorG": 0.05,
+		  "reflectivityColorB": 0.05,
+		  "albedoColorR": 0.20592723615301922,
+		  "albedoColorG": 0.942929976069088,
+		  "albedoColorB": 1,
+		  "albedoColorLevel": 1
+		});
+	});
+	
+    registerRangeUI("pbr", "indiceOfRefraction", 0, 2, function(value) {
+		pbr.indexOfRefraction = value;
+	}, function() {
+		return pbr.indexOfRefraction;
+	});
+    
+    registerRangeUI("pbr", "alpha", 0, 1, function(value) {
+		pbr.alpha = value;
+	}, function() {
+		return pbr.alpha;
+	});
+    
+    registerRangeUI("pbr", "directIntensity", 0, 2, function(value) {
+		pbr.directIntensity = value;
+	}, function() {
+		return pbr.directIntensity;
+	});
+    
+	registerRangeUI("pbr", "emissiveIntensity", 0, 2, function(value) {
+		pbr.emissiveIntensity = value;
+	}, function() {
+		return pbr.emissiveIntensity;
+	});
+	
+	registerRangeUI("pbr", "environmentIntensity", 0, 2, function(value) {
+		pbr.environmentIntensity = value;
+	}, function() {
+		return pbr.environmentIntensity;
+	});
+
+	registerRangeUI("pbr", "specularIntensity", 0, 2, function(value) {
+		pbr.specularIntensity = value;
+	}, function() {
+		return pbr.specularIntensity;
+	});
+	
+	registerRangeUI("pbr", "ShadowIntensity", 0, 2, function(value) {
+		pbr.overloadedShadowIntensity = value;
+	}, function() {
+		return pbr.overloadedShadowIntensity;
+	});
+	
+	registerRangeUI("pbr", "ShadeIntensity", 0, 2, function(value) {
+		pbr.overloadedShadeIntensity = value;
+	}, function() {
+		return pbr.overloadedShadeIntensity;
+	});
+	
+	registerRangeUI("pbr", "cameraExposure", 0, 2, function(value) {
+		pbr.cameraExposure = value;
+	}, function() {
+		return pbr.cameraExposure;
+	});
+
+	registerRangeUI("pbr", "cameraContrast", 0, 2, function(value) {
+		pbr.cameraContrast = value;
+	}, function() {
+		return pbr.cameraContrast;
+	});
+	
+	registerRangeUI("pbr", "microSurface", 0, 1, function(value) {
+		pbr.microSurface = value;
+	}, function() {
+		return pbr.microSurface;
+	});
+
+	registerRangeUI("pbr", "reflectivityColorR", 0, 1, function(value) {
+		pbr.reflectivityColor.r = value;
+	}, function() {
+		return pbr.reflectivityColor.r;
+	});
+
+	registerRangeUI("pbr", "reflectivityColorG", 0, 1, function(value) {
+		pbr.reflectivityColor.g = value;
+	}, function() {
+		return pbr.reflectivityColor.g;
+	});
+
+	registerRangeUI("pbr", "reflectivityColorB", 0, 1, function(value) {
+		pbr.reflectivityColor.b = value;
+	}, function() {
+		return pbr.reflectivityColor.b;
+	});
+
+	registerRangeUI("pbr", "albedoColorR", 0, 1, function(value) {
+		pbr.overloadedAlbedo.r = value;
+	}, function() {
+		return pbr.overloadedAlbedo.r;
+	});
+
+	registerRangeUI("pbr", "albedoColorG", 0, 1, function(value) {
+		pbr.overloadedAlbedo.g = value;
+	}, function() {
+		return pbr.overloadedAlbedo.g;
+	});
+
+	registerRangeUI("pbr", "albedoColorB", 0, 1, function(value) {
+		pbr.overloadedAlbedo.b = value;
+	}, function() {
+		return pbr.overloadedAlbedo.b;
+	});
+
+	registerRangeUI("pbr", "albedoColorLevel", 0, 1, function(value) {
+		pbr.overloadedAlbedoIntensity = value;
+	}, function() {
+		return pbr.overloadedAlbedoIntensity;
+	});
+    
+    registerButtonUI("pbr", "Toggle Skybox", function() {
+        hdrSkybox.setEnabled(!hdrSkybox.isEnabled());
+	});
+
+    registerButtonUI("pbr", "Color Grading", function() {
+        pbr.cameraColorGradingTexture = pbr.cameraColorGradingTexture ? null : colorGradingTexture; 
+	});
+
+	return pbr;
+}

+ 7 - 1
materialsLibrary/test/index.html

@@ -59,6 +59,7 @@
 	<script src="add/addgradient.js"></script>
 	<script src="add/addgradient.js"></script>
 	<script src="add/addsky.js"></script>
 	<script src="add/addsky.js"></script>
 	<script src="add/addgrid.js"></script>
 	<script src="add/addgrid.js"></script>
+    <script src="add/addpbr.js"></script>
 	
 	
 	<script>
 	<script>
 		if (BABYLON.Engine.isSupported()) {
 		if (BABYLON.Engine.isSupported()) {
@@ -198,6 +199,8 @@
 				var fire = prepareFire();
 				var fire = prepareFire();
 				
 				
 				var terrain = prepareTerrain();
 				var terrain = prepareTerrain();
+
+				var pbr = preparePBR();
 				
 				
 				var triPlanar = prepareTriPlanar();
 				var triPlanar = prepareTriPlanar();
 				
 				
@@ -210,7 +213,7 @@
 				sphere.material = std;				
 				sphere.material = std;				
 				sphere.receiveShadows = true;
 				sphere.receiveShadows = true;
 
 
-				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'fur', 'triPlanar', 'gradient', 'sky', 'grid']).onFinishChange(function () {
+				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur', 'triPlanar', 'gradient', 'sky', 'grid']).onFinishChange(function () {
 					water.enableRenderTargets(false);
 					water.enableRenderTargets(false);
 					skybox.material = skyboxMaterial;
 					skybox.material = skyboxMaterial;
 					currentMesh.isVisible = true;
 					currentMesh.isVisible = true;
@@ -237,6 +240,9 @@
 						case "terrain":
 						case "terrain":
 							currentMaterial = terrain;
 							currentMaterial = terrain;
 							break;
 							break;
+						case "pbr":
+							currentMaterial = pbr;
+							break;
 						case "fur":
 						case "fur":
 							currentMaterial = fur.material;
 							currentMaterial = fur.material;
 							fur.configureFur(currentMesh);
 							fur.configureFur(currentMesh);

File diff suppressed because it is too large
+ 18839 - 4465
materialsLibrary/test/refs/babylon.max.js


File diff suppressed because it is too large
+ 4916 - 0
materialsLibrary/test/textures/ColorGrading.3DL


+ 3 - 1
src/Debug/babylon.debugLayer.ts

@@ -356,7 +356,8 @@
             StandardMaterial.OpacityTextureEnabled = true;
             StandardMaterial.OpacityTextureEnabled = true;
             StandardMaterial.ReflectionTextureEnabled = true;
             StandardMaterial.ReflectionTextureEnabled = true;
             StandardMaterial.LightmapTextureEnabled = true;
             StandardMaterial.LightmapTextureEnabled = true;
-            StandardMaterial.RefractionTextureEnabled = true;
+            StandardMaterial.RefractionTextureEnabled = true;            
+            StandardMaterial.ColorGradingTextureEnabled = true;
 
 
             this._scene.shadowsEnabled = true;
             this._scene.shadowsEnabled = true;
             this._scene.particlesEnabled = true;
             this._scene.particlesEnabled = true;
@@ -689,6 +690,7 @@
                 this._generateCheckBox(this._optionsSubsetDiv, "Opacity", StandardMaterial.OpacityTextureEnabled, (element) => { StandardMaterial.OpacityTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Opacity", StandardMaterial.OpacityTextureEnabled, (element) => { StandardMaterial.OpacityTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Reflection", StandardMaterial.ReflectionTextureEnabled, (element) => { StandardMaterial.ReflectionTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Reflection", StandardMaterial.ReflectionTextureEnabled, (element) => { StandardMaterial.ReflectionTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Refraction", StandardMaterial.RefractionTextureEnabled, (element) => { StandardMaterial.RefractionTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Refraction", StandardMaterial.RefractionTextureEnabled, (element) => { StandardMaterial.RefractionTextureEnabled = element.checked });
+                this._generateCheckBox(this._optionsSubsetDiv, "ColorGrading", StandardMaterial.ColorGradingTextureEnabled, (element) => { StandardMaterial.ColorGradingTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Lightmap", StandardMaterial.LightmapTextureEnabled, (element) => { StandardMaterial.LightmapTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Lightmap", StandardMaterial.LightmapTextureEnabled, (element) => { StandardMaterial.LightmapTextureEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Fresnel", StandardMaterial.FresnelEnabled, (element) => { StandardMaterial.FresnelEnabled = element.checked });
                 this._generateCheckBox(this._optionsSubsetDiv, "Fresnel", StandardMaterial.FresnelEnabled, (element) => { StandardMaterial.FresnelEnabled = element.checked });
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));

+ 42 - 0
src/Materials/Textures/babylon.colorGradingTexture.ts

@@ -186,6 +186,48 @@ module BABYLON {
             }
             }
         }
         }
 
 
+         /**
+         * Binds the color grading to the shader.
+         * @param colorGrading The texture to bind
+         * @param effect The effect to bind to
+         */
+        public static Bind(colorGrading: BaseTexture, effect: Effect) : void {
+            effect.setTexture("cameraColorGrading2DSampler", colorGrading);
+                        
+     	    let x = colorGrading.level;                 // Texture Level
+            let y = colorGrading.getSize().height;      // Texture Size example with 8
+            let z = y - 1.0;                    // SizeMinusOne 8 - 1
+            let w = 1 / y;                      // Space of 1 slice 1 / 8
+            
+            effect.setFloat4("vCameraColorGradingInfos", x, y, z, w);
+            
+            let slicePixelSizeU = w / y;    // Space of 1 pixel in U direction, e.g. 1/64
+            let slicePixelSizeV = w;		// Space of 1 pixel in V direction, e.g. 1/8					    // Space of 1 pixel in V direction, e.g. 1/8
+            
+            let x2 = z * slicePixelSizeU;   // Extent of lookup range in U for a single slice so that range corresponds to (size-1) texels, for example 7/64
+            let y2 = z / y;	                // Extent of lookup range in V for a single slice so that range corresponds to (size-1) texels, for example 7/8
+            let z2 = 0.5 * slicePixelSizeU;	// Offset of lookup range in U to align sample position with texel centre, for example 0.5/64 
+            let w2 = 0.5 * slicePixelSizeV;	// Offset of lookup range in V to align sample position with texel centre, for example 0.5/8
+            
+            effect.setFloat4("vCameraColorGradingScaleOffset", x2, y2, z2, w2);
+        }
+        
+        /**
+         * Prepare the list of uniforms associated with the ColorGrading effects.
+         * @param uniformsList The list of uniforms used in the effect
+         * @param samplersList The list of samplers used in the effect
+         */
+        public static PrepareUniformsAndSamplers(uniformsList: string[], samplersList: string[]): void {
+            uniformsList.push(
+                "vCameraColorGradingInfos", 
+                "vCameraColorGradingScaleOffset"
+            );
+
+            samplersList.push(
+                "cameraColorGrading2DSampler"
+            );
+        }
+
         /**
         /**
          * Parses a color grading texture serialized by Babylon.
          * Parses a color grading texture serialized by Babylon.
          * @param parsedTexture The texture information being parsedTexture
          * @param parsedTexture The texture information being parsedTexture

+ 6 - 34
src/Materials/babylon.pbrMaterial.ts

@@ -153,9 +153,6 @@
          */
          */
         @serializeAsTexture()
         @serializeAsTexture()
         public cameraColorGradingTexture: BaseTexture = null;
         public cameraColorGradingTexture: BaseTexture = null;
-
-        private _cameraColorGradingScaleOffset: Vector4 = new Vector4(1.0, 1.0, 0.0, 0.0);
-        private _cameraColorGradingInfos: Vector4 = new Vector4(1.0, 1.0, 0.0, 0.0);
         
         
         /**
         /**
          * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT). 
          * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT). 
@@ -778,7 +775,7 @@
                     }
                     }
                 }
                 }
             
             
-                if (this.cameraColorGradingTexture) {
+                if (this.cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
                     if (!this.cameraColorGradingTexture.isReady()) {
                     if (!this.cameraColorGradingTexture.isReady()) {
                         return false;
                         return false;
                     } else {
                     } else {
@@ -1025,13 +1022,13 @@
                         "vSphericalXX", "vSphericalYY", "vSphericalZZ",
                         "vSphericalXX", "vSphericalYY", "vSphericalZZ",
                         "vSphericalXY", "vSphericalYZ", "vSphericalZX",
                         "vSphericalXY", "vSphericalYZ", "vSphericalZX",
                         "vMicrosurfaceTextureLods",
                         "vMicrosurfaceTextureLods",
-                        "vCameraInfos", "vCameraColorGradingInfos", "vCameraColorGradingScaleOffset"
+                        "vCameraInfos"
                 ];
                 ];
 
 
-                var samplers = ["albedoSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "reflectivitySampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler",
-                    "cameraColorGrading2DSampler"];
+                var samplers = ["albedoSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "reflectivitySampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"];
                 
                 
                 ColorCurves.PrepareUniforms(uniforms); 
                 ColorCurves.PrepareUniforms(uniforms); 
+                ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers); 
                 MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights); 
                 MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights); 
                 
                 
                 this._effect = scene.getEngine().createEffect(shaderName,
                 this._effect = scene.getEngine().createEffect(shaderName,
@@ -1214,33 +1211,8 @@
                         this._effect.setFloat2("vMicrosurfaceTextureLods", this._microsurfaceTextureLods.x, this._microsurfaceTextureLods.y);
                         this._effect.setFloat2("vMicrosurfaceTextureLods", this._microsurfaceTextureLods.x, this._microsurfaceTextureLods.y);
                     }
                     }
                     
                     
-                    if (this.cameraColorGradingTexture) {
-                        this._effect.setTexture("cameraColorGrading2DSampler", this.cameraColorGradingTexture);
-                        
-                        this._cameraColorGradingInfos.x = this.cameraColorGradingTexture.level;                     // Texture Level
-                        this._cameraColorGradingInfos.y = this.cameraColorGradingTexture.getSize().height;          // Texture Size example with 8
-                        this._cameraColorGradingInfos.z = this._cameraColorGradingInfos.y - 1.0;                    // SizeMinusOne 8 - 1
-                        this._cameraColorGradingInfos.w = 1 / this._cameraColorGradingInfos.y;                      // Space of 1 slice 1 / 8
-                        
-                        this._effect.setFloat4("vCameraColorGradingInfos", 
-                            this._cameraColorGradingInfos.x,
-                            this._cameraColorGradingInfos.y,
-                            this._cameraColorGradingInfos.z,
-                            this._cameraColorGradingInfos.w);
-                        
-                        var slicePixelSizeU = this._cameraColorGradingInfos.w / this._cameraColorGradingInfos.y;    // Space of 1 pixel in U direction, e.g. 1/64
-                        var slicePixelSizeV = 1.0 / this._cameraColorGradingInfos.y;							    // Space of 1 pixel in V direction, e.g. 1/8
-                        this._cameraColorGradingScaleOffset.x = this._cameraColorGradingInfos.z * slicePixelSizeU;  // Extent of lookup range in U for a single slice so that range corresponds to (size-1) texels, for example 7/64
-                        this._cameraColorGradingScaleOffset.y = this._cameraColorGradingInfos.z / 
-                            this._cameraColorGradingInfos.y;							                            // Extent of lookup range in V for a single slice so that range corresponds to (size-1) texels, for example 7/8
-                        this._cameraColorGradingScaleOffset.z = 0.5 * slicePixelSizeU;						        // Offset of lookup range in U to align sample position with texel centre, for example 0.5/64 
-                        this._cameraColorGradingScaleOffset.w = 0.5 * slicePixelSizeV;						        // Offset of lookup range in V to align sample position with texel centre, for example 0.5/8
-                        
-                        this._effect.setFloat4("vCameraColorGradingScaleOffset", 
-                            this._cameraColorGradingScaleOffset.x,
-                            this._cameraColorGradingScaleOffset.y,
-                            this._cameraColorGradingScaleOffset.z,
-                            this._cameraColorGradingScaleOffset.w);
+                    if (this.cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
+                        ColorGradingTexture.Bind(this.cameraColorGradingTexture, this._effect);
                     }
                     }
                 }
                 }
 
 

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

@@ -55,6 +55,8 @@
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPY = false;
         public INVERTNORMALMAPY = false;
         public SHADOWFULLFLOAT = false;
         public SHADOWFULLFLOAT = false;
+        public CAMERACOLORGRADING = false;
+        public CAMERACOLORCURVES = false;
 
 
         constructor() {
         constructor() {
             super();
             super();
@@ -180,6 +182,22 @@
         @serialize()
         @serialize()
         public invertNormalMapY = false;
         public invertNormalMapY = false;
 
 
+        /**
+         * Color Grading 2D Lookup Texture.
+         * This allows special effects like sepia, black and white to sixties rendering style. 
+         */
+        @serializeAsTexture()
+        public cameraColorGradingTexture: BaseTexture = null;
+        
+        /**
+         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT). 
+         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
+         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image; 
+         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
+         */
+        @serializeAsColorCurves()
+        public cameraColorCurves: ColorCurves = null;
+
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _globalAmbientColor = new Color3(0, 0, 0);
         private _globalAmbientColor = new Color3(0, 0, 0);
@@ -422,6 +440,14 @@
                         this._defines.REFRACTIONMAP_3D = this.refractionTexture.isCube;
                         this._defines.REFRACTIONMAP_3D = this.refractionTexture.isCube;
                     }
                     }
                 }
                 }
+
+                if (this.cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
+                    if (!this.cameraColorGradingTexture.isReady()) {
+                        return false;
+                    } else {
+                        this._defines.CAMERACOLORGRADING = true;
+                    }
+                }
             }
             }
 
 
             // Effect
             // Effect
@@ -448,6 +474,10 @@
             if (this.useLogarithmicDepth) {
             if (this.useLogarithmicDepth) {
                 this._defines.LOGARITHMICDEPTH = true;
                 this._defines.LOGARITHMICDEPTH = true;
             }
             }
+            
+            if (this.cameraColorCurves) {
+                this._defines.CAMERACOLORCURVES = true;
+            }
 
 
             // Point size
             // Point size
             if (this.pointsCloud || scene.forcePointsCloud) {
             if (this.pointsCloud || scene.forcePointsCloud) {
@@ -645,6 +675,8 @@
 
 
                 var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
                 var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
 
 
+                ColorCurves.PrepareUniforms(uniforms); 
+                ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers); 
                 MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
                 MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
 
 
                 this._effect = scene.getEngine().createEffect(shaderName,
                 this._effect = scene.getEngine().createEffect(shaderName,
@@ -801,6 +833,10 @@
                         }
                         }
                         this._effect.setFloat4("vRefractionInfos", this.refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
                         this._effect.setFloat4("vRefractionInfos", this.refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
                     }
                     }
+                    
+                    if (this.cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
+                        ColorGradingTexture.Bind(this.cameraColorGradingTexture, this._effect);
+                    }
                 }
                 }
 
 
                 // Clip plane
                 // Clip plane
@@ -842,6 +878,11 @@
 
 
                 // Log. depth
                 // Log. depth
                 MaterialHelper.BindLogDepth(this._defines, this._effect, scene);
                 MaterialHelper.BindLogDepth(this._defines, this._effect, scene);
+
+                // Color Curves
+                if (this.cameraColorCurves) {
+                    ColorCurves.Bind(this.cameraColorCurves, this._effect);
+                }
             }
             }
 
 
             super.bind(world, mesh);
             super.bind(world, mesh);
@@ -885,6 +926,10 @@
             if (this.refractionTexture && this.refractionTexture.animations && this.refractionTexture.animations.length > 0) {
             if (this.refractionTexture && this.refractionTexture.animations && this.refractionTexture.animations.length > 0) {
                 results.push(this.refractionTexture);
                 results.push(this.refractionTexture);
             }
             }
+            
+            if (this.cameraColorGradingTexture && this.cameraColorGradingTexture.animations && this.cameraColorGradingTexture.animations.length > 0) {
+                results.push(this.cameraColorGradingTexture);
+            }
 
 
             return results;
             return results;
         }
         }
@@ -926,6 +971,10 @@
                 if (this.refractionTexture) {
                 if (this.refractionTexture) {
                     this.refractionTexture.dispose();
                     this.refractionTexture.dispose();
                 }
                 }
+                
+                if (this.cameraColorGradingTexture) {
+                    this.cameraColorGradingTexture.dispose();
+                }
             }
             }
 
 
             super.dispose(forceDisposeEffect, forceDisposeTextures);
             super.dispose(forceDisposeEffect, forceDisposeTextures);
@@ -954,6 +1003,7 @@
         public static BumpTextureEnabled = true;
         public static BumpTextureEnabled = true;
         public static FresnelEnabled = true;
         public static FresnelEnabled = true;
         public static LightmapTextureEnabled = true;
         public static LightmapTextureEnabled = true;
-        public static RefractionTextureEnabled = true;
+        public static RefractionTextureEnabled = true;        
+        public static ColorGradingTextureEnabled = true;
     }
     }
 } 
 } 

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

@@ -142,6 +142,16 @@ uniform vec4 reflectionRightColor;
 
 
 #endif
 #endif
 
 
+#ifdef CAMERACOLORGRADING
+	#include<colorGradingDefinition>	
+	#include<colorGrading>
+#endif
+
+#ifdef CAMERACOLORCURVES
+	#include<colorCurvesDefinition>
+	#include<colorCurves>
+#endif
+
 #include<bumpFragmentFunctions>
 #include<bumpFragmentFunctions>
 #include<clipPlaneFragmentDeclaration>
 #include<clipPlaneFragmentDeclaration>
 #include<logDepthDeclaration>
 #include<logDepthDeclaration>
@@ -390,5 +400,13 @@ void main(void) {
 #include<logDepthFragment>
 #include<logDepthFragment>
 #include<fogFragment>
 #include<fogFragment>
 
 
+#ifdef CAMERACOLORGRADING
+	color = colorGrades(color);
+#endif
+
+#ifdef CAMERACOLORCURVES
+	color.rgb = applyColorCurves(color.rgb);
+#endif
+
 	gl_FragColor = color;
 	gl_FragColor = color;
 }
 }