Browse Source

Merge pull request #420 from jahow/color-correction-pp

New 'color correction' post process
David Catuhe 10 years ago
parent
commit
69549e3cdd

+ 34 - 0
Babylon/PostProcess/babylon.colorCorrectionPostProcess.ts

@@ -0,0 +1,34 @@
+/*
+ *  This post-process allows the modification of rendered colors by using
+ *  a 'look-up table' (LUT). This effect is also called Color Grading.
+ * 
+ *  The object needs to be provided an url to a texture containing the color
+ *  look-up table: the texture must be 256 pixels wide and 16 pixels high.
+ *  Use an image editing software to tweak the LUT to match your needs.
+ * 
+ *  For an example of a color LUT, see here:
+ *      http://udn.epicgames.com/Three/rsrc/Three/ColorGrading/RGBTable16x1.png
+ *  For explanations on color grading, see here:
+ *      http://udn.epicgames.com/Three/ColorGrading.html
+ */
+
+module BABYLON {
+    export class ColorCorrectionPostProcess extends PostProcess{
+
+    	private _colorTableTexture: BABYLON.Texture;
+
+    	constructor(name: string, colorTableUrl: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+    		super(name, 'colorCorrection', null, ['colorTable'], ratio, camera, samplingMode, engine, reusable);
+
+    		this._colorTableTexture = new BABYLON.Texture(colorTableUrl, camera.getScene(), true, false, BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
+    		this._colorTableTexture.anisotropicFilteringLevel = 1;
+    		this._colorTableTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
+    		this._colorTableTexture.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
+
+    		this.onApply = (effect: Effect) => {
+            	effect.setTexture("colorTable", this._colorTableTexture);
+            };
+    	}
+
+    }
+}

+ 39 - 0
Babylon/Shaders/colorCorrection.fragment.fx

@@ -0,0 +1,39 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+// samplers
+uniform sampler2D textureSampler;	// screen render
+uniform sampler2D colorTable;		// color table with modified colors
+
+// varyings
+varying vec2 vUV;
+
+// constants
+const float SLICE_COUNT = 16.0;		// how many slices in the color cube; 1 slice = 1 pixel
+									// it means the image is 256x16 pixels
+
+
+vec4 sampleAs3DTexture(sampler2D texture, vec3 uv, float width) {
+    float sliceSize = 1.0 / width;              // space of 1 slice
+    float slicePixelSize = sliceSize / width;           // space of 1 pixel
+    float sliceInnerSize = slicePixelSize * (width - 1.0);  // space of width pixels
+    float zSlice0 = min(floor(uv.z * width), width - 1.0);
+    float zSlice1 = min(zSlice0 + 1.0, width - 1.0);
+    float xOffset = slicePixelSize * 0.5 + uv.x * sliceInnerSize;
+    float s0 = xOffset + (zSlice0 * sliceSize);
+    float s1 = xOffset + (zSlice1 * sliceSize);
+    vec4 slice0Color = texture2D(texture, vec2(s0, uv.y));
+    vec4 slice1Color = texture2D(texture, vec2(s1, uv.y));
+    float zOffset = mod(uv.z * width, 1.0);
+    vec4 result = mix(slice0Color, slice1Color, zOffset);
+    return result;
+}
+
+
+void main(void)
+{
+	vec4 screen_color = texture2D(textureSampler, vUV);
+	gl_FragColor = sampleAs3DTexture(colorTable, screen_color.rgb, SLICE_COUNT);
+
+}